没有注释的 JPA ORM 映射是否可行?

Are JPA ORM Mappings without annotations possible?

在 c#(dotnet 核心)中,我可以定义一个 assembly/csproj 那

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

然后在另一个 assembly/csproj 中,我可以 "fluently" 定义 poco 和 ORM 之间的映射。 (例如 Entity Framework 或 NHibernate)。

这样的例子:(entity framework核心)

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 规范指出:

The object/relational mapping information can take the form of annotations on the managed persistence classes included in the persistence unit, an orm.xml file contained in the META-INF directory of the root of the persistence unit, one or more XML files on the classpath and referenced from the persistence. xml file, or a combination of these.

注释只是一个选项。所有映射信息都可以在 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>