1 hibernate 的对象关系映射
Orm:
类-----表
属性------字段
对象------记录
表:在数据库中存在主外键的关系,反向工厂类是由表生成,在由表生成类的时候,类和类之间存在者某个关系。将数据库的主外键关系,在java类型进行体现和维护(建立数据之间的关系和断开关系)。
2 单向的one-to-many
家庭和成员(家庭和成员之间的关系,是由家庭进行体现,成员不体现)
父亲和子女
班级和学生
……
2.1 单向one-to-many数据库的模型
在数据库中两张表,产生主外键关系。
描述班级和学生的关系
2.2单向one-to-many java中的模型体现
通过java中的pojo进行表之间关系的体现。
在班级中定义班级下的学生的集合。
2.3单向one-to-many的配置
Classes.hbm.xml
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="org.guangsoft.pojo"> 6 <!-- 类 到 表 --> 7 <class name="Classes" table="t_classes"> 8 <id name="cid" column="cid" type="java.lang.Integer"> 9 <generator class="native"></generator> 10 </id> 11 <!-- 其他简单属性 --> 12 <property name="cname" column="cname" type="java.lang.String"></property> 13 <!-- 进行单向one-to-many的映射配置 --> 14 <set name="stus" table="t_student"> 15 <key column="cid"></key> 16 <!-- one:表示的Classes班级 many:表示的Student学生 calss属性:表示set集合中元素的类型。 x-to-y:当前标签在谁的配置文件中,x就代表谁。y就表示对方。 17 <element column="cls" type="java.lang.String"></element> --> 18 <one-to-many class="Student" /> 19 </set> 20 </class> 21 </hibernate-mapping>
Student.hbm.xml
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="org.guangsoft.pojo"> 6 <!-- 类 到 表 --> 7 <class name="Student" table="t_student"> 8 <id name="sno" column="sno" type="java.lang.Integer"> 9 <generator class="native"></generator> 10 </id> 11 <!-- 其他简单属性 --> 12 <property name="sname" column="sname" type="java.lang.String"></property> 13 </class> 14 </hibernate-mapping>
2.4进行CRUD操作
2.4.1添加班级信息
班级为one的一方,在数据库中为主表。
1 /*** 2 * 添加班级信息 3 * ***/ 4 @Test 5 public void testSaveClasses(){ 6 //1获得会话session 7 Session session=sf.openSession(); 8 //2开启事务 9 Transaction tr=session.beginTransaction(); 10 //3进行增加操作 11 Classes cls = new Classes(); 12 //cls对象封装数据 13 cls.setCname("java逆袭班"); 14 session.save(cls); 15 //提交事务 16 tr.commit(); 17 //释放资源 18 session.close(); 19 }
2.4.2添加新班级和学生
在保存班级信息的时候,由于给班级对象,分配了学生信息,这时候会自动建立该班级和集合中学生的关系
1 /*** 2 * 添加班级的同时添加学生信息 3 * set标签的cascade属性:对象的级联操作,对某个对象进行crud操作的是, 4 * 同时操作该对象,关联的对象 5 * all:包含所有 6 * save-update:级联保存和更新,在one-to-many中,实际中通常设置为通过many去保存one 7 * delete:级联删除 8 * none:不级联(默认) 9 * ****/ 10 @Test 11 public void testSaveClasses2(){ 12 //1获得会话session 13 Session session=sf.openSession(); 14 //2开启事务 15 Transaction tr=session.beginTransaction(); 16 //3进行增加操作 17 Classes cls = new Classes(); 18 //cls对象封装数据 19 cls.setCname("java爆发班"); 20 /** 21 * 给班级分配学生信息 22 * ***/ 23 Student s1 = new Student(); 24 s1.setSname("朱元璋"); 25 Student s2 = new Student(); 26 s2.setSname("刘邦"); 27 //将s1,s2分配给cls(建立班级和学生的关系) 28 cls.getStus().add(s1); 29 cls.getStus().add(s2); 30 session.save(cls); 31 //提交事务 32 tr.commit(); 33 //释放资源 34 session.close(); 35 }
2.4.3 修改班级信息
1 /***更新班级信息 2 *级联更新:更新了班级下的学生的信息 3 * ***/ 4 @Test 5 public void testUpdate(){ 6 //1获得会话session 7 Session session=sf.openSession(); 8 //2开启事务 9 Transaction tr=session.beginTransaction(); 10 //3进行增加操作 11 Classes cls = (Classes) session.get(Classes.class, 3); 12 cls.setCname("javaee班"); 13 //获得该班级学生 14 Iterator<Student> its=cls.getStus().iterator(); 15 while(its.hasNext()){ 16 //获得某个学生信息 17 Student s=its.next(); 18 s.setSname(s.getSname()+"名字"); 19 } 20 session.update(cls); 21 //提交事务 22 tr.commit(); 23 //释放资源 24 session.close(); 25 }
2.4.4查询班级信息
同时关联加载 该班级下的所有学生。
1 /** 2 查询班级信息, 3 hibernate:在对象关联加载的时候,默认为延迟加载。 4 延迟加载:在加载A对象的时候,不会立即查询与A对象的其他对象 5 只有在访问A对象关联的其他对象的时候,(..)在进行数据库的查询 6 默认延迟加载:提供数据库的加载速度 7 * ***/ 8 @Test 9 public void testSelectClasses(){ 10 //1获得会话session 11 Session session=sf.openSession(); 12 //查询所有的班级 13 List<Classes> clist=session.createCriteria(Classes.class).list(); 14 //遍历集合 15 for(Classes c :clist){ 16 System.out.println(c.getCname()); 17 //访问班级下的学生信息 18 Set<Student> stus = c.getStus(); 19 //获得stus集合的迭代器 20 Iterator<Student> it = stus.iterator(); 21 while(it.hasNext()){ 22 //获得一个学生信息 23 Student s=it.next(); 24 System.out.println("\t\t"+s.getSname()+"\t\t"+c.getCname()); 25 } 26 } 27 //释放资源 28 session.close(); 29 }
2.4.5删除班级信息
需要删除主表中的数据,子表中关联的记录怎么处理:
断开主外键,删除主表中的数据,子表中的数据继续存在
主表,子表中的数据一起删除
1 /*** 2 删除班级信息 3 1 删除主表中数据的默认情况,断开主外键关系,删除主表中数据 4 2cascade级联删除 5 cascade="all" "delete" 6 主表,子表一起删除 7 delete-orphan:当通过控制方解除被控制的对象的时候。会自动将解除关系的对象进行删除 8 对HashSet集合的使用:注意重写两个方法hashCode 和 equals() 9 * ***/ 10 @Test 11 public void testDeleteClasses2(){ 12 //1获得会话session 13 Session session=sf.openSession(); 14 //2开启事务 15 Transaction tr=session.beginTransaction(); 16 //3进行增加操作 17 Classes cls = (Classes) session.get(Classes.class, 6); 18 //获得该班级的所有学生 19 Set<Student> stus=cls.getStus(); 20 Student s = new Student(); 21 s.setSno(6); 22 //删除集合中的某个学生(解除班级和学生的关系) 23 stus.remove(s); 24 //提交事务 25 tr.commit(); 26 //释放资源 27 session.close(); 28 } 29 /***给已有的班级,添加学生****/
2.4.5 出现问题
外键不允许为空造成:
使用hashSet集合注意:
hashCode方法
equals()方法
总结:cascade级联操作
All(save-update,delete) :级联保存,更新,删除
save-update:设置为one-to-many,将many的一方设置为save-update
delete:设置one-to-many,将one的一方设置为delete或者all
none:默认的删除是将主外键关系断开,(员工---工资)
来源:https://www.cnblogs.com/guanghe/p/6093546.html