hibernate多表操作1(六)多对一和一对多
来源:互联网 发布:数据库外键和主键 编辑:程序博客网 时间:2024/06/18 15:13
hibernate多表操作
多对一
创建学生和班级的类以及对应的映射文件,多对一的情况多个学生属于一个班级,以此为例。类中除了基本的属性需要在学生类中添加一个班级的引用。
班级类
package com.hibernate.entity;public class Grade implements java.io.Serializable{ private static final long serialVersionUID = 1L; private String id; private String gradeName;
学生类
package com.hibernate.entity;public class Student implements java.io.Serializable{ private static final long serialVersionUID = 1L; private String id; private String stuName; private Grade grade;}
在映射文件中普通的属性已经通过普通的标签进行了映射,对于引用的属性,需要运用many-to-one标签进行映射。注意该标签要在多的那一方类的映射文件中添加。
name属性:引用的名称;
class属性:对应的类可以指明也可以不指明;
column属性:外键名称自己随便起;
添加完该标签之后将映射文件添加到连接文件中。
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.hibernate.entity.Student" > <id name="id"> <generator class="uuid" /> </id> <property name="stuName" /> <many-to-one name="grade" class="com.hibernate.entity.Grade" column="fk_s_g"/> </class></hibernate-mapping>
测试类
public static void main(String[] args) { Configuration cfg = new Configuration().configure(); SchemaExport export = new SchemaExport(cfg); export.create(true, true); }
运行测试类结果中可以看到有生成两个表的语句和外键的语句。
观察数据库中生成的表,可以在学生表中看到外键已经被创建。
测试添加
将多个学生保存到一个班级中,创建一个班级临时对象,将班级类持久化,创建多个学生持久对象。
public static void saveManyToOne() { Grade grade = new Grade(); grade.setGradeName("测试班级1"); BaseDao.saveOrUpdate(grade); Student student1 = new Student(); student1.setStuName("娃娃"); student1.setGrade(grade); BaseDao.saveOrUpdate(student1); Student student2 = new Student(); student2.setStuName("张三"); student2.setGrade(grade); BaseDao.saveOrUpdate(student2); }
从运行结果的sql语句中可以看到外键已经insert进去。
可以看到已经将班级表的id拿来存到学生表中,是hibernate自己存储的。
测试查询
查学生类就可以了。当输出的信息包括班级是就会报错。
报错原因:配置文件中少配置一个属性。lazy:值为false,将其添加即可成功运行。属性设置为false,让延迟加载,其实本质是不让hibernate使用JDK的动态代理机制。
lazy=”false”指定此关联总是被预先抓取
<many-to-one name="grade" class="com.hibernate.entity.Grade" column="fk_s_g" lazy="false"/>
通过设置断点进行调试,在有该标签时,可以看到班级类的内容已经被获取到。
没有时添加该标签时,班级类的内容没有被获取。主要是因为他的底层用的是JDK的动态代理,当你不用的时候不查出来,用的时候才查出来。添加这个标签是屏蔽了动态代理。动态代理在查询数据时不是从数据库中查,从内容中查。就好比买火车票在代理商处买,而不是直接去火车站买更加方便。动态代理在此可以理解为不加载引用类中的属性。
从运行结果可以看出查询是先查从表(学生表)再查主表(班级表)。
一对多
一对多情况:一个班级包括多个学生。以此为例,完成一对多的操作,需要在班级类中装多个学生,在其中创建一个set集合(选择set因为选其他集合有下标最终会在数据库中生成表的字段),其中存储student,并声明该集合的get,set方法。删除掉在多对一时对学生类的操作。
private Set<Student> students=new HashSet<Student>(); public Set<Student> getStudents() { return students; } public void setStudents(Set<Student> students) { this.students = students; }
如何在映射文件中对集合来进行映射:运用set标签,name属性:是属性的名称;key标签是外键,其中的column属性值是外键名;关系用one-to-many标签,其中class属性是集合中存储内容对应的类名称。
<set name="students"> <key column="fk_s_g" /> <one-to-many class="com.hibernate.entity.Student" /> </set>
运行后查看生成的数据库发现与之前多对一生成的表是一致的,在学生表中生成了一个外键,说明两种情况的主外键关系是一致的,只是在类的层面发生变化。
测试添加
创建一个班级对象,通过集合对应的get方法得到班级里的学生集合,在往集合中添加学生,之后在将集合设置到班级里,在学生类里创建一个构造函数(通过姓名创建对象),将班级类持久化,学生是临时对象。
public static void saveOneToMany() { Grade grade=new Grade(); grade.setGradeName("测试一对多"); Set<Student> students=grade.getStudents(); students.add(new Student("张三")); students.add(new Student("李斯")); students.add(new Student("王五")); grade.setStudents(students); BaseDao.saveOrUpdate(grade); }
在主函数中运行此方法,因为是一个持久对象可以调用临时对象,会报如下错。
解决办法在set标签中添加cascade属性:级联操作。指明哪些操作会从父对象级联到关联的对象。
<set name="students" cascade="all">
再次运行,通过sql语句可以看到此时外键是通过更新完成的。
测试查询
查询比较麻烦因此一般将一对多转换为多对一,调用dao层方法查找班级,得到班级里面的学生集合,设置迭代器输出学生姓名,注意要在set标签中添加lazy属性并将值设置为false。
public static void findOneToMany(){ Grade grade=(Grade) BaseDao.getUser("from Grade where id='402881e55de38bcb015de38bd0e70001'"); System.out.println(grade.getGradeName()); Set<Student> students=grade.getStudents(); Iterator<Student> iter=students.iterator(); while(iter.hasNext()){ System.out.println(iter.next().getStuName()); } }
在一个类中添加是单向,当然也可以在两个类中都添加是双向,但这样做会造成一些不合理的问题,例如:转成json格式是会造成死循环。
- hibernate多表操作1(六)多对一和一对多
- Hibernate-一对多和多对一
- hibernate(八)注解基础、注解映射表、注解多表操作多对一和一对多
- Hibernate(六)实现一对多、多对一映射关联关系
- hibernate中多对一和一对多关联入门
- hibernate多对一和一对多实现
- hibernate的一对多和多对一关系映射
- hibernate多对一和一对多映射浅析
- hibernate的单向多对一和一对多
- hibernate多对一和一对多双向关联
- Hibernate一对多和多对一关系详解
- Hibernate一对多和多对一关系详解
- Hibernate中一对多和多对一关系
- hibernate多对一关联和一对多关联
- 【Hibernate】--关联关系映射:一对多和多对一
- Hibernate一对多和多对一关系详解
- hibernate里面的一对多和多对一映射
- Hibernate框架-多对一和一对多关联
- 电子邮件协议、FTP 和 CGI 编程
- Centos 环境Docker离线安装方式
- 安卓游戏接入的时候遇到的找不到V4包的方法checkSelfPermission
- 机器学习第五周(一)
- LINUX 学习第16天 redis
- hibernate多表操作1(六)多对一和一对多
- 服务器负载均衡技术
- selenium自学_元素基本定位方法
- 读取pcd文件 c++
- 欢迎使用CSDN-markdown编辑器
- mac terminal修改hosts
- Oracle之:Function :getcurrdate()
- matplotlib模块数据可视化-设置坐标轴
- Vue 头部动态添加数据