没有注释的 JPA ORM 映射是否可行?
Are JPA ORM Mappings without annotations possible?
在 c#(dotnet 核心)中,我可以定义一个 assembly/csproj 那
- 仅包含 POCO(又名 POJO)类。
- 对任何其他库的引用为零。
- 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>
在 c#(dotnet 核心)中,我可以定义一个 assembly/csproj 那
- 仅包含 POCO(又名 POJO)类。
- 对任何其他库的引用为零。
- 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>