一、一对多(单向)
1.一对多单向关联中的一方
1 package com.zhidi.entity.one2many; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 /** 7 * 一对多关单向关联关系中的->一方 8 * 9 * @author lx 10 * 11 */ 12 public class Dept { 13 14 private Integer deptno; 15 private String dname; 16 private String loc; 17 // 需要持有多方的引用 18 private Set<Emp> emps = new HashSet<Emp>(); 19 20 public Integer getDeptno() { 21 return deptno; 22 } 23 24 public void setDeptno(Integer deptno) { 25 this.deptno = deptno; 26 } 27 28 public String getDname() { 29 return dname; 30 } 31 32 public void setDname(String dname) { 33 this.dname = dname; 34 } 35 36 public String getLoc() { 37 return loc; 38 } 39 40 public void setLoc(String loc) { 41 this.loc = loc; 42 } 43 44 public Set<Emp> getEmps() { 45 return emps; 46 } 47 48 public void setEmps(Set<Emp> emps) { 49 this.emps = emps; 50 } 51 52 }
2.一对多单向关联中的多方
1 package com.zhidi.entity.one2many; 2 3 import java.util.Date; 4 5 /** 6 * 一对多关单向关联关系中的->多方 7 * 8 * @author lx 9 * 10 */ 11 public class Emp { 12 13 private Integer empno; 14 private String ename; 15 private String job; 16 private Integer mgr; 17 private Double sal; 18 private Date hiredate; 19 20 public Integer getEmpno() { 21 return empno; 22 } 23 24 public void setEmpno(Integer empno) { 25 this.empno = empno; 26 } 27 28 public String getEname() { 29 return ename; 30 } 31 32 public void setEname(String ename) { 33 this.ename = ename; 34 } 35 36 public String getJob() { 37 return job; 38 } 39 40 public void setJob(String job) { 41 this.job = job; 42 } 43 44 public Integer getMgr() { 45 return mgr; 46 } 47 48 public void setMgr(Integer mgr) { 49 this.mgr = mgr; 50 } 51 52 public Double getSal() { 53 return sal; 54 } 55 56 public void setSal(Double sal) { 57 this.sal = sal; 58 } 59 60 public Date getHiredate() { 61 return hiredate; 62 } 63 64 public void setHiredate(Date hiredate) { 65 this.hiredate = hiredate; 66 } 67 68 }
3.文件配置
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping package="com.zhidi.entity.one2many" > 6 <class name="Dept" table="dept"> 7 <id name="deptno"> 8 <generator class="native"/> 9 </id> 10 <property name="dname"/> 11 <property name="loc"/> 12 <!-- 配置一对多 --> 13 <!-- cascade:设置级联操作 --> 14 <set name="emps" cascade="save-update,delete,delete-orphan"> 15 <!-- 配置外键字段名 --> 16 <key column="deptno"/> 17 <!-- 指定一对多关系的关联对象的类型 --> 18 <one-to-many class="Emp"/> 19 </set> 20 </class> 21 </hibernate-mapping>
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping package="com.zhidi.entity.one2many"> 6 <class name="Emp" table="emp"> 7 <id name="empno"> 8 <generator class="native" /> 9 </id> 10 <property name="ename" /> 11 <property name="job" /> 12 <property name="mgr" /> 13 <property name="sal" /> 14 <property name="hiredate" type="date" /> 15 </class> 16 </hibernate-mapping>
4.cfg核心配置(一下所有的都不写,包含在这里面)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-configuration PUBLIC 3 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 5 <hibernate-configuration> 6 <session-factory> 7 <!-- 为session工厂添加一些基础配置 --> 8 <!-- 驱动名称 --> 9 <property name="connection.driver_class">com.mysql.jdbc.Driver</property> 10 <!-- url --> 11 <property name="connection.url">jdbc:mysql://localhost:3306/db_hibernate</property> 12 <!-- 用户名 --> 13 <property name="connection.username">root</property> 14 <!-- 密码 --> 15 <property name="connection.password">root</property> 16 17 <!-- 可以添加一些其他配置 --> 18 <!-- 设置方言 --> 19 <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> 20 <property name="pool_size">1</property> 21 <!-- 配置session --> 22 <property name="current_session_context_class">thread</property> 23 <!-- 打印sql语句 --> 24 <property name="show_sql">false</property> 25 <!-- 格式化sql --> 26 <property name="format_sql">true</property> 27 28 <!-- <mapping resource="com/zhidi/entity/many2one/Emp.hbm.xml"/> 29 <mapping resource="com/zhidi/entity/many2one/Dept.hbm.xml"/> --> 30 31 <!-- <mapping resource="com/zhidi/entity/one2many/Emp.hbm.xml"/> 32 <mapping resource="com/zhidi/entity/one2many/Dept.hbm.xml"/> --> 33 34 <mapping resource="com/zhidi/entity/one2many/bothway/Emp.hbm.xml"/> 35 <mapping resource="com/zhidi/entity/one2many/bothway/Dept.hbm.xml"/> 36 37 <mapping resource="com/zhidi/entity/many2many/Student.hbm.xml"/> 38 <mapping resource="com/zhidi/entity/many2many/Course.hbm.xml"/> 39 40 </session-factory> 41 </hibernate-configuration>
二、一对多(双向)
1.一对多关双向关联关系中的->一方
1 package com.zhidi.entity.one2many.bothway; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 /** 7 * 一对多关双向关联关系中的->一方 8 * 9 * @author lx 10 * 11 */ 12 public class Dept { 13 14 private Integer deptno; 15 private String dname; 16 private String loc; 17 // 需要持有多方的引用 18 private Set<Emp> emps = new HashSet<Emp>(); 19 20 public Integer getDeptno() { 21 return deptno; 22 } 23 24 public void setDeptno(Integer deptno) { 25 this.deptno = deptno; 26 } 27 28 public String getDname() { 29 return dname; 30 } 31 32 public void setDname(String dname) { 33 this.dname = dname; 34 } 35 36 public String getLoc() { 37 return loc; 38 } 39 40 public void setLoc(String loc) { 41 this.loc = loc; 42 } 43 44 public Set<Emp> getEmps() { 45 return emps; 46 } 47 48 public void setEmps(Set<Emp> emps) { 49 this.emps = emps; 50 } 51 52 }
2.一对多关单向关联关系中的->多方
1 package com.zhidi.entity.one2many.bothway; 2 3 import java.util.Date; 4 5 /** 6 * 一对多关单向关联关系中的->多方 7 * 8 * @author lx 9 * 10 */ 11 public class Emp { 12 13 private Integer empno; 14 private String ename; 15 private String job; 16 private Integer mgr; 17 private Double sal; 18 private Date hiredate; 19 private Dept dept; 20 21 public Integer getEmpno() { 22 return empno; 23 } 24 25 public void setEmpno(Integer empno) { 26 this.empno = empno; 27 } 28 29 public String getEname() { 30 return ename; 31 } 32 33 public void setEname(String ename) { 34 this.ename = ename; 35 } 36 37 public String getJob() { 38 return job; 39 } 40 41 public void setJob(String job) { 42 this.job = job; 43 } 44 45 public Integer getMgr() { 46 return mgr; 47 } 48 49 public void setMgr(Integer mgr) { 50 this.mgr = mgr; 51 } 52 53 public Double getSal() { 54 return sal; 55 } 56 57 public void setSal(Double sal) { 58 this.sal = sal; 59 } 60 61 public Date getHiredate() { 62 return hiredate; 63 } 64 65 public void setHiredate(Date hiredate) { 66 this.hiredate = hiredate; 67 } 68 69 public Dept getDept() { 70 return dept; 71 } 72 73 public void setDept(Dept dept) { 74 this.dept = dept; 75 } 76 77 }
3.文件配置
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.zhidi.entity.one2many.bothway" > <class name="Dept" table="dept"> <id name="deptno"> <generator class="native"/> </id> <property name="dname"/> <property name="loc"/> <!-- 配置一对多 --> <!-- inverse:代表由谁来维护两者之间的关系,为false时,由当前实体维护对应关系 inverse=true,代表有对方来维护关系 --> <set name="emps" inverse="true"> <!-- 配置外键字段名 --> <key column="deptno"/> <!-- 指定一对多关系的关联对象的类型 --> <one-to-many class="Emp"/> </set> </class> </hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.zhidi.entity.one2many.bothway"> <class name="Emp" table="emp"> <id name="empno"> <generator class="native"/> </id> <property name="ename"/> <property name="job"/> <property name="mgr"/> <property name="sal"/> <!-- 当java中的类型对一数据库中的类型有多个时,需要明确指定其hibernate类型是什么 --> <property name="hiredate" type="date"/> <!-- 多对一 --> <many-to-one name="dept" column="deptno" class="Dept" cascade="save-update"/> </class> </hibernate-mapping>
三、多对一
1.多对一关单向关联关系中的->一方
package com.zhidi.entity.many2one; public class Dept { private Integer deptno; private String dname; private String loc; public Integer getDeptno() { return deptno; } public void setDeptno(Integer deptno) { this.deptno = deptno; } public String getDname() { return dname; } public void setDname(String dname) { this.dname = dname; } public String getLoc() { return loc; } public void setLoc(String loc) { this.loc = loc; } }
2.多对一关单向关联关系中的->多方
package com.zhidi.entity.many2one; import java.util.Date; /** * 多对一关单向关联关系中的->多方 * * @author lx * */ public class Emp { private Integer empno; private String ename; private String job; private Integer mgr; private Double sal; private Date hiredate; // 提供类型为Dept的成员变量 private Dept dept; public Integer getEmpno() { return empno; } public void setEmpno(Integer empno) { this.empno = empno; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public Integer getMgr() { return mgr; } public void setMgr(Integer mgr) { this.mgr = mgr; } public Double getSal() { return sal; } public void setSal(Double sal) { this.sal = sal; } public Date getHiredate() { return hiredate; } public void setHiredate(Date hiredate) { this.hiredate = hiredate; } public Dept getDept() { return dept; } public void setDept(Dept dept) { this.dept = dept; } }
3.文件配置
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.zhidi.entity.many2one" > <class name="Dept" table="dept"> <id name="deptno"> <generator class="native"/> </id> <property name="dname"/> <property name="loc"/> </class> </hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.zhidi.entity.many2one"> <class name="Emp" table="emp"> <id name="empno"> <generator class="native"/> </id> <property name="ename"/> <property name="job"/> <property name="mgr"/> <property name="sal"/> <property name="hiredate" type="date"/> <!-- 维护关系 --> <!-- cascade="save-update":设置级联保存 --> <many-to-one name="dept" column="deptno" class="Dept" cascade="save-update"/> </class> </hibernate-mapping>
4.测试
package com.zhidi.entity.many2one; import java.util.Date; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; public class Test { public static void main(String[] args) { Configuration cfg = new Configuration().configure(); SessionFactory sessionFactory = cfg .buildSessionFactory(new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build()); //获取session Session session = sessionFactory.getCurrentSession(); //开启事务 session.beginTransaction(); Emp emp = new Emp(); emp.setEname("肖"); emp.setJob("主播"); emp.setSal(10000.0); emp.setHiredate(new Date()); Dept dept = new Dept(); dept.setDname("斗鱼"); dept.setLoc("武汉"); //添加关联 emp.setDept(dept); //执行保存操作 //没有设置级联保存的情况下,要注意保存顺序,否则会出现多余的sql语句用来维护关联关系 //设置了级联保存,就只需要保存维护关系的一方 session.save(emp); // session.save(dept); session.getTransaction().commit(); } }
四、多对多
1.多对多的多方
package com.zhidi.entity.many2many; import java.util.HashSet; import java.util.Set; public class Course { private Integer id; private String name; // 学生集合 private Set<Student> students = new HashSet<Student>(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Student> getStudents() { return students; } public void setStudents(Set<Student> students) { this.students = students; } }
2.多对多的多方
package com.zhidi.entity.many2many; import java.util.HashSet; import java.util.Set; public class Student { private Integer id; private String name; private String sex; //课程 private Set<Course> courses = new HashSet<Course>(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Set<Course> getCourses() { return courses; } public void setCourses(Set<Course> courses) { this.courses = courses; } }
3.文件配置
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.zhidi.entity.many2many"> <class name="Course" table="tb_courses"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <!-- 当指定set元素的table属性时,会将关系维护到指定表中 --> <set name="students" table="tb_students_courses"> <!-- 指定当前表在中间表的外键 --> <key column="cou_id"/> <!-- 指定关系表中的外键,以及关系表的类型 --> <many-to-many column="stu_id" class="Student"/> </set> </class> </hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.zhidi.entity.many2many"> <class name="Student" table="tb_students"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <property name="sex"/> <!-- 关系 --> <set name="courses" table="tb_students_courses"> <key column="stu_id"/> <many-to-many column="cou_id" class="Course"/> </set> </class> </hibernate-mapping>
test
1 package com.zhidi.test.base; 2 3 import org.hibernate.Session; 4 import org.hibernate.SessionFactory; 5 import org.hibernate.boot.registry.StandardServiceRegistryBuilder; 6 import org.hibernate.cfg.Configuration; 7 import org.junit.After; 8 import org.junit.AfterClass; 9 import org.junit.Before; 10 import org.junit.BeforeClass; 11 12 public class BaseTest { 13 14 protected static SessionFactory sessionFactory; 15 protected Session session; 16 17 @BeforeClass 18 public static void beforeClass() { 19 Configuration cfg = new Configuration().configure(); 20 //初始化会话工厂 21 sessionFactory = cfg 22 .buildSessionFactory(new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build()); 23 } 24 25 @AfterClass 26 public static void afterClass() { 27 //如果会话工厂不为空,就关闭 28 if (sessionFactory != null) { 29 sessionFactory.close(); 30 } 31 } 32 33 @Before 34 public void beforeMethod() { 35 //获取session 36 session = sessionFactory.getCurrentSession(); 37 session.beginTransaction(); 38 } 39 40 @After 41 public void afterMethod() { 42 //有存活的事务就提交 43 if (session.getTransaction().isActive()) { 44 session.getTransaction().commit(); 45 } 46 } 47 48 49 }
以上的测试
1 package com.zhidi.test.retention; 2 3 import org.junit.Test; 4 5 import com.zhidi.entity.many2many.Course; 6 import com.zhidi.entity.many2many.Student; 7 import com.zhidi.test.base.BaseTest; 8 9 public class TestMany2Many extends BaseTest{ 10 11 @Test 12 public void testSave() { 13 Student stu = new Student(); 14 stu.setName("赵日天"); 15 stu.setSex("男"); 16 17 Course course = new Course(); 18 course.setName("马克思理论"); 19 20 course.getStudents().add(stu); 21 // stu.getCourses().add(course); 22 23 session.save(stu); 24 session.save(course); 25 } 26 27 @Test 28 public void test() { 29 Student stu = (Student) session.get(Student.class, 2); 30 System.out.println(stu.getCourses()); 31 } 32 33 }
1 package com.zhidi.test.retention; 2 3 import org.junit.Test; 4 5 import com.zhidi.entity.many2one.Emp; 6 import com.zhidi.test.base.BaseTest; 7 8 public class TestMany2One extends BaseTest { 9 10 @Test 11 public void test() { 12 //延迟加载 13 //查询员工 14 Emp emp = (Emp) session.get(Emp.class, 7958); 15 //在使用关联实体的非主键字段时,会发送sql语句查询出关联实体,关联属性要使用的时候才会去查询 16 System.out.println(emp.getDept().getDeptno()); 17 18 session.close(); 19 20 //延迟加载只能在session的生命周期之内 21 System.out.println(emp.getDept().getDname()); 22 23 } 24 25 }
1 package com.zhidi.test.retention; 2 3 import java.util.Date; 4 import java.util.Set; 5 6 import org.junit.Test; 7 8 import com.zhidi.entity.one2many.Dept; 9 import com.zhidi.entity.one2many.Emp; 10 import com.zhidi.test.base.BaseTest; 11 12 public class TestOne2Many extends BaseTest { 13 14 /** 15 * 没有设置级联保存,会有3条sql 16 * insert emp ... 17 * insert dept ... 18 * update emp set deptno=? where empno=? 19 */ 20 @Test 21 public void testSave() { 22 Emp emp = new Emp(); 23 emp.setEname("王尼玛"); 24 emp.setJob("逗比"); 25 emp.setSal(2000d); 26 emp.setHiredate(new Date()); 27 28 Dept dept = new Dept(); 29 dept.setDname("暴漫"); 30 dept.setLoc("杭州"); 31 32 //关系由部门维护 33 dept.getEmps().add(emp); 34 35 session.save(dept); 36 session.save(emp); 37 } 38 39 /** 40 * cascade=save-update,只需要保存关系维护方 41 */ 42 @Test 43 public void testSave2() { 44 Emp emp = new Emp(); 45 emp.setEname("张全蛋"); 46 emp.setJob("富土康员工"); 47 emp.setSal(800d); 48 emp.setHiredate(new Date()); 49 50 Dept dept = new Dept(); 51 dept.setDname("暴漫"); 52 dept.setLoc("杭州"); 53 54 //关系由部门维护 55 dept.getEmps().add(emp); 56 57 session.save(dept); 58 } 59 60 /** 61 * 在没有cascade=delete时,删除主表数据会执行以下操作 62 * 1.update emp set deptno=null where ename=? 63 * 2.delete from dept where deptno=? 64 */ 65 @Test 66 public void testDelete() { 67 Dept dept = (Dept) session.get(Dept.class, 91); 68 session.delete(dept); 69 } 70 71 /** 72 * 设置cascade=delete 73 * 设置了级联删除 74 */ 75 @Test 76 public void testDelete2() { 77 Dept dept = (Dept) session.get(Dept.class, 90); 78 session.delete(dept); 79 } 80 81 /** 82 * 没有设置cascade=delete-orphan, 83 * 直接解除关系,但是不会删除数据 84 */ 85 @Test 86 public void testRemove() { 87 Dept dept = (Dept) session.get(Dept.class, 89); 88 Set<Emp> emps = dept.getEmps(); 89 for (Emp emp : emps) { 90 dept.getEmps().remove(emp); 91 } 92 } 93 94 /** 95 * 设置cascade=delete-orphan, 96 * 直接将解除关系的关联数据给删除掉 97 */ 98 @Test 99 public void testRemove2() { 100 Dept dept = (Dept) session.get(Dept.class, 82); 101 Set<Emp> emps = dept.getEmps(); 102 for (Emp emp : emps) { 103 dept.getEmps().remove(emp); 104 } 105 } 106 }
1 package com.zhidi.test.retention; 2 3 import java.util.Calendar; 4 5 import org.junit.Test; 6 7 import com.zhidi.entity.one2many.bothway.Dept; 8 import com.zhidi.entity.one2many.bothway.Emp; 9 import com.zhidi.test.base.BaseTest; 10 11 public class TestOne2ManyBothway extends BaseTest { 12 13 /** 14 * inverse=false 15 */ 16 @Test 17 public void testSave() { 18 Dept dept = new Dept(); 19 dept.setDname("阿里妈妈"); 20 dept.setLoc("杭州"); 21 22 Emp emp = new Emp(); 23 emp.setEname("马云爸爸"); 24 Calendar calendar = Calendar.getInstance(); 25 calendar.set(1999, 0, 01); 26 emp.setHiredate(calendar.getTime()); 27 emp.setSal(1234d); 28 29 //添加依赖关系 30 emp.setDept(dept); 31 dept.getEmps().add(emp); 32 33 //当inverse=false或不设置时,会有多余sql语句来维护两者之间的关系 34 session.save(dept); 35 session.save(emp); 36 } 37 38 /** 39 * inverse=true,就不会产生多余的sql语句来维护对应关系 40 */ 41 @Test 42 public void testSave2() { 43 Dept dept = new Dept(); 44 dept.setDname("阿里妈妈"); 45 dept.setLoc("杭州"); 46 47 Emp emp = new Emp(); 48 emp.setEname("马云爸爸"); 49 Calendar calendar = Calendar.getInstance(); 50 calendar.set(1999, 0, 01); 51 emp.setHiredate(calendar.getTime()); 52 emp.setSal(1234d); 53 54 //添加依赖关系 55 emp.setDept(dept); 56 // dept.getEmps().add(emp); 57 58 // session.save(dept); 59 session.save(emp); 60 } 61 62 /** 63 * 现在关系是由员工来维护,所有部门解除依赖关系没有卵用 64 */ 65 @Test 66 public void testRemove() { 67 Dept dept = (Dept) session.get(Dept.class, 103); 68 dept.getEmps().clear(); 69 } 70 71 @Test 72 public void testRemove2() { 73 Emp emp = (Emp) session.get(Emp.class, 7983); 74 //解除关系会保存到数据库 75 emp.setDept(null); 76 } 77 }
eclipse中的分布和导包