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通过关系映射来表示数据库中表与表之间的关系,关系映射可以通过两种方式:配 ...
随机推荐
- b树和hash树的应用场景
关系型数据库中,索引大多采用B/B+树来作为存储结构,而全文搜索引擎的索引则主要采用hash的存储结构,这两种数据结构有什么区别? 如果是等值查询,那么哈希索引明显有绝对优势,因为只需要经 ...
- Linux内核模块编程——Hello World模块
Linux内核模块编程 编程环境 Ubuntu 16.04 LTS 什么是模块 内核模块的全称是动态可加载内核模块(Loadable Kernel Modul,KLM),可以动态载入内核,让它成为内核 ...
- bzoj3168 钙铁锌硒维生素 (矩阵求逆+二分图最小字典序匹配)
设第一套为A,第二套为B 先对于每个B[i]判断他能否替代A[j],即B[i]与其他的A线性无关 设$B[i]=\sum\limits_{k}{c[k]*A[k]}$,那么只要看c[j]是否等于零即可 ...
- JavaWeb之DButils整理
一.DBUtils介绍 apache 什么是dbutils,它的作用 DBUtils是java编程中的数据库操作实用工具,小巧简单实用. 用前导包!!!DBUtils包!!! 二.DBUtils的三 ...
- jupyter nootbook本地使用指南
本地文件读入jupyter notebook 在文件夹内,shift+鼠标右键,出现菜单中选择“”在此处打开命令窗口“”,输入jupyter notebook, 可以把本地文件读入jupyter.
- Jupyter Notebook 的安装使用以及 tree 路径变更
由于最近开始学习 Python,进而接触到一个十分强大的交互式编辑器 — Jupyter Notebook,用起来也非常顺手,于是记录一下相关的使用过程. 一.安装 Python: ①首先前往 pyt ...
- 强连通分量(Kosaraju)
//P2002解题思路: //先求SCC,缩点后,转换为DAG(有向无环图) //在DAG上统计入度为0的scc数量即可 //Kosaraju时间复杂度:O(N+E) //两次DFS,2N,图的转置E ...
- 《11招玩转网络安全》之第三招:Web暴力破解-Low级别
Docker中启动LocalDVWA容器,准备DVWA环境.在浏览器地址栏输入http://127.0.0.1,中打开DVWA靶机.自动跳转到了http://127.0.0.1/login.php登录 ...
- Axis2 WebService客户端Axis2调用
第一RPC方式,不生成客户端代码 第二,document方式,不生成客户端代码 第三,用wsdl2java工具,生成客户端方式调用 package samples.quickstart.client; ...
- 安装hue及hadoop和hive整合
环境: centos7 jdk1.8.0_111 Hadoop 2.7.3 Hive1.2.2 hue-3.10.0 Hue安装: 1.下载hue-3.10.0.tgz: https://dl.dro ...