列表功能实现
1.表与表之间关系回顾
2.hibernate 一对多操作(重点)
(1) 一对多
(客户和联系人):
客户:与公司有业务往来,百度,新浪,360
联系人:公司里面的员工,百度里面有很多员工,联系员工
(分类和商品) : 一个分类里面有多个商品,一个商品只能属于一个分类
客户是一:联系人是多
一个客户里面有多个联系人,一个联系人只能属于一个客户
一对多,通过外键建立关系
学生实体类:
package main.java.com.it.domain;
import java.io.Serializable;
public class Student implements Serializable {
private Integer id;
private String name;
private Teacher teacher;
public Student() {
super();
}
public Student(String name, Teacher teacher) {
super();
this.name = name;
this.teacher = teacher;
}
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 Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
老师实体类
package main.java.com.it.domain;
import java.io.Serializable;
import java.util.Set;
public class Teacher implements Serializable {
private Integer id;
private String name;
private Integer age;
private Set<Student> students;
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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "Teacher{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", students=" + students +
'}';
}
}
学生核心配置文件
<?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="main.java.com.it.domain">
<!--
name: 即实体类的全名
table: 映射到数据库里面的那个表的名称
catalog: 数据库的名称
-->
<class name="Student" table="student" catalog="hibernate">
<!-- class 下必须有一个id的子元素 -->
<!-- id是用于描述主键的 -->
<id name="id" column="id">
<!-- 主键生成策略 -->
<generator class="native"></generator>
</id>
<!--
如果property 来描述属性与字段对应关系
如果length 忽略不写,且你的表自动创建这种方案,那么长度默认为255
-->
<property name="name" column="name" length="20"></property>
<!--
一对多关联映射配置(通过部门管理到员工)
Student映射关键点:
1.指定映射的属性:teacher
2.集合表的外键字段:t_id
3.元素的类型:teacher
-->
<many-to-one name="teacher" column="t_id" class="Teacher"></many-to-one>
</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="main.java.com.it.domain">
<!--
name: 即实体类的全名
table: 映射到数据库里面的那个表的名称
catalog: 数据库的名称
-->
<class name="Student" table="student" catalog="hibernate">
<!-- class 下必须有一个id的子元素 -->
<!-- id是用于描述主键的 -->
<id name="id" column="id">
<!-- 主键生成策略 -->
<generator class="native"></generator>
</id>
<!--
如果property 来描述属性与字段对应关系
如果length 忽略不写,且你的表自动创建这种方案,那么长度默认为255
-->
<property name="name" column="name" length="20"></property>
<!--
一对多关联映射配置(通过部门管理到员工)
Student映射关键点:
1.指定映射的属性:teacher
2.集合表的外键字段:t_id
3.元素的类型:teacher
-->
<many-to-one name="teacher" column="t_id" class="Teacher"></many-to-one>
</class>
</hibernate-mapping>
Hibernate配置文件
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 配置关于数据库连接的四个项 :driver_class url username password -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- 可以将数据库发送SQL语句显示出来 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL语句 -->
<property name="hibernate.format_sql">true</property>
<!-- hibernate的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置hibernate的映射文件所在的位置 -->
<mapping resource="main/java/com/it/domain/Teacher.hbm.xml"></mapping>
<mapping resource="main/java/com/it/domain/Student.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
数据库截图:
学生表的数据库截图
老师数据库截图
运行截图
一对多映射配置解释:
以上述代码为例:老师是一,学生是多。
第一步 :创建两个实体类,老师和学生。
第二步:让两个实体类之间互相表示
(1)在老师实体类里面表示多个学生
老师实体类中表示多个老师,一个老师里面可以有多个学生。
hibernate 要求使用集合表示多的数据,使用Set 集合。
第三步:配置映射关系
(1) 一般一个实体类对应一个映射文件
(2) 把映射文件最基本配置完成
(3) 在映射文件中,配置一对多关系
在老师映射文件中,表示所有学生
使用set 标签表示所有的学生
set标签里面有name 属性;
属性值写在老师实体类里面表示学生的Set集合名称
hibernate机制:双向维护外键,在一和多那一方都配置外键
column 属性值:外键名称
ont - to -many 属性值: class中写的是学生的实体类的全路径
在学生映射文件中,表示所属老师
many-to-many 表示学生所属客户
name 属性: 因为学生实体类使用customer 对象表示,写customer 名称
column属性:外键名称
第四步: 创建核心配置文件,mapping resource 属性把映射文件引入到核心配置文件中。
多对多
(用户和角色):一个用户可以有多个角色,一个角色可以有多个用户。
用户:小王。小马,小宋
角色.总经理,秘书,司机,保安
比如小王 可以是总经理,可以是司机
比如小宋 可以是司机,可以是秘书,可以是保安
比如小马 可以是秘书,也可以是总经理、
(订单和商品):一个订单可以有多个商品,一个商品可以有多个订单
(3) 一对一
中国合法状况下一夫一妻制
(2) 一对多级联保存
级联操作
(1) 级联保存:添加了一个学生,为这个学生添加了多个老师
(2)级联删除:删除某一个老师,这个老师下面所有的学生也删除
复杂写法:
简单写法:
一般根据老师添加学生
第一步:在客户映射文件中进行配置
在老师映射文件中里面的Set 标签进行配置
第二步: 创建老师和学生对象,只需要把学生放到老师里面就可以了
变化的地方在于这里上面代码一样
(3) 一对多级联删除
1 删除某个老师,把客户里面所有的学生删除
2.具体实现
第一步: 在老师映射文件set 标签,进行配置
(1) 使用属性cascade 属性值 delete
第二步: 在代码中直接删除老师
(1)根据id 查询对象,调用session 里面的delete删除
删除执行过程:
(1)根据id 查询客户
(2)根据外键id值查询联系人
(3)把联系人的外键设置为null
(4) 删除联系人客户
一对多修改操作(inverse属性)
(4) inverse属性
(1) 因为hibernate 双向维护外键,在客户与联系人里面都需要维护外键,修改客户时候需要在修改一次外键,修改联系人时候也修改一次外键,造成效率问题
(2) 解决方式,让其中的一方不维护外键
一对多里面,让其中一方放弃外键维护
(3)具体实现
在放弃关系维护映射文件中,进行配置,在set标签上使用inverse 属性
3.hibernate 多对多操作
(1)多对多映射配置
以用户和角色为例演示
第一步创建实体类,用户和角色
第二步: 让两个实体类互相表示
(1) 用户里面表示所有角色,使用set 集合
(2) 一个角色有多个用户,使用set 集合
第三步: 配置映射关系
(1) 基本配置
(2) 配置多对多关系
-在用户里面表示所有角色,使用set 标签
-在角色里面表示所有用户,使用set标签
第四步: 在核心配置文件引入映射文件
测试:
数据库表
(2)多对多级联保存(重点)
根据用户保存角色
第一步: 在用户配置中set 标签进行配置,cascade 值save-update
第二步: 写代码实现
(1) 创建用户和角色对象,把角色放在用户里面,最终保存用户就可以了
@Test
public void testsave() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try {
// 得到sessionFactory
sessionFactory = HibernateUtils.getSessionFactory();
// 得到session
session = sessionFactory.openSession();
// 开启事务
tx = session.beginTransaction();
// 添加两个用户,为每个角色添加两个角色
// 创建角色
User user1 = new User();
user1.setUser_name("lucy");
user1.setUser_password("123");
User user2 = new User();
user2.setUser_name("tom");
user2.setUser_password("231");
Role role1 = new Role();
role1.setRole_name("总经理");
role1.setRole_memo("总经理");
Role role2 = new Role();
role2.setRole_name("秘书·");
role2.setRole_memo("秘书");
Role role3 = new Role();
role3.setRole_name("保安");
role3.setRole_memo("保安");
// 建立关系
user1.getSetRole().add(role1);
user1.getSetRole().add(role2);
user2.getSetRole().add(role2);
user2.getSetRole().add(role3);
session.save(user1);
session.save(user2);
// 提交事务
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
}
(3)多对多级联删除(了解)
第一步: 在src 标签进行配置,cascade 值delete
第二步: 删除用户
(4)维护第三张表(重点)
1.用户和角色是多对多关系,维护关系通过第三张表维护
2.让某个用户有某个角色
第一步: 根据用户id 查询用户和角色
第二步: 把角色放在用户里面
(1) 把角色对象放在用户Set集合
3. 让某个用户没有某个角色
第一步: 根据用户id 查询用户和角色
第二步: 从用户把角色去掉
(1) 从Set 集合把角色移除