Hibernate
实体类编写规则
(1)要求实体类有属性作为唯一值(id)
(2)实体类属性使用包装类
- 学生有属性为分数,Integer可为null,表明学生未参加考试
主键生成策略
<id name="id" column="id">
<!-- 设置数据库表id增长策略
native:生成表的id自增长
-->
<generator class="native"></generator>
</id>
generator标签class属性:
- increment:用于long、short、int,由hibernate自动以递增的方式生成唯一标识符,每次增量为1
- dentity:采用底层数据库本身提供的主键生成标识符,主要用于MySQL,DB2,SQLServer,要求数据库把主键定义成自增长
- sequence:用于Oracle,hibernate根据底层数据库序列生成标识符,要求数据库支持序列
- native:根据底层数据库选择相对应的生成策略
- uuid:使用uuid生成策略,实体类id属性必须为字符串
crud操作
1. Insert
// 5 insert操作
User user = new User();
user.setUsername("root");
user.setPassword("root");
2. session.save(user);Select
/*
* 5 执行查询操作
* 调用session的get方法
* 第一个参数:实体类的class
* 第二个参数:id值
*/
User user = session.get(User.class, 1);
System.out.println(user);
3. Update
//5 执行修改操作
//5.1 根据id查询
User user = session.get(User.class, 1);
//5.2 set方法设置
user.setPassword("123");
//5.3 调用session的update方法修改(底层通过id来进行修改)
session.update(user);
4. Delete
//5 执行删除操作
//第一种 :根据id查询对象,调用session对象delete方法
User user = session.get(User.class, 2);
session.delete(user);
//第二种:
User user2 = new User();
user2.setId(3);
session.delete(user2);
Hibernate缓存
1. 缓存:
数据存在数据库中,数据库本身是一个文件系统,使用流方式存取数据,效率低。
通过把数据存入内存中,不需要使用流方式,可以直接在内存中读取数据,效率高。
2. Hibernate一级缓存
(1)hibernate一级缓存默认打开
(2)使用范围:session范围,从session创建到session关闭
(3)存储数据 持久态数据
3. Hibernate二级缓存
(1)很少使用,redis替代
(2)范围:SessionFactory范围
Hibernate本地线程绑定session
(1)在核心配置文件中进行配置
<!-- 本地线程绑定Session -->
<property name="hibernate.current_session_context_class">thread</property>
(2)调用SessionFactory中方法
public static Session getSession() {
return SESSION_FACTORY.getCurrentSession();
}
Hibernate的API
1. Query对象
参数是hql语句
//创建Query对象
Query query = session.createQuery("from User");
//调用query对象里的list方法得到结果
List<User> list = query.list();
2. Criteria对象
参数是实体类.class
//创建criteria对象
Criteria criteria = session.createCriteria(User.class);
//调用criteria对象里的list方法得到结果
List<User> list = criteria.list();
3. SQLQuery对象
Hibernate一对多操作(两张表间通过外键建立一对多关系)
1. 一对多映射配置
以学生班级为例:一个学生对应一个班级,一个班级对应多个学生
(1)创建学生、班级实体类,并建立联系
学生类:
//一个学生对应一个班级
private Classs classs;
public Classs getClasss() {
return classs;
}
public void setClasss(Classs classs) {
this.classs = classs;
}
班级类:
//一个班级对应多个学生
private Set<Student> students = new HashSet<>();
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
(2)配置映射文件
学生映射文件
<class name="com.wzw.hibernate.model.Student" table="student">
<id name="sId" column="sid">
<generator class="native"></generator>
</id>
<property name="sName" column="sname"></property>
<property name="sAge" column="sage"></property>
<!-- 表示学生所属的班级
name属性:班级实体类的classs对象名称
class属性:Classs全路径
column属性:外键名称
-->
<many-to-one name="classs" class="com.wzw.hibernate.model.Classs" column="cid"></many-to-one>
</class>
班级映射文件
<class name="com.wzw.hibernate.model.Classs" table="class">
<id name="cId" column="cid">
<generator class="native"></generator>
</id>
<property name="cName" column="cname"></property>
<!-- 在班级类映射文件中,表示班级所拥有的全部学生
set标签:
name属性:在班级实体类中表示学生的set集合名称
-->
<set name="students">
<!-- 一对多建表,有外键
hibernate:双向维护外键,既一和多双方都要配置
-->
<key column="sid"></key>
<!-- 班级的所有学生,class里写学生的全路径-->
<one-to-many class="com.wzw.hibernate.model.Student"/>
</set>
</class>
(3)创建核心配置文件,将映射文件引入核心配置文件中
<!-- hibernate自动创建表
update:如果已经有表,更新;如果没有,创建
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- <property name="hibernate.hbm2ddl.auto">update</property> -->
<!-- 配置数据库方言
在MySQL里实现分页关键字 limit,只能在MySQL里使用
在Oracle中,rownum
让hibernate框架识别不同数据库的语句
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 3 把映射文件放到核心配置文件中 -->
<mapping resource="com/wzw/hibernate/model/Classs.hbm.xml"/>
<mapping resource="com/wzw/hibernate/model/Student.hbm.xml"/>
2. 一对多级联保存
// 添加
// 1 创建学生对象与班级对象
Student student = new Student();
student.setsName("wzw");
student.setsAge(16);
Classs classs = new Classs();
classs.setcName("104班");
//2 建立学生与班级间联系
student.setClasss(classs);
classs.getStudents().add(student);
//3 insert
session.save(classs);
session.save(student);
3. 一对多级联删除
(1)获取待删除班级id
(2)根据班级id获取班级学生
(3)删除学生
(4)删除班级
Hibernate多对多操作(两张表间通过第三张表建立多对多关系)
一个用户对应多个角色,一个角色对应多个用户
1. 多对多映射配置
(1)创建用户、角色实体类,并建立联系
用户类:
//一个用户对应多个角色
private Set<Role> roles = new HashSet<>();
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
角色类:
//一个角色对应多个用户
private Set<User> users = new HashSet<>();
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
(2)配置映射文件
User:
<!-- name:Set<Role> roles
table:第三张表名称
-->
<set name="roles" table="user_role">
<!-- key标签column属性:配置当前的映射文件user在第三张表中外键的名称user_id -->
<key column="user_id"></key>
<!-- class:Role全路径
column:Role在第三张表中外键的名称role_id
-->
<many-to-many class="com.wzw.hibernate.model.Role" column="role_id"></many-to-many>
</set>
Role:
<set name="users" table="user_role">
<key column="role_id"></key>
<many-to-many class="com.wzw.hibernate.model.User" column="user_id"></many-to-many>
</set>
(3)创建核心配置文件,并将映射文件引入配置文件中
<!-- 3 把映射文件放到核心配置文件中 -->
<mapping resource="com/wzw/hibernate/model/User.hbm.xml"/>
<mapping resource="com/wzw/hibernate/model/Role.hbm.xml"/>
2. 多对多级联保存
Role.hbm.xml:
<set name="users" table="user_role" cascade="save-update">
User.hbm.xml:
<set name="roles" table="user_role" cascade="save-update">
//级联保存
//1 创建用户与角色对象
User user1 = new User();
User user2 = new User();
user1.setUsername("zhangsan");
user1.setPassword("123");
user2.setUsername("lisi");
user2.setPassword("123");
Role role1 = new Role();
Role role2 = new Role();
Role role3 = new Role();
role1.setRole_name("root");
role2.setRole_name("S");
role3.setRole_name("A");
//2 User与Role建立联系
//user1--role1/role2
//user2--role2/role3
user1.getRoles().add(role1);
user2.getRoles().add(role2);
user2.getRoles().add(role2);
user2.getRoles().add(role3);
//3 添加
session.save(user1);
session.save(user2);
3. 多对多级联删除
HIbernate查询方式
1. 对象导航查询
根据id查询A对象,再查询A中的B对象(Set)
2. OID查询
根据id查询某条记录,返回对象
3. hql查询
Query对象,hql语句
4. QBC查询
Criteria对象
5. 本地sql查询
SQLQuery对象,sql语句
(懒加载)Hibernate检索策略
1. hibernate检索策略分为两类:
get()立即查询:
根据id查询,调用get方法,一调用get方法马上发送查询语句查询数据库
load()延迟查询:
根据id查询,调用load方法,不会马上发送查询语句查询数据库,只有得到对象里面的值时才会发送语句查询
2. 延迟查询分为两类
类级别延迟
根据id查询返回实体类对象,调用load方法不会马上发送语句
关联级别延迟
先查询A,再查询A中所有的B,而这个过程是否需要延迟,这个过程称为关联级别延迟