上一节我们介绍了通过persistence.xml
初始化一个EntityManagerFactory
;但是在很多种情况下是不需要使用xml配置文件来配置持久化单元的,因此,我们今天来学习如何通过编程来自动初始化一个EntityManagerFactory
Hibernate早就为我们考虑到了这一点,它允许您完全以编程方式构建一个 EntityManagerFactory,只需几行代码:
protected EntityManagerFactory newEntityManagerFactory() {
PersistenceUnitInfo persistenceUnitInfo =
persistenceUnitInfo(getClass().getSimpleName());
Map<String, Object> configuration = new HashMap<>();
configuration.put(AvailableSettings.INTERCEPTOR,
interceptor()
);
return new EntityManagerFactoryBuilderImpl(
new PersistenceUnitInfoDescriptor(
persistenceUnitInfo), configuration
).build();
}
protected PersistenceUnitInfoImpl persistenceUnitInfo(
String name) {
return new PersistenceUnitInfoImpl(
name, entityClassNames(), properties()
);
}
每个测试都以一些合理的默认属性开始,并且必须在每个测试的基础上提供实体。
protected Properties properties() {
Properties properties = new Properties();
properties.put("hibernate.dialect",
dataSourceProvider().hibernateDialect()
);
properties.put("hibernate.hbm2ddl.auto",
"create-drop");
DataSource dataSource = newDataSource();
if (dataSource != null) {
properties.put("hibernate.connection.datasource",
dataSource);
}
return properties;
}
protected List entityClassNames() {
return Arrays.asList(entities())
.stream()
.map(Class::getName)
.collect(Collectors.toList());
}
每个测试可以定义自己的设置和实体,这样我们就可以封装整个环境。
@Override
protected Class<?>[] entities() {
return new Class<?>[] {
Patch.class
};
}
@Entity(name = "Patch")
public class Patch {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ElementCollection
@CollectionTable(
name="patch_change",
joinColumns=@JoinColumn(name="patch_id")
)
@OrderColumn(name = "index_id")
private List<Change> changes = new ArrayList<>();
public List<Change> getChanges() {
return changes;
}
}
@Embeddable
public class Change {
@Column(name = "path", nullable = false)
private String path;
@Column(name = "diff", nullable = false)
private String diff;
public Change() {
}
public Change(String path, String diff) {
this.path = path;
this.diff = diff;
}
public String getPath() {
return path;
}
public String getDiff() {
return diff;
}
}
以上代码简单吧,主要就是使用了两个关键的类EntityManagerFactoryBuilderImpl
和PersistenceUnitInfoImpl
进行了封装,第一个类负责创建EntityManagerFactory
,第二个类负责封装persistence.xml
的相关配置信息,因此,主要还是用这个类来实现持久化单元的可编程配置。
大家如果对此感兴趣,可以留言一起讨论。嘿嘿