[TOC]
Hibernate
1 直译:冬眠 数据持久化框架 ORM框架
2 用处: 最终将JDBC 替换
uniqueResult 唯一结果
lazy 延迟加载
cascade 级联
inverse 反转
3 Hibernate 实现的步骤
导包
主配置文件和映射文件<将实体和表映射>
-
测试类 TestHibernste
测试类步骤:- 获取配置 创建工厂 获取session 执行方法 处理结果 关闭session
具体操作
设置主配置文件
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--主配置 -->
<session-factory>
<property name="connection.url">
jdbc:mysql://localhost:3306/user
</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<mapping resource="com/wxb/bean/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
映射文件设置
<?xml version="1.0" encoding="utf-8"?>
<!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.wxb.bean.User" table="user">
<id name="uid" column="uid" type="java.lang.Integer">
<generator class="increment" ></generator>
</id>
<property name="name" column="name" type="java.lang.String"></property>
</class>
</hibernate-mapping>
测试类
//获取配置
Configuration cf=new Configuration().configure();
//创建工厂
SessionFactory sf = cf.buildSessionFactory();
//获取session
Session session = sf.openSession();
//hql 语句获取用户信息
List<User> list = session.createQuery("from User").list();
显示sql语句 格式化配置
- 显示sql语句
<property name="hibernate.show_sql">true</property>
- 格式化
<property name="hibernate.format_sql">true</property>
session常用的方法
- save
- update
- delete
- saveOrUpdate 如果配置文件中设置的是自增长,新增是无需编号 ,修改则需要编号
对象实体的三个状态
- 自由状态
- 持久状态
- 游离状态
get/load 区别
User us = (User) session.get(User.class, 46);
User use= (User) session.load(User.class, 46)
- 同样都是可以通过编号获取对象
区别在于编号不存在是,get返回null,而load则会报异常ObjectNotFoundException(需打印异常信息)
唯一结果 uniqueResult
Object object = session.createQuery("select count(*) from User").uniqueResult();
HQL-Hibernate 查询语句 OOP+SQL
hq语句
/***
* hq语句查询
*
*/
String hql1="from User order by uid desc"; //降序排列
String hql1="from User where name like'%云%'"; //模糊查询
String hql1="from User where uid=1"; // 通过ID查询
占位符
/**
* 占位符的三种方式
*
*/
- 使用 ? 填充序号从0开始
- 使用 :ui 填充参数序号从0开始
- 使用 :属性 填充参数一样是属性 优点:和顺序无关
``` java
String hql2="from User where uid=? or name=?";
List<User> list =session.createQuery(hql2)
.setParameter(0,29)
.setParameter(1,"齐天大圣")
.list();
for (User user : list) {
System.out.println(user);
}
String hql3="from User where uid=:ui and name=:na";
List<User> list =session.createQuery(hql3)
.setParameter("ui", 29)
.setParameter("na","齐天大圣")
.list();
for (User user : list) {
System.out.println(user);
}
String hql4="from User where uid=:uid and name=:name";
List<User> list =session.createQuery(hql3)
.setProperties(new User(29,"齐天大圣"))
.setFirstResult(0)
.list();
for (User user : list) {
System.out.println(user);
}
分页
String hql1="from User order by uid desc"; //降序排列
List<User> list = session.createQuery(hql1)
.setFirstResult(0)
.setMaxResults(5)
.list();
for (User user : list) {
System.out.println(user);
}
原生SQL
方式1
/**
* 原生sql
*/
String sql="select * from user";
List<Object[]> list = session.createSQLQuery(sql).list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
方式2
List<User> list2 = session.createSQLQuery(sql).addEntity(User.class).list();
for (User user2 : list2) {
System.out.println(user2);
}
HQL 与SQL比较
HQL
优点:增删改有专用的方法 ;输出比较方便
缺点:hql专用语法;属性需要在模型;里面
-
原生 SQL
优点:使用灵活;获取的数据不受限制;可用于复杂统计查询;同样支持增删改
缺点:输出无法直接进行模型化
注: 复杂查询建议使用(子查询/连接查询)
ER 关系
映射文件的属性
lazy 懒加载
lazy="true"/ 延迟加载
lazy="false" 立加载
立加载 就是在session 关闭之前,就会执行完sql/hql 语句,在多对一(many- to-one)的情况下,需要设置为false,否则会报错
延迟加载 就是在session关闭前执行一部分sql/hql语句,一对多(one-to-many)默认为true
<!-- 一对多 -->
<set name="set" lazy="false" cascade="all">
<key column="deptno"></key>
<one-to-many class="com.wxb.bean.User"/>
</set>
<!-- 多对一 -->
<many-to-one name="dept" class="com.wxb.bean.Department" lazy="false">
<column name="deptno" ></column>
</many-to-one>
cascade 级联
级联新增
Department department=new Department("开天辟地");
User user=new User("盘古");
department.getSet().add(user);
user.setDept(department)
session.save(department);
tac.commit();
反转 inverse
一般默认为false
当设置为false 的时候,此时为不反转,为系统的智能模式,此时只需说明部分关系 即一对多的关系
当设置为true的时候,为不反转 需要程序员自己手动维护,说明全部关系 即一对多和多对一的关系
命名查询
优点:sql或hql集中管理,方便发布之后维护
List <Object []>list = session.getNamedQuery("getMoneyMMA").setProperties(new User("%天%"))
.list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
使用方法getNameQuery
sql 语句
<sql-query name="getMoneyMMA">
select max(money),min(money),avg(money) from user
</sql-query>
List <Object []>list = session.getNamedQuery("getMoneyMMA").list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
hql 语句
<query name="getMoneyHQL">
<![CDATA[from User]]>
</query>
List list = session.getNamedQuery("getMoneyHQL").list();
for (Object object : list) {
System.out.println(object);
}
缓存
Hibernate实现了良好的Cache机制,可以借助Hibernate内部的Cache迅速提高系统的数据读取性能。Hibernate中的Cache可分为两层:一级Cache和二级Cache。
一级Cache:
同一个session 查询两次 sql语句执行一次
二级Cache:
工厂级别的缓存(sessionFactory)同一个sessionFactroy
实现步骤:
- 同一个seesionFactory
- 打开二级缓存设置
<property name="hibernate.cache.use_second_level_cache">true</property>
- 打开第三方插件支持
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
- 相应的对象映射文件配置
<cache usage="read-write"/>
- 导包 commons-lonning-1.1.1jar
- lazy设置为默认 proxy
缓存查询
<property name="hibernate.cache.use_query_cache">true</property>