hibernate-第二章-关系映射
一,持久化类
持久化类就是之前写过的实体类
持久化类必须符合javabean规范,属性必须有set和get方法;
持久化类的属性类型可以是8种基本类型或对应的包装类,通常定义包装类型,因为包装类型可以兼容null(private int id;---------private Integer id)
在对象关系映射文件(xxx.hbm.xml)中,property元素的access属性来指定访问持久化类属性的方式
access="field" 表示hibernate通过反射访问属性,可以不写set 和get方法
access="noop"表示实体类中没有对应的属性,但是数据库有
access="property" 默认值,表示hibernate通过属性的set 和get 方法访问属性
对象标识符
通常来说主键字段取名为"ID"
主键字段为整形
主键的set 方法权限设置为private,防止随意修改
二,主键生成器
主要负责我们生成数据库表中主键字段的值,通常有下面几种的配置:
(1):increment
对int,short,long的数据列生成自动增长主键
(2):identity
对SQLserver 和MySql等数据库支持自动增长的数据库
(3):sequence:
对Oracle和db2等支持序列的数据库
(4):uuid
对字符串采用uuid算法产生一个唯一的字符串主键
(5):native
根据底层的数据库支持情况自动选择identity,sequence,适合跨多种数据库的系统
若要修改主键生成器,需要在xxx.hbm.xml中配置
- <id name="id" type="int">
- <column name="ID" />
- <generator class="native" />
- </id>
三、1 vs 多
1、准备数据库和表
create table dept(
deptId int not null primary key auto_increment,
deptName varchar(20) not null
)
insert into dept values(0,'财务部');
insert into dept values(0,'开发部');
insert into dept values(0,'业务部');
insert into dept values(0,'产品部');
create table emp(
empId int not null primary key auto_increment,
deptId int references dept(deptId),
empNo char(4) not null unique,
empName varchar(20) not null,
empSex int not null,
empBirth date not null
)
insert into emp values(0,1,'E001','小明',0,'2010-10-10');
insert into emp values(0,1,'E002','小红',0,'2011-10-11');
insert into emp values(0,2,'E100','小芳',1,'2012-10-12');
insert into emp values(0,2,'E101','小王',1,'2013-10-13');
insert into emp values(0,3,'E200','小李',1,'2014-10-14');
insert into emp values(0,3,'E201','小赵',0,'2015-10-15');
2、创建maven项目
- <!-- MySQL数据库驱动 -->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>5.1.47</version>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.18.2</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-core</artifactId>
- <version>5.2.17.Final</version>
- </dependency>
3、实体类
- @Setter
- @Getter
- public class Dept {
- private Integer deptId;//主键
- private String deptName;//部门名称
- }
- @Setter
- @Getter
- public class Emp {
- private Integer empId; //主键
- private Integer deptId; //部门外键
- private String empNo;//员工编号
- private String empName;//员工姓名
- private Integer empSex;//员工性别
- private String empBirth;//员工生日
- }
4、hibernate.cfg.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE hibernate-configuration PUBLIC
- "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
- "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
- <hibernate-configuration>
- <session-factory>
- <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
- <property name="hibernate.connection.password">123456</property>
- <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate-test?characterEncoding=utf-8</property>
- <property name="hibernate.connection.username">root</property>
- <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
- <!-- 是否显示SQL语句 true-显示 -->
- <property name="hibernate.show_sql">true</property>
- </session-factory>
- </hibernate-configuration>
5、xxx.bhm.xml
Dept.hbm.xml
- <?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.yujun.maven.po.Dept" table="dept">
- <id name="deptId" type="int">
- <column name="deptId" />
- <generator class="native" />
- </id>
- <property name="deptName" type="java.lang.String">
- <column name="deptName" />
- </property>
- <!-- set就是用来配置集合属性 name:实体类中属性名 -->
- <set name="emps">
- <!-- key用来配置外键 column:外键字段名-->
- <key>
- <column name="deptId"></column>
- </key>
- <!-- 1-多 class:配置的set集合的泛型-->
- <one-to-many class="com.yujun.maven.po.Emp"/>
- </set>
- </class>
- </hibernate-mapping>
Emp.hbm.xml
- <?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.yujun.maven.po.Emp" table="emp">
- <id name="empId" type="int">
- <column name="empId" />
- <generator class="native" />
- </id>
- <property name="empNo" type="java.lang.String">
- <column name="empNo" />
- </property>
- <property name="empName" type="java.lang.String">
- <column name="empName" />
- </property>
- <property name="empSex" type="int">
- <column name="empSex" />
- </property>
- <property name="empBirth" type="java.lang.String">
- <column name="empBirth" />
- </property>
- <!-- 多-1 name:实体类中的属性名 class:属性对应的类 -->
- <many-to-one name="dept" class="com.yujun.maven.po.Dept">
- <!-- 外键字段 -->
- <column name="deptId"></column>
- </many-to-one>
- </class>
- </hibernate-mapping>
6、加载映射文件
在hibernate.cfg.xml中
- <mapping resource="com/yujun/maven/po/Dept.hbm.xml"/>
- <mapping resource="com/yujun/maven/po/Emp.hbm.xml"/>
7、查询部门获取部门的所有员工
- public class Demo1 {
- public static void main(String[] args) {
- // 1配置对象
- Configuration config = new Configuration().configure();
- // 2会话工厂
- SessionFactory factory = config.buildSessionFactory();
- // 3会话对象
- Session session = factory.openSession();
- //查询一个部门
- Dept dept = session.get(Dept.class, 1);//立即发送SQL语句去数据库中查询
- System.out.println(dept);
- //获取dept对象中所有员工信息
- Set<Emp> emps = dept.getEmps(); //默认使用延迟加载(懒加载)
- System.out.println("1-----------------------------");
- emps.forEach(System.out::println);
- // 关闭
- session.close();
- System.exit(0);
- }
- }
8、查询员工获取部门
- public class Demo2 {
- public static void main(String[] args) {
- // 1配置对象
- Configuration config = new Configuration().configure();
- // 2会话工厂
- SessionFactory factory = config.buildSessionFactory();
- // 3会话对象
- Session session = factory.openSession();
- //查询一个员工
- Emp emp = session.get(Emp.class, 2);
- System.out.println(emp);
- //这个员工的部门
- Dept dept = emp.getDept(); //默认是延迟加载
- System.out.println(dept);
- // 关闭
- session.close();
- System.exit(0);
- }
- }
四、级联操作和控制权
操作一个对象,会一并操作被关联的对象
比如:删除一个部门,顺带给把此部门下的所有员工删除;
增删改、这里我们只讲解级联删除;
先删除从表,再删主表(推荐)
级联操作:cascade告知hibernate对于关联的对象应该如何操作,取值:none、save-update、delete、all,默认是none-无级联操作,双方都可以配置级联操作
控制权:inverse告知hibernate对于外键的维护由谁来取得控制权;取值:true、false;
false表示控制权在己方,true-表示控制权在对方。
对于1-多关系,我们把控制权交给多的一方,也就是需要我们在1方的set节点中配置:inverse="true"
通常我们不需要配置级联操作,太危险;默认就好
dept.hbm.xml
- <!-- set就是用来配置集合属性 name:实体类中属性名 cascade="delete"表示级联删除员工-->
- <!-- inverse="true"表示控制权,控制权控制外键由谁维护,默认是false,false-控制权在己方 true-控制权在对方 -->
- <set name="emps" cascade="delete" inverse="true">
- <!-- key用来配置外键 column:外键字段名-->
- <key>
- <column name="deptId"></column>
- </key>
- <!-- 1-多 class:配置的set集合的泛型-->
- <one-to-many class="com.yujun.maven.po.Emp"/>
- </set>
- public class Demo3 {
- public static void main(String[] args) {
- // 1配置对象
- Configuration config = new Configuration().configure();
- // 2会话工厂
- SessionFactory factory = config.buildSessionFactory();
- // 3会话对象
- Session session = factory.openSession();
- //4事务
- Transaction tran = session.beginTransaction();
- //查询一个部门
- Dept dept = session.get(Dept.class, 2);
- //删除部门
- session.delete(dept);
- //如果设置了级联删除,那么先删除部门对应的员工,再删除部门
- //如果没有设置级联删除,那么只会删除部门,员工表的deptID字段数据被设置为null
- tran.commit();
- // 关闭
- session.close();
- System.exit(0);
- }
- }
五、多-多
1、数据库和表
- -- 学生表
- create table student(
- stuId int not null primary key auto_increment,
- stuName varchar(20) not null
- )
- -- 课程表
- create table course(
- couId int not null primary key auto_increment,
- couName varchar(20) not null
- )
- -- 选课表
- create table xuanke(
- xkId int not null primary key auto_increment,
- studentId int references student(stuId),
- courseId int references course(couId)
- )
- insert into student value(0,'小二');
- insert into student value(0,'小三');
- insert into course values(0,'Struts2');
- insert into course values(0,'Hibernate');
- insert into course values(0,'Spring');
- insert into xuanke values(0,1,1);
- insert into xuanke values(0,1,2);
- insert into xuanke values(0,2,1);
- insert into xuanke values(0,2,2);
- insert into xuanke values(0,2,3);
2、实体类
- @Setter
- @Getter
- public class Course {
- private Integer couId;
- private String couName;
- private Set<Student> stus; //多个学生
- @Override
- public String toString() {
- return "Course [couId=" + couId + ", couName=" + couName + "]";
- }
- }
- @Setter
- @Getter
- public class Student {
- private Integer stuId;
- private String stuName;
- private Set<Course> cous; //多门课程
- @Override
- public String toString() {
- return "Student [stuId=" + stuId + ", stuName=" + stuName + "]";
- }
- }
3、xxx.hbm.xml
student.hbm.xml
- <?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.yujun.maven.po.Student" table="student">
- <id name="stuId" type="int">
- <column name="stuId" />
- <generator class="native" />
- </id>
- <property name="stuName" type="java.lang.String">
- <column name="stuName" />
- </property>
- <!-- table:表示管理的第三方的表名 -->
- <set name="cous" table="xuanke">
- <!-- 此表在第三方表中的外键字段 -->
- <key>
- <column name="studentId"></column>
- </key>
- <!-- 多-多 column:第三方表中的外键-->
- <many-to-many column="courseId" class="com.yujun.maven.po.Course"></many-to-many>
- </set>
- </class>
- </hibernate-mapping>
course.hbm.xml
- <?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.yujun.maven.po.Course" table="course">
- <id name="couId" type="int">
- <column name="couId" />
- <generator class="native" />
- </id>
- <property name="couName" type="java.lang.String">
- <column name="couName" />
- </property>
- <!-- table:表示管理的第三方的表名 -->
- <set name="stus" table="xuanke">
- <!-- 此表在第三方表中外键字段 -->
- <key>
- <column name="courseId"></column>
- </key>
- <!-- 多-多 column:第三方表中的外键-->
- <many-to-many column="studentId" class="com.yujun.maven.po.Student"></many-to-many>
- </set>
- </class>
- </hibernate-mapping>
需要再hibernate.cfg.xml中引用映射文件
- <mapping resource="com/yujun/maven/po/Student.hbm.xml"/>
- <mapping resource="com/yujun/maven/po/Course.hbm.xml"/>
4、查询案例
根据一个学生,查询相应的选课
- public class Demo4 {
- public static void main(String[] args) {
- // 1配置对象
- Configuration config = new Configuration().configure();
- // 2会话工厂
- SessionFactory factory = config.buildSessionFactory();
- // 3会话对象
- Session session = factory.openSession();
- //查询一个学生
- Student student = session.get(Student.class, 2);
- System.out.println(student);
- //查询这个学生的所选的课程
- Set<Course> cous = student.getCous();
- cous.forEach(System.out::println);
- // 关闭
- session.close();
- System.exit(0);
- }
- }
六、1 - 1
1-1的关系,在实际开发中不是特别多,若要使用1-1关系映射,可以在双方的xxx.hbm.xml中使用<one-to-one/>进行配置
hibernate-第二章-关系映射的更多相关文章
- Hibernate多对多关系映射(建表)
下边讲述Hibernate多对多关系映射. 多对多关系的表的结构为: 两个实体表,还包含一个关系表,关系表为复合主键,如果要使用Hibernate多对多关系映射,则关系表必须只包含两个字段,如果生成了 ...
- 菜鸟学习Hibernate——多对多关系映射
Hibernate中的关系映射,最常见的关系映射之一就是多对多关系映射例如用户与角色的关系,一个用户对应多个角色,一个角色对应多个用户.如图: Hibernate中如何来映射这两个的关系呢? 下面就为 ...
- 菜鸟学习Hibernate——一对多关系映射
Hibernate中的关系映射,最常见的关系映射之一就是一对多关系映射例如学生与班级的关系,一个班级对应多个学生.如图: Hibernate中如何来映射这两个的关系呢? 下面就为大家讲解一下: 1.创 ...
- hibernate的对象/关系映射结果为空,exists查不到值的问题-20190823
1: hibernate的对象/关系映射 情景:在使用@onetotone/@manytonone时关联结果为空 原因:在使用这个注解的时候,默认的时crossjoin(交叉连接),在进行查询时以及排 ...
- Hibernate 中对象关系映射(ObjectRelationMapping)
1.什么是对象关系映射? 解析:对象-关系映射(Object Relational Mapping,简称ORM,对象关系映射)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说, ...
- Hibernate之实体关系映射
延迟加载与即时加载 例如Person类和Email类是一对多关系,如果设为即时加载,当加载Person时,会自动加载Email,如果设置为延迟加载,当第一次调用person.getEmails()时才 ...
- Hibernate学习之关系映射(转)
一.一对多 "一对多"是最普遍的映射关系,简单来讲就如消费者与订单的关系.一对多:从消费者角的度来说一个消费者可以有多个订单,即为一对多.多对一:从订单的角度来说多个订单可以对应一 ...
- Hibernate多对多关系映射
两张表的多对多关系,在数据库中通常是通过第三张中间表来实现的,第三张中间表放的是两张表各自的主键值,通过主键与主键的对应来体现表直接的关系.比如在权限系统中,一个用户可以拥有多种权限,而一种权限也可以 ...
- Hibernate:对象关系映射(一对一,一对多,多对一,多对多)
如需转载,请说明出处:http://www.cnblogs.com/gudu1/p/6895610.html Hibernate通过关系映射来表示数据库中表与表之间的关系,关系映射可以通过两种方式:配 ...
随机推荐
- Android P添加一个可以让system_server进程访问的hal service需要改动的sepolicy文件
在device/sepolicy/common目录中: 修改文件attributes: attribute hal_newXX;attribute hal_newXX_client;attribute ...
- P2522 [HAOI2011]Problem b (莫比乌斯反演)
题目 P2522 [HAOI2011]Problem b 解析: 具体推导过程同P3455 [POI2007]ZAP-Queries 不同的是,这个题求的是\(\sum_{i=a}^b\sum_{j= ...
- 2019余姚培训游记+ZJOJD2划水记
2019余姚培训游记 突然就想写一个... 注意:以下全是胡言乱语的自high,还有很多错别字 Day 0 来的比较早,早上就到了 上午把一本小说看完了,是一个年轻作者的处女作. 我觉得我第一本书一定 ...
- [NOI2017]游戏
题目描述 http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf 题解 如果说没有x的话,那么每一局只能有两种选择,可以描述为是/非,每条限制也可以 ...
- java并发编程 | 线程详解
个人网站:https://chenmingyu.top/concurrent-thread/ 进程与线程 进程:操作系统在运行一个程序的时候就会为其创建一个进程(比如一个java程序),进程是资源分配 ...
- jemter+ant+jenkins进行集成测试
一下为我学习的一些笔记: 一.安装配置ant 安装地址:http://ant.apache.org/ 1.下载ant一路傻瓜式安装 2.配置ant环境变量:path下配置ant的bin路径 3.将jm ...
- 洛谷 P5304 [GXOI/GZOI2019]旅行者(最短路)
洛谷:传送门 bzoj:传送门 参考资料: [1]:https://xht37.blog.luogu.org/p5304-gxoigzoi2019-lv-xing-zhe [2]:http://www ...
- Mac 装机必备软件推荐
所谓Mac 装机必备软件,就是用 Mac OS X 几乎都要安装的软件,无论你是开发者.设计师还是摄影师,如果你是刚开始用 Mac,那么推荐看看以下内容,对你非常有帮助. 一.输入法 Mac 自带的中 ...
- [源码分析]读写锁ReentrantReadWriteLock
一.简介 读写锁. 读锁之间是共享的. 写锁是独占的. 首先声明一点: 我在分析源码的时候, 把jdk源码复制出来进行中文的注释, 有时还进行编译调试什么的, 为了避免和jdk原生的类混淆, 我在类前 ...
- java接口多实现和多继承
package test; interface mouth { public abstract void speak(); } interface nose{ public abstract void ...