【问题标题】:Are JPA ORM Mappings without annotations possible?没有注释的 JPA ORM 映射是否可行?
【发布时间】:2020-05-12 11:57:59
【问题描述】:

在 c# (dotnet core) 中,我可以定义一个程序集/csproj

  1. 仅包含 POCO(又名 POJO)类。
  2. 对任何其他库的引用为零。
  3. 在 Poco 对象上具有零 ORM 属性(也称为注释)。

然后在另一个程序集/csproj 中,我可以“流畅地”定义 poco 和 ORM 之间的映射。 (例如实体框架或 NHibernate)。

像这样的例子:(实体框架核心)

public class SchoolDBContext: DbContext 
{
    public DbSet<Student> Students { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        //Write Fluent API configurations here

        //Property Configurations
        modelBuilder.Entity<Student>()
                .Property(s => s.StudentId)
                .HasColumnName("Id")
                .HasDefaultValue(0)
                .IsRequired();
    }
}

(以上来自https://www.entityframeworktutorial.net/efcore/fluent-api-in-entity-framework-core.aspx

或NHibernate(下)

public class CarMap : ClassMap<Car>
{
    public CarMap()
    {
        Table( "Vehicles.dbo.Car" );

        Id( x => x.CarId );
        Map( x => x.Name );
        Map( x => x.Year );

        HasOne( x => x.SteeringWheel ).PropertyRef( x => x.Car);
    }
}

public class SteeringWheelMap : ClassMap<SteeringWheel>
{
    public SteeringWheelMap()
    {
        Table( "Vehicles.dbo.SteeringWheel" );

        Id( x => x.SteeringWheelId );
        Map( x => x.Diameter );
        Map( x => x.Color );

        References( x => x.Car, "CarId" ).Unique();
    }
}

(以上来自https://github.com/FluentNHibernate/fluent-nhibernate/wiki/fluent-mapping

在 java 中,我通常会看到这样的 JPA 代码:

package com.mycompany.pojosandjpaannotationsmixed;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.time.OffsetDateTime;

@Entity
@Table(name = "SomeEntityTable")
public class SomeEntity {

    @Id
    @Column(name = "SomeEntityKey", unique = true)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long someEntityKey;

    @Column(name = "SomeEntityName", unique = true)
    private String someEntityName;

    @Column(name = "CreateOffsetDateTime", columnDefinition = "TIMESTAMP WITH TIME ZONE" )
    private OffsetDateTime createOffsetDateTime;

    public long getSomeEntityKey() {
        return someEntityKey;
    }

    public void setSomeEntityKey(long someEntityKey) {
        this.someEntityKey = someEntityKey;
    }

    public String getSomeEntityName() {
        return someEntityName;
    }

    public void setSomeEntityName(String someEntityName) {
        this.someEntityName = someEntityName;
    }

    public OffsetDateTime getCreateOffsetDateTime() {
        return createOffsetDateTime;
    }

    public void setCreateOffsetDateTime(OffsetDateTime createOffsetDateTime) {
        this.createOffsetDateTime = createOffsetDateTime;
    }
}

所有都在同一个模块中(我使用的是 gradle,仅供参考),又名,都在同一个 .jar 中。

在 java(8 或 11 或其他)中是否有将 POCO 与 ORM 分开?

这样的pojo:

public class SomeEntity {

    private long someEntityKey;

    private String someEntityName;

    private OffsetDateTime createOffsetDateTime;


    public long getSomeEntityKey() {
        return someEntityKey;
    }

    public void setSomeEntityKey(long someEntityKey) {
        this.someEntityKey = someEntityKey;
    }

    public String getSomeEntityName() {
        return someEntityName;
    }

    public void setSomeEntityName(String someEntityName) {
        this.someEntityName = someEntityName;
    }

    public OffsetDateTime getCreateOffsetDateTime() {
        return createOffsetDateTime;
    }

    public void setCreateOffsetDateTime(OffsetDateTime createOffsetDateTime) {
        this.createOffsetDateTime = createOffsetDateTime;
    }

}

还有其他地方的 ORM 映射代码? (在不同的模块/.jar 中)?

我发现了这个:

https://vladmihalcea.com/fluent-api-entity-building-with-jpa-and-hibernate/

不过,POJO 似乎充满了注释。

【问题讨论】:

    标签: jpa java-8 java-11


    【解决方案1】:

    是的。 JPA 规范指出:

    对象/关系映射信息可以采用以下形式 包含在托管持久性类上的注释 持久性单元,包含在 META-INF 目录中的 orm.xml 文件 持久性单元的根,一个或多个 XML 文件 类路径并从持久性中引用。 xml 文件,或 这些的组合。

    注解只是一种选择。所有映射信息都可以在 xml 文件中定义,或者两者的组合。在后一种情况下,xml 文件上的映射信息会覆盖注释。

    例如,这可能是一个META-INF/orm.xml 文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm 
                     http://xmlns.jcp.org/xml/ns/persistence/orm_2_2.xsd"
                     version="2.2">
        <entity class="com.mycompany.pojosandjpaannotationsmixed.SomeEntity">
            <table name="SomeEntityTable" />
            <attributes>
                <id name="someEntityKey">
                    <column name="SomeEntityKey" unique="true" />
                    <generated-value strategy="AUTO" />
                </id>
                <basic name="someEntityName">
                    <column name="SomeEntityName" unique="true" />
                </basic>
                <!--
                 .... 
                 -->
            </attributes>
        </entity>
    </entity-mappings>
    

    【讨论】:

    • 这个映射可以很容易地在 JSON 中定义,并且很多映射可以使用反射来推断。有没有 Java ORM 可以做到这一点?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多