Hibernate 表操作
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate 表操作相关的知识,希望对你有一定的参考价值。
表与表之间关系回顾
1. 一对多
(1) 分类和商品关系
(2) 客户和联系人
2. 多对多
(1) 订单和商品
(2) 用户和角色
3. 一对一
Hibernate一对多操作
级联:同时对多个表的数据进行操作
1. 一对多映射操作(one to many)
以客户与联系人为例
(1) 实体类创建:
One:Customer(客户实体类):关键点在于存储联系人实例的集合属性(Set),它用于存储对应每一个联系人的对象
1 /** 2 * 关键点:在于存储LinkMan的Set集合属性,用于存储联系人对象的集合 3 */ 4 5 import java.util.HashSet; 6 import java.util.Set; 7 8 public class Customer { 9 // 客户ID 10 private Integer cId; 11 12 // 客户名称 13 private String custName; 14 15 // 客户级别 16 private String custLevel; 17 18 // 客户来源 19 private String custSource; 20 21 // 联系电话 22 private String custPhone; 23 24 // 手机 25 private String custMobile; 26 27 // 联系人:在客户实体类里面表示多个联系人,实体类其中一个属性存储多个联系人。 28 private Set<LinkMan> setLinkMan = new HashSet<LinkMan>(); 29 30 // 无参构造函数 31 public Customer() { 32 } 33 34 public Integer getcId() { 35 return cId; 36 } 37 38 public void setcId(Integer cId) { 39 this.cId = cId; 40 } 41 42 public String getCustName() { 43 return custName; 44 } 45 46 public void setCustName(String custName) { 47 this.custName = custName; 48 } 49 50 public String getCustLevel() { 51 return custLevel; 52 } 53 54 public void setCustLevel(String custLevel) { 55 this.custLevel = custLevel; 56 } 57 58 public String getCustSource() { 59 return custSource; 60 } 61 62 public void setCustSource(String custSource) { 63 this.custSource = custSource; 64 } 65 66 public String getCustPhone() { 67 return custPhone; 68 } 69 70 public void setCustPhone(String custPhone) { 71 this.custPhone = custPhone; 72 } 73 74 public String getCustMobile() { 75 return custMobile; 76 } 77 78 public void setCustMobile(String custMobile) { 79 this.custMobile = custMobile; 80 } 81 82 public Set<LinkMan> getSetLinkMan() { 83 return setLinkMan; 84 } 85 86 }
Many:LinkMan(联系人实体类):关键点在于存储客户实例的Customer的属性,它用于存储对应的客户对象。
1 /** 2 * 关键点:在于Customer属性,它用于存储对应的客户对象。 3 */ 4 5 public class LinkMan { 6 // 联系人ID 7 private Integer lkmId; 8 9 // 联系人姓名 10 private String lkmName; 11 12 // 联系人性别 13 private String lkmGender; 14 15 // 联系人办公电话 16 private String lkmPhone; 17 18 // 在联系人实体类里面表示所属客户,一个联系人只能有一个客户 19 // 存储对应的客户对象 20 private Customer customer; 21 22 public LinkMan() { 23 } 24 25 public Integer getLkmId() { 26 return lkmId; 27 } 28 29 public void setLkmId(Integer lkmId) { 30 this.lkmId = lkmId; 31 } 32 33 public String getLkmName() { 34 return lkmName; 35 } 36 37 public void setLkmName(String lkmName) { 38 this.lkmName = lkmName; 39 } 40 41 public String getLkmGender() { 42 return lkmGender; 43 } 44 45 public void setLkmGender(String lkmGender) { 46 this.lkmGender = lkmGender; 47 } 48 49 public String getLkmPhone() { 50 return lkmPhone; 51 } 52 53 public void setLkmPhone(String lkmPhone) { 54 this.lkmPhone = lkmPhone; 55 } 56 57 public Customer getCustomer() { 58 return customer; 59 } 60 61 public void setCustomer(Customer customer) { 62 this.customer = customer; 63 } 64 65 }
(2) 映射文件配置:
Customer.hbm.xml:关键点在于set标签中配置Many(多方)信息
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4 <!-- Generated 2017-10-1 0:18:54 by Hibernate Tools 3.5.0.Final --> 5 <hibernate-mapping> 6 <class name="code.entity.Customer" table="CUSTOMER"> 7 <id name="cId" type="java.lang.Integer"> 8 <column name="CID" /> 9 <generator class="native" /> 10 </id> 11 <property name="custName" type="java.lang.String"> 12 <column name="CUSTNAME" /> 13 </property> 14 <property name="custLevel" type="java.lang.String"> 15 <column name="CUSTLEVEL" /> 16 </property> 17 <property name="custSource" type="java.lang.String"> 18 <column name="CUSTSOURCE" /> 19 </property> 20 <property name="custPhone" type="java.lang.String"> 21 <column name="CUSTPHONE" /> 22 </property> 23 <property name="custMobile" type="java.lang.String"> 24 <column name="CUSTMOBILE" /> 25 </property> 26 <!-- 在客户映射文件中,表示所有联系人 27 使用set标签标识所有联系人 28 set标签里面有name属性: 29 客户实体类里面表示联系人的set集合的属性名称 30 cascade: 31 级联配置,表示下级对象(LinkMan的对象会自动关联且保存) 32 inverse: 33 默认为false:表示不放弃外键关系维护 34 true:表示放弃外键关系维护 35 --> 36 <set name="setLinkMan" table="LINKMAN" cascade="save-update,delete" inverse="false"> 37 <!-- key:指外键 38 column:对应外键名称 39 hibernate机制:双向维护外键在One和Many都要配置外键 40 --> 41 <key> 42 <column name="CLID" /> 43 </key> 44 <!-- 配置实体类One和Many的关系 45 one-to-many:指定Many(多方)的class 46 class:Many(多方)实体类的全路径 47 --> 48 <one-to-many class="code.entity.LinkMan" /> 49 </set> 50 </class> 51 </hibernate-mapping>
LinkMan.hbm.xml:
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4 <!-- Generated 2017-10-1 0:18:54 by Hibernate Tools 3.5.0.Final --> 5 <hibernate-mapping> 6 <class name="code.entity.LinkMan" table="LINKMAN"> 7 <id name="lkmId" type="java.lang.Integer"> 8 <column name="LKMID" /> 9 <generator class="native" /> 10 </id> 11 <property name="lkmName" type="java.lang.String"> 12 <column name="LKMNAME" /> 13 </property> 14 <property name="lkmGender" type="java.lang.String"> 15 <column name="LKMGENDER" /> 16 </property> 17 <property name="lkmPhone" type="java.lang.String"> 18 <column name="LKMPHONE" /> 19 </property> 20 21 <!-- 表示联系人所属客户 22 name:存储Customer对象属性的属性名(customer) 23 class:指向Customer实体类的全路径 24 column:外键名称[创建数据表字段名称](跟One[一方]配置的key值一致) 25 --> 26 <many-to-one name="customer" class="code.entity.Customer" 27 fetch="join"> 28 <column name="CID" /> 29 </many-to-one> 30 </class> 31 </hibernate-mapping>
2. 一对多级联保存(在One[一方]的映射文件配置cascade属性 = "save-update")
1 package code.test; 2 3 import org.hibernate.Session; 4 import org.hibernate.SessionFactory; 5 import org.hibernate.Transaction; 6 import org.junit.Test; 7 8 import code.entity.Customer; 9 import code.entity.LinkMan; 10 import code.utils.HibernateUtil; 11 12 public class TestCode { 13 @Test 14 public void testSave() { 15 // Hibernate版本 5.2.11 16 SessionFactory sf = HibernateUtil.getSessionFactory();// 获取SessionFactory 17 Session session = sf.openSession();// 打开session 18 Transaction transaction = session.beginTransaction();// 开启事务 19 20 // 创建客户对象 21 Customer c = new Customer(); 22 c.setCustName("CNAME"); 23 c.setCustLevel("vip"); 24 c.setCustMobile("020123123"); 25 c.setCustPhone("123123"); 26 c.setCustSource("source"); 27 28 // 创建联系人 29 30 LinkMan l = new LinkMan(); 31 l.setLkmName("kname"); 32 l.setLkmGender("测试"); 33 l.setLkmPhone("123123"); 34 35 // 将客户对象保存到联系人的客户属性成员中 36 // 当在Customer.hbm.xml中的set标签中配置了cascade="save-update"后,盖面这行代码便可不用操作 37 // l.setCustomer(c); 38 39 // 客户对象set属性,用于保存联系人对象信息 40 // 将联系人添加至客户对象的set集合属性成员中 41 c.getSetLinkMan().add(l); 42 43 // 保存对象 44 session.save(c); 45 session.save(l); 46 47 // 提交事务 48 transaction.commit(); 49 50 // 关闭资源 51 session.close(); 52 sf.close(); 53 } 54 }
3. 一对多级联删除(在One[一方]的映射文件配置cascade属性 = "delete")
1 @Test 2 public void testDelete() { 3 // Hibernate版本 5.2.11 4 SessionFactory sf = HibernateUtil.getSessionFactory();// 获取SessionFactory 5 Session session = sf.openSession();// 打开session 6 Transaction transaction = session.beginTransaction();// 开启事务 7 Customer customer = session.get(Customer.class, 1); 8 session.delete(customer); 9 10 // 执行事务 11 transaction.commit(); 12 13 // 关闭资源 14 session.close(); 15 sf.close(); 16 }
4. 一对多级联更新
1 @Test 2 public void testUpdate() { 3 // Hibernate版本 5.2.11 4 SessionFactory sf = HibernateUtil.getSessionFactory();// 获取SessionFactory 5 Session session = sf.openSession();// 打开session 6 Transaction transaction = session.beginTransaction();// 开启事务 7 8 // 获取客户对象 9 Customer customer = session.get(Customer.class, 1); 10 // 获取联系人对象 11 LinkMan lm = session.get(LinkMan.class, 3); 12 13 // 将linkman对象添加到customer的set集合属性中 14 customer.getSetLinkMan().add(lm); 15 16 //LinkMan保存customer 17 lm.setCustomer(customer); 18 19 // 更新 20 // session.update(customer); 21 22 // 提交事务 23 transaction.commit(); 24 25 // 关闭资源 26 session.close(); 27 sf.close(); 28 }
5. inverse属性
因为hibernate双向维护外键,在客户和联系人里面都需要维护外键,修改客户时修改一次外键,修改联系人时也修改了一次外键,共修改了两次,造成效率问题。
让一方不维护外键,在One(一方)的映射文件中set标签上使用inverse属性。
Hibernate多对多操作(多对多建表操作中,实体类之间存在着第三张表,用于间接联系数据之间的关系
以用户和角色为例
1. 创建理由互相表示关系的实体类
1 /** 2 * 实体类:User创建 3 */ 4 import java.util.HashSet; 5 import java.util.Set; 6 7 public class User { 8 private Integer userId;// 用户ID 9 private String userName;// 用户名称 10 private String userPassword;// 用户密码 11 private Set<Role> roleSet = new HashSet<Role>(); 12 13 public User() { 14 } 15 16 public User(String userName, String userPassword) { 17 super(); 18 this.userName = userName; 19 this.userPassword = userPassword; 20 } 21 22 public Integer getUserId() { 23 return userId; 24 } 25 26 public void setUserId(Integer userId) { 27 this.userId = userId; 28 } 29 30 public String getUserName() { 31 return userName; 32 } 33 34 public void setUserName(String userName) { 35 this.userName = userName; 36 } 37 38 public String getUserPassword() { 39 return userPassword; 40 } 41 42 public void setUserPassword(String userPassword) { 43 this.userPassword = userPassword; 44 } 45 46 public Set<Role> getRoleSet() { 47 return roleSet; 48 } 49 50 public void setRoleSet(Set<Role> roleSet) { 51 this.roleSet = roleSet; 52 } 53 54 }
1 /** 2 * 实体类:Role创建 3 */ 4 5 import java.util.HashSet; 6 import java.util.Set; 7 8 public class Role { 9 private Integer roleId;// 角色ID 10 private String roleName;// 角色名称 11 private String roleMemo;// 角色描述 12 private Set<User> userSet = new HashSet<User>();; 13 14 public Role() { 15 } 16 17 public Role(String roleName, String roleMemo) { 18 super(); 19 this.roleName = roleName; 20 this.roleMemo = roleMemo; 21 } 22 23 public Integer getRoleId() { 24 return roleId; 25 } 26 27 public void setRoleId(Integer roleId) { 28 this.roleId = roleId; 29 } 30 31 public String getRoleName() { 32 return roleName; 33 } 34 35 public void setRoleName(String roleName) { 36 this.roleName = roleName; 37 } 38 39 public String getRoleMemo() { 40 return roleMemo; 41 } 42 43 public void setRoleMemo(String roleMemo) { 44 this.roleMemo = roleMemo; 45 } 46 47 public Set<User> getUserSet() { 48 return userSet; 49 } 50 51 public void setUserSet(Set<User> userSet) { 52 this.userSet = userSet; 53 } 54 55 }
2. 多对多映射关系配置(在映射文件中使用set标签进行配置)
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4 <hibernate-mapping> 5 <class name="code.entity.User" table="USER"> 6 <id name="userId" type="java.lang.Integer"> 7 <column name="USERID" /> 8 <generator class="native" /> 9 </id> 10 <property name="userName" type="java.lang.String"> 11 <column name="USERNAME" /> 12 </property> 13 <property name="userPassword" type="java.lang.String"> 14 <column name="USERPASSWORD" /> 15 </property> 16 17 <!-- 18 表示所有的Role 19 name属性:角色的set集合名称 20 table属性:第三张表名称 21 cascade属性:哪些执行语句会启用级联操作 22 save-update:保存/更新时启用级联操作 23 delete:删除时启用级联操作 24 --> 25 <set name="roleSet" table="USER_ROLE" cascade="save-update,dalete" inverse="false" lazy="true"> 26 <!-- KEY标签里面配置 27 配置当前映射文件在第三张表的字段名称 28 --> 29 <key> 30 <column name="USERID" /> 31 </key> 32 <!-- class:多对多映射的实体类全路径 33 column:该实体类在第三张表的外键名称 34 --> 35 <many-to-many class="code.entity.Role" column="ROLEID"/> 36 </set> 37 </class> 38 </hibernate-mapping>
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4 <hibernate-mapping> 5 <class name="code.entity.Role" table="ROLE"> 6 <id name="roleId" type="java.lang.Integer"> 7 <column name="ROLEID" /> 8 <generator class="assigned" /> 9 </id> 10 <property name="roleName" type="java.lang.String"> 11 <column name="ROLENAME" /> 12 </property> 13 <property name="roleMemo" type="java.lang.String"> 14 <column name="ROLEMEMO" /> 15 </property> 16 17 <!-- 18 表示所有的Role 19 name属性:角色的set集合名称 20 table属性:第三张表名称 21 --> 22 <set name="userSet" table="USER_ROLE" cascade="save-update" inverse="false" lazy="true"> 23 <!-- KEY标签里面配置 24 配置当前映射文件在第三张表的字段名称 25 --> 26 <key> 27 <column name="ROLEID" /> 28 </key> 29 <!-- class:多对多映射的实体类全路径 30 column:该实体类在第三张表的外键名称 31 --> 32 <many-to-many class="code.entity.User" column="USERID"/> 33 </set> 34 </class> 35 </hibernate-mapping>
3. 多对多级联保存
1 /* 2 * 多对多 - 级联保存演示 3 */ 4 5 import org.hibernate.Session; 6 import org.hibernate.SessionFactory; 7 import org.hibernate.Transaction; 8 import org.junit.Test; 9 10 import code.entity.Role; 11 import code.entity.User; 12 import code.utils.HibernateUtil; 13 14 public class TestCode { 15 @Test 16 public void testSave() { 17 // Hibernate版本 5.2.11 18 SessionFactory sf = HibernateUtil.getSessionFactory();// 获取SessionFactory 19 Session session = sf.openSession();// 打开session 20 Transaction transaction = session.beginTransaction();// 开启事务 21 22 // 创建用户(2个) 23 User user1 = new User("一号用户", "123"); 24 User user2 = new User("二号用户", "456"); 25 26 // 创建角色(3个) 27 Role role1 = new Role("角色一号", "一号"); 28 Role role2 = new Role("角色二号", "二号"); 29 Role role3 = new Role("角色三号", "三号"); 30 31 // 给用户添加角色 32 user1.getRoleSet().add(role1); 33 user1.getRoleSet().add(role2); 34 35 user2.getRoleSet().add(role2); 36 user2.getRoleSet().add(role3); 37 38 // 保存用户对象 39 session.save(user1); 40 session.save(user2); 41 42 // 执行事务 43 transaction.commit(); 44 45 // 关闭资源 46 session.close(); 47 sf.close(); 48 } 49 }
4. 维护第三张表
1) 用户和角色多对多关系,维护关系通过第三张表维护,该表间接体现了用户与角色之间的关系
2) 让某个用户有某个角色(增加角色关系)
- 获取/新建用户对象;获取/新建角色对象
- 将角色对象放到用户的set集合属性中
1 public class TestCode { 2 @Test 3 public void testAddRoleIntoUser() { 4 // Hibernate版本 5.2.11 5 SessionFactory sf = HibernateUtil.getSessionFactory();// 获取SessionFactory 6 Session session = sf.openSession();// 打开session 7 Transaction transaction = session.beginTransaction();// 开启事务 8 9 // 获取用户对象 10 User user = session.get(User.class, 1); 11 12 // 获取角色对象 13 Role role = session.get(Role.class, 3); 14 15 // 获取set集合属性,并添加角色 16 user.getRoleSet().add(role); 17 18 // 执行事务 19 transaction.commit(); 20 21 // 关闭资源 22 session.close(); 23 sf.close(); 24 } 25 }
3) 让某个用户没有某个角色(移除角色关系)
- 根据ID查询用户
- 获取用户对象的set集合属性,调用remove方法将角色对象从set集合中移除
1 public class TestCode { 2 @Test 3 public void testRemoveRoleOutUser() { 4 // Hibernate版本 5.2.11 5 SessionFactory sf = HibernateUtil.getSessionFactory();// 获取SessionFactory 6 Session session = sf.openSession();// 打开session 7 Transaction transaction = session.beginTransaction();// 开启事务 8 9 // 获取用户对象 10 User user = session.get(User.class, 2); 11 12 // 获取角色对象 13 Role role = session.get(Role.class, 3); 14 15 user.getRoleSet().remove(role); 16 17 // 执行事务 18 transaction.commit(); 19 20 // 关闭资源 21 session.close(); 22 sf.close(); 23 } 24 }
以上是关于Hibernate 表操作的主要内容,如果未能解决你的问题,请参考以下文章
具有运行时 pojos 的带有 Hibernate 的 OSGi 片段包