我有一个有两个字段的表我希望有两个对象.
第一个只有field1
@Entity(name = "simpleTableObject")
@Table(name = "someTable")
public class SimpleTableObject
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
protected long id;
@Column(name = "field1")
private String field1;
Run Code Online (Sandbox Code Playgroud)
第二个有两个领域
@Entity(name = "tableObject")
@Table(name = "someTable")
public class TableObject
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
protected long id;
@Column(name = "field1")
private String field1;
@Column(name = "field2")
private String field2;
Run Code Online (Sandbox Code Playgroud)
我使用加载每一个
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public List get(Class aClass)
{
ClassMetadata hibernateMetadata = sessionFactory.getClassMetadata(aClass);
if (hibernateMetadata == null)
{
return null;
}
if (hibernateMetadata instanceof AbstractEntityPersister)
{
AbstractEntityPersister persister = (AbstractEntityPersister) hibernateMetadata;
String tableName = persister.getTableName();
if (tableName != null)
{
return sessionFactory.getCurrentSession().
createQuery("from " + tableName).list();
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
我想做的是TableObject扩展SimpleTableObject.我该怎么做呢?
如果您想在所需表中保存公共字段意味着假设您有 A 类和 B 类,并且您有一些公共字段,如 created_by,updated_by 并且您想在两个实体中保存 field1,field2:IN 数据库级别:
query> select * from A;
+----++------------------------+
| id | created_by | updated_by |
+----+------------+------------+
| 3 | xyz | abc |
+----+------------+------------+
query> select * from B;
+----++------------------------+
| id | created_by | updated_by |
+----+------------+------------+
| 3 | xyz | abc |
+----+------------+------------+
Run Code Online (Sandbox Code Playgroud)
对于这种类型的结构,您应该像@Dragan Bozanovic 建议的那样使用@MappedSuperclass
但是,如果您想要父子关系并希望为每个类生成表,那么您可以使用 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 它将为每个类创建表,例如:假设您有 2 个类 Payment 和 CreditCard,Payment 是 CreditCard 的父类。
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Payment {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private int id;
@Column(nullable = false)
private double amount;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
}
@Entity
public class CreditCard extends Payment {
private String ccNumber;
private Date expireDate;
public String getCcNumber() {
return ccNumber;
}
public void setCcNumber(String ccNumber) {
this.ccNumber = ccNumber;
}
public Date getExpireDate() {
return expireDate;
}
public void setExpireDate(Date expireDate) {
this.expireDate = expireDate;
}
}
Run Code Online (Sandbox Code Playgroud)
现在您将保存日期:
public class TestConcreteClasses {
public static void main(String[] args) {
Payment payment = new Payment();
payment.setAmount(52.6);
createData(payment);
CreditCard creditCard = new CreditCard();
creditCard.setAmount(10);
creditCard.setCcNumber("2536985474561236");
creditCard.setExpireDate(new Date());
createData(creditCard);
}
private static void createData(Payment instance) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
session.save(instance);
session.getTransaction().commit();
}
}
Run Code Online (Sandbox Code Playgroud)
然后数据将保存
query> select * from Payment;
+----+--------+
| id | amount |
+----+--------+
| 1 | 52.6 |
+----+--------+
1 row in set (0.00 sec)
select * from CreditCard;
+----+--------+------------------+---------------------+
| id | amount | ccNumber | expireDate |
+----+--------+------------------+---------------------+
| 2 | 10 | 2536985474561236 | 2017-03-12 14:10:15 |
+----+--------+------------------+---------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
hibernate 中使用了 3 种类型的继承,这里是继承的 hibernate doc https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/InheritanceType.html,你应该根据你的要求。
小智 6
我能够对你的问题做些什么.我定义了另一个类层次结构:UserWithRole扩展了User,它类似于你的.
User为具有继承策略的实体SINGLE_TABLE:@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "USERS")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
@Column(nullable = false)
protected String name;
// toString(), default constructor, setters/getters, more constructors.
...
}
Run Code Online (Sandbox Code Playgroud)
这种继承策略有一个相当大的缺点:
还有另一种策略JOINED允许在子类中创建不可为空的列.它为每个子类创建一个附加表,这些表具有FK到超类表.
UserWithRole类:@Entity
public class UserWithRole extends User {
private String role;
// toString(), default constructor, setters/getters, more constructors.
...
}
Run Code Online (Sandbox Code Playgroud)
Helper类以在数据库中创建用户并使用您的查询:@Component
public class Helper {
@Autowired
EntityManager entityManager;
@Transactional
public void createUsers() {
for (long i = 0; i < 10; i++) {
User user;
if (i % 2 == 0) {
user = new UserWithRole("User-" + i, "Role-" + i);
} else {
user = new User("User-" + i);
}
entityManager.persist(user);
}
entityManager.flush();
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public < T > List < T > get(Class < T > aClass) {
SessionFactory sessionFactory = entityManager.getEntityManagerFactory().unwrap(SessionFactory.class);
ClassMetadata hibernateMetadata = sessionFactory.getClassMetadata(aClass);
if (hibernateMetadata == null) {
return null;
}
if (hibernateMetadata instanceof AbstractEntityPersister) {
AbstractEntityPersister persister = (AbstractEntityPersister) hibernateMetadata;
String entityName = persister.getEntityName();
if (entityName != null) {
return sessionFactory.getCurrentSession().
createQuery("from " + entityName).list();
}
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
如你所见,我改变了你的方法:
User实例:@Test
public void testQueryUsers() {
helper.createUsers();
for (User user: helper.get(User.class)) {
System.out.println(user);
}
}
Run Code Online (Sandbox Code Playgroud)
输出(具有角色的用户仍然UserWithProfile是运行时的实例):
UserWithRole{id=1, name='User-0', role='Role-0'}
User{id=2, name='User-1'}
UserWithRole{id=3, name='User-2', role='Role-2'}
User{id=4, name='User-3'}
UserWithRole{id=5, name='User-4', role='Role-4'}
User{id=6, name='User-5'}
UserWithRole{id=7, name='User-6', role='Role-6'}
User{id=8, name='User-7'}
UserWithRole{id=9, name='User-8', role='Role-8'}
User{id=10, name='User-9'}
Run Code Online (Sandbox Code Playgroud)
Hibernate发出的SQL查询:
select
user0_.id as id2_0_,
user0_.name as name3_0_,
user0_.role as role4_0_,
user0_.dtype as dtype1_0_
from
users user0_
Run Code Online (Sandbox Code Playgroud)
UserWithProfile实例:@Test
public void testQueryUsersWithProfile() {
helper.createUsers();
for (User user: helper.get(UserWithRole.class)) {
System.out.println(user);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
UserWithRole{id=1, name='User-0', role='Role-0'}
UserWithRole{id=3, name='User-2', role='Role-2'}
UserWithRole{id=5, name='User-4', role='Role-4'}
UserWithRole{id=7, name='User-6', role='Role-6'}
UserWithRole{id=9, name='User-8', role='Role-8'}
Run Code Online (Sandbox Code Playgroud)
Hibernate发出的SQL查询:
select
userwithro0_.id as id2_0_,
userwithro0_.name as name3_0_,
userwithro0_.role as role4_0_
from
users userwithro0_
where
userwithro0_.dtype = 'UserWithRole'
Run Code Online (Sandbox Code Playgroud)
请告诉我这是你要找的.
您可以为两个实体都有一个共同的超类:
@MappedSuperclass
public abstract class AbstractTableObject {
// common mappings
}
@Entity
@Table(name = "someTable")
public class TableObject extends AbstractTableObject {
// remaining mappings
}
@Entity
@Table(name = "someTable")
@Immutable
public class SimpleTableObject extends AbstractTableObject {
// nothing here
}
Run Code Online (Sandbox Code Playgroud)
此外,您可以将SimpleTableObject实体标记为@Immutable如上所示,以便不会意外地保留或更新它.
| 归档时间: |
|
| 查看次数: |
8173 次 |
| 最近记录: |