hibernate 自然键 和 复合自然键

必须提醒你:当应用程序继承现有的遗留数据库Schema时,通常应该尽可能地对现有的Schema少做一些改变。你 
对Schema所做的每一处改变都可能破坏访问数据库的其他现有应用程序。现有数据的迁移可能很昂贵,这也是你要考虑 
的问题。一般来说,构建一个新的应用程序不可能不对现有的数据模型做任何改变--新应用程序通常意味着 
额外的业务需求,自然需要数据库Schema的演变。 




处理主键: 
不幸的是,遗留的数据库很多使用了自然主键、复合键,这样在业务需求改变时,很难重构数据库。 


1、映射自然键 
如你遇到的User表,可能userName是一个自燃键。那么你就需要告诉hibernate,标示符是在对象保存之前由应用 
分配的一个自燃键:
  1. <class name="User" table="USER">  
  2.     <!-- PRIMARY KEY  (`USER_NAME`) -->  
  3.     <id name="userName" column="USER_NAME">  
  4.         <generator class="assigned"></generator>  
  5.     </id>  
  6.     <property name="password"></property>  
  7. </class>  

JPA实现:
  1. @Entity  
  2. public class User implements Serializable {  
  3.     @Id  
  4.     @Column(name="USER_NAME")  
  5.     private String userName;  
  6.     private String password;  
  7.       


2、映射复合自然健 
复合主键单独抽取出来一个实体来表示主键会比较优雅
代码: 
UserID:要重装hashCode
  1. public class UserId implements Serializable {  
  2.     private String userCode;  
  3.     private String userName;  
  4.       
  5.     public UserId() {  
  6.         super();  
  7.     }  
  8.   
  9.     public UserId(String userCode, String userName) {  
  10.         super();  
  11.         this.userCode = userCode;  
  12.         this.userName = userName;  
  13.     }  
  14.   
  15.     public String getUserCode() {  
  16.         return userCode;  
  17.     }  
  18.   
  19.     public void setUserCode(String userCode) {  
  20.         this.userCode = userCode;  
  21.     }  
  22.   
  23.     public String getUserName() {  
  24.         return userName;  
  25.     }  
  26.   
  27.     public void setUserName(String userName) {  
  28.         this.userName = userName;  
  29.     }  
  30.   
  31.     @Override  
  32.     public int hashCode() {  
  33.         final int prime = 31;  
  34.         int result = 1;  
  35.         result = prime * result  
  36.                 + ((userCode == null) ? 0 : userCode.hashCode());  
  37.         result = prime * result  
  38.                 + ((userName == null) ? 0 : userName.hashCode());  
  39.         return result;  
  40.     }  
  41.   
  42.     @Override  
  43.     public boolean equals(Object obj) {  
  44.         if (this == obj)  
  45.             return true;  
  46.         if (obj == null)  
  47.             return false;  
  48.         if (getClass() != obj.getClass())  
  49.             return false;  
  50.         UserId other = (UserId) obj;  
  51.         if (userCode == null) {  
  52.             if (other.userCode != null)  
  53.                 return false;  
  54.         } else if (!userCode.equals(other.userCode))  
  55.             return false;  
  56.         if (userName == null) {  
  57.             if (other.userName != null)  
  58.                 return false;  
  59.         } else if (!userName.equals(other.userName))  
  60.             return false;  
  61.         return true;  
  62.     }  
  63.   
  64.     @Override  
  65.     public String toString() {  
  66.         return "UserId [userCode=" + userCode + ", userName=" + userName + "]";  
  67.     }  
  68.       
  69.       
  70. }  

User:
  1. public class User implements Serializable {  
  2.     private UserId userId;  
  3.     private String password;  
  4.       

查询比较特别:
  1. UserId userId = new UserId("code""hello");  
  2. User user = (User) session.get(User.class, userId);   


3、复合主键中的外键/4、复合主键的外键 
代码:
  1. public class User implements Serializable {  
  2.     private UserId userId;  
  3.     private String password;  
  4.     private Department department;  
  5.     private Set<Item> items = new HashSet<Item>();  
  6.       
  1. public class Department implements Serializable {  
  2.     private Integer departmentId;  
  3.     private String departmentName;  
  4.     private Set<User> users = new HashSet<User>();  
  1. public class Item implements Serializable {  
  2.     private Integer itemId;  
  3.     private String itemName;  
  4.     private User user;  
  5.       

配置文件:
  1.   <class name="User" table="USER">  
  2. <composite-id name="userId" class="UserId">  
  3.     <key-property name="userCode" column="USER_CODE"></key-property>  
  4.     <key-property name="userName" column="USER_NAME"></key-property>  
  5. </composite-id>  
  6.     <property name="password"></property>  
  7.       
  8.     <many-to-one name="department" class="Department"   
  9.         column="DEPARTMENT_ID"   
  10.         cascade="save-update"></many-to-one>  
  11.           
  12.     <set name="items" cascade="save-update" inverse="true">  
  13.         <key>  
  14.             <column name="USER_CODE"></column>  
  15.             <column name="USER_NAME"></column>  
  16.         </key>  
  17.         <one-to-many class="Item"/>  
  18.     </set>      
  19.   </class>  
  1. <class name="Department" table="Department">  
  2.     <id name="departmentId" column="DEPARTMENT_ID">  
  3.         <generator class="native"></generator>  
  4.     </id>  
  5.     <property name="departmentName" column="department_Name"></property>  
  6.       
  7.     <set name="users" inverse="true"  cascade="save-update">  
  8.         <key column="DEPARTMENT_ID"></key>  
  9.         <one-to-many class="User"/>  
  10.     </set>  
  11. </class>  
  1. <class name="Item" table="Item">  
  2.     <id name="itemId" column="item_Id">  
  3.         <generator class="native"></generator>  
  4.     </id>  
  5.     <property name="itemName" column="item_Name"></property>  
  6.       
  7.     <many-to-one name="user" class="User">  
  8. <column name="USER_CODE"></column>  
  9.         <column name="USER_NAME"></column>  
  10.     </many-to-one>  
  11. </class>  

插入:
  1. User user = new User("123");  
  2. UserId userId = new UserId("code""hello");  
  3. user.setUserId(userId);  
  4.   
  5. Department department = new Department("de hello");  
  6. user.setDepartment(department);  
  7.   
  8. Item item = new Item("item1");  
  9. user.getItems().add(item);  
  10.   
  11. //必须添加,因为,在<set name="items" cascade="save-update" inverse="true">设置了反向控制,  
  12. //那么就由Item的user属性来控制之间的关系,所以Item的user必须知道user的存在  
  13. //要知道这个东西和cascade="save-update"并不想干,cascade只是负责是否级联保存的,和表之间的关系由谁维护无关(这一点相信很多人都会搞混)  
  14. item.setUser(user);  
  15.   
  16. session.save(user);  
  17.                       

5、利用注解的复合键
  1. @Embeddable  
  2. public class UserId implements Serializable {  
  3.     private String userCode;  
  4.     private String userName;  
  1. @Entity  
  2. public class User implements Serializable {  
  3.     @Id  
  4.     @AttributeOverrides({  
  5.         @AttributeOverride(name="userCode",  
  6.                 column=@Column(name="user_Code")),  
  7.         @AttributeOverride(name="userName",  
  8.                 column=@Column(name="user_Name"))         
  9.                   
  10.     })  
  11.     private UserId userId;  
  12.     private String password;  
  13.     @OneToMany(mappedBy="user")  
  14.     private Set<Item> items = new HashSet<Item>();  
  1. @Entity  
  2. public class Item implements Serializable {  
  3.     @Id  
  4.     @GeneratedValue  
  5.     @Column(name="ITEM_ID")  
  6.     private Integer itemId;  
  7.     private String itemName;  
  8. //  KEY `FK22EF338367E49C` (`user_Code`,`user_Name`),  
  9. //  CONSTRAINT `FK22EF338367E49C` FOREIGN KEY (`user_Code`, `user_Name`) REFERENCES `user` (`user_Code`, `user_Name`)  
  10.     @ManyToOne  
  11.     @JoinColumns({  
  12.         @JoinColumn(name="user_Code"),  
  13.         @JoinColumn(name="user_Name")  
  14.     })  
  15.     private User user;    
  16.           
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值