0
点赞
收藏
分享

微信扫一扫

Hibernate_day03总结

Hibernate_day03总结_sql

更多资源分享就在【Java帮帮】微信公众号QQ空间

Hibernate_day03总结

今日内容

l Hibernate的检索方式

l Hibernate的抓取策略

l Hibernate的批量检索

l 事务的并发问题

1.1 ​上次课内容回顾:

Hibernate的持久类三种状态:

* 瞬时态:没有唯一标识OID,没有被session管理

* 持久态:有唯一标识OID,被session管理

* 脱管态:有唯一标识OID,没有被session管理.

* 状态换:

瞬时态:new 获得.

* 瞬时à持久:save/saveOrUpdate

* 瞬时à脱管:user.setId(1);

持久态:get/load/find

* 持久à脱管:close,clear,evict

* 持久à瞬时:delete

脱管态:new User() user.setId(1);

* 脱管à持久:update,saveOrUpdate

* 脱管à瞬时:user.setId(null);

Hibernate的一级缓存:

* Hibernate一级缓存:session级别缓存.

* session中一系列的Java集合.

* session中一级缓存存在:

* 快照区:

* 一级缓存常用操作的方法:

* clear/flush/evict/refresh

Hibernate的操作持久化类的常用的方法:

* save/update/get/load/delete/saveOrUpdate

Hibernate的关联关系映射:

* 一对多:

* 部门和员工:

* 部门实体:

* Set<Employee> employees = new HashSet<Employee>();

* 员工实体:

* Department department

* 部门映射:

<set name=”employees”>

<key column=”dno”/>

<one-to-many class=”..Employee”/>

</set>

* 员工映射:

<many-to-one name=”department” class=”Department” column=”dno”/>

* cascade:级联 控制的是关联的对象.

* inverse:外键维护 控制的是外键的关系.

* 多对多:

* 一对一:

1.2 ​Hibernate的检索方式:

1.2.1 ​Hibernate的检索方式:

Hibernate中提供了五种检索方式:

1.对象导航检索:

* Customer customer = session.get(Customer.class,1);

* customer.getOrders();

* Order order = session.get(Order.class,1);

* order.getCustomer().getCname();

2.OID检索:

* session.get(Customer.class,1);

* session.load(Customer.class,1);

3.HQL检索:

HQL:Hibernate Query Language.

Query query = session.createQuery(String hql);

4.QBC检索:

QBC:Query By Criteria

Criteria criteria = session.createCriteria(Class clazz);

5.SQL检索:

SQL:

SQLQuery query = session.createSQLQuery(String sql);

1.2.2 ​HQL检索:

HQL概述:

HQL(Hibernate Query Language) 是面向对象的查询语言, 它和 SQL 查询语言有些相似. 在 Hibernate 提供的各种检索方式中, HQL 是使用最广的一种检索方式. 它有如下功能:

在查询语句中设定各种查询条件

支持投影查询, 即仅检索出对象的部分属性

支持分页查询

支持连接查询

支持分组查询, 允许使用 HAVING 和 GROUP BY 关键字

提供内置聚集函数, 如 sum(), min() 和 max()

能够调用 用户定义的 SQL 函数或标准的 SQL 函数中

支持子查询

支持动态绑定参数

HQL的简单查询:

@Test

/**

* 简单查询:查询所有记录

*/

publicvoid​ demo2(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

/*Query query = session.createQuery("from Customer");

List<Customer> list = query.list();*/

List<Customer> list = session.createQuery("from Customer").list();

for​ (Customer customer : list) {

System.out.println(customer);

}

tx.commit();

session.close();

}

HQL的别名查询:

@Test

/**

* 别名查询:

* * 使用as 定义别名 (as可以省略)

*/

publicvoid​ demo3(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

// HQL中不支持select * 写法.

// List<Customer> list = session.createQuery("from Customer as c").list();

// List<Customer> list = session.createQuery("from Customer c").list();

List<Customer> list = session.createQuery("select c from Customer c").list();

for​ (Customer customer : list) {

System.out.println(customer);

}

tx.commit();

session.close();

}

HQL的多态查询(了解)

@Test

/**

* 多态查询

*/

publicvoid​ demo4(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

// 查询所有继承了Object的持久化类.

Listlist = session.createQuery("from java.lang.Object").list();

System.out.println(list);

tx.commit();

session.close();

}

HQL的排序查询:

@Test

/**

* 排序查询

*/

publicvoid​demo5(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

// List<Customer> list = session.createQuery("from Customer order by age asc").list();

List<Customer> list = session.createQuery("from Customer order by age desc").list();

for​ (Customer customer : list) {

System.out.println(customer);

}

tx.commit();

session.close();

}

HQL的分页查询:

@Test

/**

* 分页查询

*/

publicvoid​ demo6(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

Query query = session.createQuery("from Order");

// 设置从哪开始:

query.setFirstResult(10);

query.setMaxResults(10);

List<Order> list = query.list();

for​ (Order order : list) {

System.out.println(order);

}

tx.commit();

session.close();

}

HQL的检索单个对象:

@Test

/**

* 检索单个对象

*/

publicvoid​ demo7(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

Customer customer = (Customer) session.createQuery("from Customer where cname = ?").setString(0, "老马").uniqueResult();

System.out.println(customer);

tx.commit();

session.close();

}

HQL的条件查询:

@Test

/**

* 条件对象

*/

publicvoid​ demo8(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

/**

* 按位置绑定参数

*/

/*Query query = session.createQuery("from Customer where cname like ? and age > ?");

query.setParameter(0, "%马%");

query.setParameter(1, 38);*/

/**

* 按名称进行绑定参数

*/

Query query = session.createQuery("from Customer where cname like :cname and age > :age");

query.setParameter("cname", "%马%");

query.setParameter("age", 38);

List<Customer> list= query.list();

for​ (Customer customer : list) {

System.out.println(customer);

}

tx.commit();

session.close();

}

HQL的投影查询:

@Test

/**

* 投影查询

*/

publicvoid​ demo9(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

// 查询cname这列的值

/*List<String> list = session.createQuery("select cname from Customer").list();

for (String string : list) {

System.out.println(string);

}*/

// 查询cname,age这两个列的值:

/*List<Object[]> list = session.createQuery("select cname,age from Customer").list();

for (Object[] objects : list) {

System.out.println(Arrays.toString(objects));

}*/

// 使用构造查询:

List<Customer> list = session.createQuery("select new Customer(cname,age) from Customer").list();

for​ (Customer customer : list) {

System.out.println(customer);

}

tx.commit();

session.close();

}

HQL的聚合查询

@Test

/**

* 聚合函数查询

*/

publicvoid​ demo10(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

/*Long count = (Long) session.createQuery("select count(*) from Customer").uniqueResult();

System.out.println(count);*/

Integer age = (Integer) session.createQuery("select max(age) from Customer").uniqueResult();

System.out.println(age);

tx.commit();

session.close();

}

HQL的分组查询:

@Test

/**

* 分组查询

*/

publicvoid​ demo11(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

List<Object[]> list = session.createQuery("select o.customer.cname,count(*) from Order o group by o.customer.cname").list();

for​ (Object[] objects : list) {

System.out.println(Arrays.toString(objects));

}

tx.commit();

session.close();

}

1.2.3 ​QBC检索:

QBC检索的概述:

QBC:Query By Criteria:条件查询.专门用来进行条件查询.更加面向对象.

QBC简单查询:

@Test

/**

* 简单查询:

*/

publicvoid​ demo1(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

List<Customer> list = session.createCriteria(Customer.​class​).list();

for​ (Customer customer : list) {

System.out.println(customer);

}

tx.commit();

session.close();

}

QBC排序查询:

@Test

/**

* 排序查询:

*/

publicvoid​ demo2(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

Criteria criteria = session.createCriteria(Customer.​class​);

// criteria.addOrder(Order.asc("age"));

criteria.addOrder(Order.desc("age"));

List<Customer> list = criteria.list();

for​ (Customer customer : list) {

System.out.println(customer);

}

tx.commit();

session.close();

}

QBC的分页查询:

@Test

/**

* 分页查询:

*/

publicvoid​demo3(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

Criteria criteria = session.createCriteria(Order.​class​);

criteria.setFirstResult(10);

criteria.setMaxResults(10);

List<Order> list = criteria.list();

for​ (Order order : list) {

System.out.println(order);

}

tx.commit();

session.close();

}

QBC条件查询:

Hibernate_day03总结_hibernate_02

@Test

/**

* 条件查询:

*/

publicvoid​demo4(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

Criteria criteria = session.createCriteria(Customer.​class​);

// 设置条件:

/*criteria.add(Restrictions.like("cname", "%马%"));

List<Customer> list = criteria.list();

for (Customer customer : list) {

System.out.println(customer);

}*/

criteria.add(Restrictions.like("cname", "%马%"));

criteria.add(Restrictions.gt("age", 38));

List<Customer> list = criteria.list();

for​ (Customer customer : list) {

System.out.println(customer);

}

tx.commit();

session.close();

}

1.2.4 ​连接查询:

SQL中连接查询

连接查询:多表查询.

SQL中有哪些连接的方式?

* 交叉连接:

* select * from A,B; --- 得到的结果两个表的笛卡尔积.

* 内连接:inner join (inner可以省略)

* 隐式内连接:

* select * from A ,B where 条件;

* 显示内连接:

* select * from A inner join B on 条件;

* 外连接:outer join (outer 可以省略)

* 左外连接:

* select * from A left outer join B on 条件;

* 右外连接:

* select * from A right outer join B on 条件;

面试题:内连接和外连接有什么区别?

Hibernate中的连接查询(HQL连接查询)

HQL连接查询的时候:

* 交叉连接:

* 内连接:

* 显示内连接:inner join

* 隐式内连接:where

* 迫切内连接:

* 外连接:

* 左外连接:

* 右外连接:

* 迫切左外连接:

@Test

/**

* 区分内连接和迫切内连接区别

*/

publicvoid​ demo1(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

/**

* 内连接的SQL:

* SELECT * FROM customer c INNER JOIN orders o ON c.cid = o.cno;

* SELECT * FROM customer c,orders o WHERE c.cid = o.cno;

*/

/*List<Object[]> list = session.createQuery("from Customer c inner join c.orders").list();

for (Object[] objects : list) {

System.out.println(Arrays.toString(objects));

}*/

/**

* 迫切内连接:语法.inner join fetch

* ***** 迫切内连接和 内连接生成的SQL语句是一样的!!!

*/

List<Customer> list = session.createQuery("select distinct c from Customer c inner join fetch c.orders").list();

for​ (Customer customer : list) {

System.out.println(customer);

}

tx.commit();

session.close();

}

1.2.5 ​命名查询:

可以在配置文件中配置一个HQL,给HQL取个名字.通过名称获得到执行的HQL.

在映射文件中预定义一个HQL/SQL

<query name=”​findAllCustomer​”>from Customer</query>

@Test

/**

* 命名查询:

*/

publicvoid​demo2(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

List<Customer> list = session.getNamedQuery("​findAllCustomer​").list();

for​ (Customer customer : list) {

System.out.println(customer);

}

tx.commit();

session.close();

}

1.2.6 ​离线条件查询:

DetachedCriteria:离线条件查询.可以在没有session的情况下使用,在DAO层再去绑定session.应用在条件查询上.

Criteria:必须使用session创建.Criteria必须在DAO层才能使用.

@Test

/**

* 离线条件查询

*/

publicvoid​ demo3(){

DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.​class​);

detachedCriteria.add(Restrictions.like("cname", "%马%"));

detachedCriteria.add(Restrictions.gt("age", 38));

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

List<Customer> list = detachedCriteria.getExecutableCriteria(session).list();

for​ (Customer customer : list) {

System.out.println(customer);

}

tx.commit();

session.close();

}

1.3 ​Hibernate的抓取策略:

1.3.1 ​延迟加载:是否在执行语句的时候马上查询该对象.

类级别延迟加载:

Customer customer = session.load(Customer.class,1);

以下办法使延迟加载失效

持久化类如果使用final进行修饰,那么延迟加载就会失效!!!

<class>标签上有一个属性:lazy=”true”.配置lazy=”false”使类级别延迟加载失效.

Hibernate.initalize(Object proxy);

关联级别的延迟:

在<many-to-one>,<set>,<one-to-one>上lazy属性.

1.3.2 ​抓取策略:查询一个对象的时候,是否查询其关联对象.

<set>集合上的fetch和lazy

fetch:控制查询其关联对象采用的SQL语句的格式.

* select :普通select查询.(默认)

* join :使用连接查询.(fetch配置为join那么lazy就会失效.)

* subselect :使用子查询查询其关联对象.

lazy:控制查询其关联对象是否采用延迟加载

* true :采用延迟加载(默认)

* false :不采用延迟加载.立即加载

* extra :及其懒惰.

测试代码:详见HibernateDemo5.

<many-to-one>上的fetch 和 lazy:

fetch:控制SQL的格式

* select :普通select语句(默认)

* join :迫切左外连接

lazy:控制关联对象是否采用延迟

* false :不采用延迟加载

* proxy :默认.当前对象是否采用延迟,由另一方的<class>上的lazy属性来决定.

* no-proxy :

代码详见 HibernateDemo6

批量抓取:

查询客户时候批量抓取订单:

@SuppressWarnings("unchecked")

@Test

/**

* 查询客户,批量抓取订单

* <set>上配置batch-size=""

*/

publicvoid​ demo1(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

List<Customer> list = session.createQuery("from Customer").list();

for​ (Customer customer : list) {

System.out.println(customer);

System.out.println(customer.getOrders().size());

}

tx.commit();

session.close();

}

查询订单的时候,批量查询客户.

@SuppressWarnings("unchecked")

@Test

/**

* 查询订单,批量抓取客户

* 在.hbm.xmlCustomer中<class>上配置batch-size

*/

publicvoid​ demo2(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

List<Order> list = session.createQuery("from Order").list();

for​ (Order order : list) {

System.out.println(order);

System.out.println(order.getCustomer().getCname());

}

tx.commit();

session.close();

}

1.4 ​Hibernate的事务管理:

1.4.1 ​回顾事务:

什么是事务:

事务:指的是逻辑上一组操作,各个单元要么一起成功,要么一起失败!

事务特点:

原子性:指的是事务不可分割.

一致性:事务执行的前后,数据的完整性保持一致.

隔离性:一个事务在执行的过程中,不应该受到其他事务的干扰.

持久性:一个事务一旦执行结束,那么数据就永久的保存到数据库中.

如果不考虑事务的隔离性,引发哪些问题:

两大类问题:

* 读问题:

* 脏读 :一个事务读到了另一个事务还没有提交的数据.

* 不可重复读 :一个事务读到了另一个事务已经提交的update数据,而导致多次查询结果不一致.

* 虚读 :一个事务读到了另一个事务已经提交的insert数据,而导致多次查询结果不一致.

* 写问题:

* 引发两类丢失更新问题:

避免以上问题的发生:

避免读问题:

* 设置事务的隔离级别:

* 未提交读:以上读情况都能发生.

* 已提交读:避免脏读.但是不可重复读和虚读有可能发生.

* 可重复读:避免脏读,不可重复读.但是虚读有可能发生.

* 串行化 :避免以上所有读的问题.

避免写问题:

* 悲观锁:

* 乐观锁:

1.4.2 ​Hibernate中避免读问题:

设置事务的隔离级别:

<property name="hibernate.connection.isolation">4</property>

1.4.3 ​Hibernate避免写问题:

悲观锁:

@SuppressWarnings("deprecation")

@Test

/**

* 使用悲观锁解决丢失更新

*/

publicvoid​ demo3(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

Customer customer = (Customer) session.get(Customer.​class​, 1, LockMode.UPGRADE);

customer.setCname("小马");

tx.commit();

session.close();

}

@SuppressWarnings("deprecation")

@Test

/**

* 使用悲观锁解决丢失更新

*/

publicvoid​ demo4(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

Customer customer = (Customer) session.get(Customer.​class​, 1, LockMode.UPGRADE);

customer.setAge(52);

tx.commit();

session.close();

}

乐观锁:

@Test

/**

* 使用乐观锁解决丢失更新

*/

publicvoid​ demo5(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

Customer customer = (Customer) session.get(Customer.​class​, 1);

customer.setCname("小马");

tx.commit();

session.close();

}

@Test

/**

* 使用乐观锁解决丢失更新

*/

publicvoid​ demo6(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

Customer customer = (Customer) session.get(Customer.​class​, 1);

customer.setAge(52);

tx.commit();

session.close();

}

1.4.4 ​线程绑定的session的使用:

配置:

<!-- 开启与线程绑定的session -->

<propertyname="hibernate.current_session_context_class">thread</property>

使用sessionFactory.getCurrentSession();

1.5 ​Hibernate的反向工程:

1.5.1 ​Hibernate反向工程:

步骤一:创建一个数据库视图:

Hibernate_day03总结_hibernate_03

Hibernate_day03总结_sql_04

步骤二:新建工程:

Hibernate_day03总结_hibernate_05

步骤三:反向工程.回到数据库视图:

Hibernate_day03总结_hibernate_06


举报

相关推荐

0 条评论