Hibernate基础学习2

0)测试hibernate的一级缓存,事务以及查询语句

1)Hibernate的一些相关概念

hibernate的一级缓存
1)缓存是为了提高该框架对数据库的查询速度
2)一级缓存是将获取的结果放到了session中,再次查询直接从缓存中获取(提高查询效率)
3)缓存进阶之快照:将获取的一份结果放到session中,一份放到快照中,当修改时,对比快照与缓存,
如果数据没有发生变化,直接结束修改(避免不必要的修改)

hibernate的事务
在业务开始之前打开事务,在业务结束时提交事务,如果出现异常则回滚事务

1)事务的4大特性
A:原子性(Atomicity)
       事务是数据库的逻辑工作单位,事务中包括的诸操作要么全做,要么全不做。
B:一致性(Consistency)
       事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
C:隔离性(Isolation)
      一个事务的执行不能被其他事务干扰。
D:持续性/永久性(Durability)
      一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。

2)事务并发存在的问题
1.丢失更新:撤消一个事务时,把其它事务已提交的更新的数据覆盖了。
2.脏读:一个事务读到另一个事务未提交的更新数据。
3.幻读:一个事务执行两次查询,但第二次查询比第一次查询多出了一些数据行。
4.不可重复读:一个事务两次读同一行数据,可是这两次读到的数据不一样。

3)事务的隔离级别(处理事务并发问题)
1.Read uncommitted(读未提交)
顾名思义,就是一个事务可以读取另一个未提交事务的数据。

事例:老板要给程序员发工资,程序员的工资是3.6万/月。但是发工资时老板不小心按错了数字,
按成3.9万/月,该钱已经打到程序员的户口,但是事务还没有提交,就在这时,程序员去查看自己这个月的工资,
发现比往常多了3千元,以为涨工资了非常高兴。但是老板及时发现了不对,马上回滚差点就提交了的事务,
将数字改成3.6万再提交。

分析:实际程序员这个月的工资还是3.6万,但是程序员看到的是3.9万。他看到的是老板还没提交事务时的数据。这就是脏读。

那怎么解决脏读呢?Read committed!读提交,能解决脏读问题。

2.Read committed(读提交)
顾名思义,就是一个事务要等另一个事务提交后才能读取数据。

事例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他埋单时(程序员事务开启),
收费系统事先检测到他的卡里有3.6万,就在这个时候!!程序员的妻子要把钱全部转出充当家用,并提交。
当收费系统准备扣款时,再检测卡里的金额,发现已经没钱了(第二次检测金额当然要等待妻子转出金额事务提交完)。
程序员就会很郁闷,明明卡里是有钱的…

分析:这就是读提交,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后
才能读取数据,可以解决脏读问题。但在这个事例中,出现了一个事务范围内两个相同的查询却返回了不同数据,
这就是不可重复读。

那怎么解决可能的不可重复读问题?Repeatable read !

3.Repeatable read(重复读)
就是在开始读取数据(事务开启)时,不再允许修改操作

事例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他埋单时(事务开启,不允许其他事务的UPDATE修改操作),
收费系统事先检测到他的卡里有3.6万。这个时候他的妻子不能转出金额了。接下来收费系统就可以扣款了。

分析:重复读可以解决不可重复读问题。写到这里,应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。
但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。

什么时候会出现幻读?

事例:程序员某一天去消费,花了2千元,然后他的妻子去查看他今天的消费记录(全表扫描FTS,妻子事务开启),
看到确实是花了2千元,就在这个时候,程序员花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。
当妻子打印程序员的消费记录清单时(妻子事务提交),发现花了1.2万元,似乎出现了幻觉,这就是幻读。

那怎么解决幻读问题?Serializable!

4.Serializable(序列化,串行化:排队执行)
Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。
但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

study

2)在主配置文件中添加如下配置对事务进行管理

<!-- 指定hibernate操作数据库时的隔离级别
            #hibernate.connection.isolation 1|2|4|8
            0001    1    读未提交
            0010    2    读已提交
            0100    4    可重复读
            1000    8    串行化
         -->
        <property name="hibernate.connection.isolation">4</property>
        <!-- 指定session与当前线程绑定,事务中确保使用同一个session -->
        <property name="hibernate.current_session_context_class">thread</property>

3)测试对象的3种状态

package com.hibernate.test;

import com.hibernate.domain.Customer;
import com.hibernate.utils.HibernateUtils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

/**
 * @author: 肖德子裕
 * @date: 2018/11/15 11:41
 * @description: 测试hibernate框架
 */
public class Test {
    /**
     * 添加客户信息
     */
    @org.junit.Test
    public void addTest(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        //对象的3种状态体现(状态之间的转换)
        //瞬时状态:没有ID,没有与session关联
        Customer customer=new Customer();
        customer.setCust_name("xdzy");
        //持久化状态:有ID,与session有关联
        session.save(customer);

        /*******************************************************/

        tx.commit();
        //游离|托管状态,有ID,与sesssion无关联
        session.close();
    }

    /**
     * 删除客户信息
     */
    @org.junit.Test
    public void deleteTest(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        //获取ID为1的客户
        Customer customer = session.get(Customer.class, 30L);
        //删除
        session.delete(customer);

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 修改客户信息
     */
    @org.junit.Test
    public void updateTest(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        Customer customer = session.get(Customer.class, 6L);
        customer.setCust_name("xdzy");
        session.update(customer);

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 查询客户信息
     */
    @org.junit.Test
    public void selectTest(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        Customer customer = session.get(Customer.class, 6L);
        System.out.println(customer);

        /*******************************************************/

        tx.commit();
        session.close();
    }
}

测试

4)测试事务中获取session的方法

package com.hibernate.test;

import com.hibernate.utils.HibernateUtils;
import org.hibernate.Session;
import org.junit.Test;

/**
 * @author: 肖德子裕
 * @date: 2018/11/16 10:00
 * @description: 测试事务中获取session的方法
 */
public class Test2 {
    /**
     * 获取绑定的session是同一个,可以确保事务使用同一个session
     * 用该方法获取事务提交后会自动关闭,所以事务提交之后不能手动关闭,会引发异常
     */
    @Test
    public void test(){
        Session session = HibernateUtils.getCurrentSession();
        Session session1 = HibernateUtils.getCurrentSession();
        System.out.println(session==session1);
    }

    /**
     * 获取新的session
     */
    @Test
    public void test1(){
        Session session = HibernateUtils.openSession();
        Session session1 = HibernateUtils.openSession();
        System.out.println(session==session1);
    }
}

测试

5)测试HQL语句

package com.hibernate.test;

import com.hibernate.domain.Customer;
import com.hibernate.utils.HibernateUtils;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import java.util.List;

/**
 * @author: 肖德子裕
 * @date: 2018/11/16 10:26
 * @description: 测试HQL语句(hibernate独有的面向对象的语法)(适合不复杂的多表查询)
 * HQL语句不能出现数据库相关字段,而是类的属性或类的名称
 */
public class Test3 {
    /**
     * 查询所有
     */
    @Test
    public void test(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        //1)书写HQL语句
        String hql="from Customer";
        //2)创建查询对象
        Query query = session.createQuery(hql);
        //3)执行查询
        List<Customer> list = query.list();

        System.out.println(list);

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 指定查询
     */
    @Test
    public void test1(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        //1)书写HQL语句
        String hql="from Customer where cust_id=6";
        //2)创建查询对象
        Query query = session.createQuery(hql);
        //3)执行查询
        Customer customer = (Customer) query.uniqueResult();

        System.out.println(customer);

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 占位符
     */
    @Test
    public void test2(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        //1)书写HQL语句
        String hql="from Customer where cust_id=?";
        //2)创建查询对象
        Query query = session.createQuery(hql);
        //3)设置参数
        //query.setLong(0,6L);
        query.setParameter(0,6L);
        //4)执行查询
        Customer customer = (Customer) query.uniqueResult();

        System.out.println(customer);

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 命名占位符
     */
    @Test
    public void test3(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        //1)书写HQL语句
        String hql="from Customer where cust_id= :cust_id";
        //2)创建查询对象
        Query query = session.createQuery(hql);
        //3)设置参数
        //query.setLong(0,6L);
        query.setParameter("cust_id",6L);
        //4)执行查询
        Customer customer = (Customer) query.uniqueResult();

        System.out.println(customer);

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 分页查询所有
     */
    @Test
    public void test4(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        //1)书写HQL语句
        String hql="from Customer";
        //2)创建查询对象
        Query query = session.createQuery(hql);
        //3)设置分页条件(从0开始查询1条)
        query.setFirstResult(0);
        query.setMaxResults(1);
        //4)执行查询
        List<Customer> list = query.list();

        System.out.println(list);

        /*******************************************************/

        tx.commit();
        session.close();
    }
}

测试

6)测试Criteria语句

package com.hibernate.test;

import com.hibernate.domain.Customer;
import com.hibernate.utils.HibernateUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;

import java.util.List;

/**
 * @author: 肖德子裕
 * @date: 2018/11/16 10:26
 * @description: 测试criteria语句(hibernate独有的无语句的全面向对象的查询语法)(适合单表查询)
 * > (gt)
 * >= (ge)
 * < (lt)
 * <= (le)
 * == (eq)
 * != (ne)
 * in (in)
 * between and (between)
 * like (like)
 * is not null (isNotNull)
 * is null (isNull)
 * or (or)
 * and (and)
 */
public class Test4 {
    /**
     * 查询所有
     */
    @Test
    public void test(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        Criteria criteria = session.createCriteria(Customer.class);
        List list = criteria.list();
        System.out.println(list);

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 指定查询
     */
    @Test
    public void test1(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        Criteria criteria = session.createCriteria(Customer.class);
        criteria.add(Restrictions.eq("cust_id",6L));
        Customer customer = (Customer) criteria.uniqueResult();
        System.out.println(customer);

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 分页查询所有
     */
    @Test
    public void test2(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        Criteria criteria = session.createCriteria(Customer.class);
        criteria.setFirstResult(0);
        criteria.setMaxResults(1);
        List list = criteria.list();
        System.out.println(list);

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 查询总记录数,分页总行数
     */
    @Test
    public void test3(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        Criteria criteria = session.createCriteria(Customer.class);
        criteria.setProjection(Projections.rowCount());
        Long count = (Long) criteria.uniqueResult();
        System.out.println(count);

        /*******************************************************/

        tx.commit();
        session.close();
    }
}

测试

7)测试原生SQL语句

package com.hibernate.test;

import com.hibernate.domain.Customer;
import com.hibernate.utils.HibernateUtils;
import org.hibernate.*;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;

/**
 * @author: 肖德子裕
 * @date: 2018/11/16 10:26
 * @description: 测试原生SQL语句查询(适合复杂多表查询)
 */
public class Test5 {
    /**
     * 查询所有
     */
    @Test
    public void test(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        String sql="select * from cst_customer";
        SQLQuery query = session.createSQLQuery(sql);
        List<Object[]> list = query.list();
        for (Object[] customers:list){
            System.out.println(Arrays.toString(customers));
        }

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 查询所有并且封装到对象
     */
    @Test
    public void test1(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        String sql="select * from cst_customer";
        SQLQuery query = session.createSQLQuery(sql);
        query.addEntity(Customer.class);
        List<Customer> list = query.list();
        System.out.println(list);

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 占位符
     */
    @Test
    public void test2(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        String sql="select * from cst_customer where cust_id=?";
        SQLQuery query = session.createSQLQuery(sql);
        query.setParameter(0,6L);
        query.addEntity(Customer.class);
        Customer customer = (Customer) query.uniqueResult();
        System.out.println(customer);

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 分页查询
     */
    @Test
    public void test3(){
        //创建Session对象
        Session session = HibernateUtils.openSession();
        //开启事务并获取事务对象
        Transaction tx = session.beginTransaction();

        /********************* 数据库操作 **********************/

        String sql="select * from cst_customer limit ?,?";
        SQLQuery query = session.createSQLQuery(sql);
        query.setParameter(0,0);
        query.setParameter(1,1);
        query.addEntity(Customer.class);
        List<Customer> list = query.list();
        System.out.println(list);

        /*******************************************************/

        tx.commit();
        session.close();
    }
}

测试

原文地址:https://www.cnblogs.com/xdzy/p/9974922.html

时间: 2024-11-10 11:55:46

Hibernate基础学习2的相关文章

Hibernate基础学习(四)&mdash;对象-关系映射(上)

一.映射对象标识符      Java语言按内存地址来识别或区分同一个类的不同对象,而关系数据库按主键值来识别或区分同一个表的不同记录.Hibernate使用对象标识符(OID)来建立内存中的对象和数据库表中的记录的对应关系,对象的OID和数据库表的主键对应,为了保证OID的唯一性和不可变性,应该让Hibernate,而不是应用程序来为OID赋值.     Hibernate推荐在数据表中使用代理主键,即不具备业务含义的字段.代理主键通常为整型,因为整型比字符串要节省更多数据库空间.     在

JPA(三):JPA+Hibernate 基础学习

在该系列的第一篇文章中,我们已经提到JPA和Hibernate.下图是两者在系统架构中的作用: 由以上图片我们可以得出两个结论:首先JPA的主要作用就是持久化操作:其次JPA只是一种规范,它需要一种实现,正如上图显示的,Hibernate.oPenJPA等等.简单些,可以说JPA只是一套接口,本身不能完成任何事情. 而这篇博文的主要内容就是对JPA和Hibernate学习的一个总结.首先来看一个最简单的入门demo. 所需jar包: hibernate3.jar hibernate-cglib-

hibernate基础学习---hierbnate2级缓存

1:开启二级缓存sessionFactory需要安装jar包 2:在实体类配置文件添加(配置二级缓存).我的配置文件是Account.hbm.xml <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapp

Hibernate基础学习(二)&mdash;Hibernate相关API介绍

一.Hibernate的核心接口      所有的Hibernate应用中都会访问Hibernate的5个核心接口.      (1)Configuration接口: 配置Hibernate,启动Hibernate,创建SessionFactory对象.      (2)SessionFactory接口: 初始化Hibernate,创建Session.      (3)Session接口: 负责保存.更新.删除.加载和查询对象.      (4)Transaction接口: 管理事务.     

Hibernate基础学习(一)&mdash;初识Hibernate

一.对象的持久化 狭义的理解: 持久化仅仅指把对象永久的保存到数据库中. 广义的理解: 持久化包括和数据库相关的各种操作.         保存: 把对象永久保存到数据库中.         更新: 更新数据库中对象的状态.         删除: 从数据库中删除一个对象.         查询: 根据特定的查询条件,把符合查询条件的一个或者多个对象加载到内存中.   二.ORM      ORM(Object-Relation-Mapping),对象关系映射.      ORM的思想: 将关系

Hibernate基础学习(六)&mdash;Hibernate二级缓存

一.概述      Session的缓存是一块内存空间,在这个内存空间存放了相互关联的Java对象,这个位于Session缓存内的对象也被称为持久化对象,Session负责根据持久化对象的状态来同步更新数据库.      Session的缓存是内置的,不能被拆卸,也被称为Hibernate的第一级缓存.此外,SessionFactory有一个内置缓存和一个外置缓存,内置缓存不能被拆卸,而外置缓存是可插拔的缓存插件,也被称为Hibernate的第二级缓存,第二级的缓存本身实现很复杂,必须实现并发访

Spring Framework基础学习

Spring Framework基础学习 Core support for dependency injection,transaction management,web applications,data access,messaging,testing and more 推荐的官方文章:http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/index.html 一.Instrod

JAVA基础学习-集合三-Map、HashMap,TreeMap与常用API

一.Map简述 1.1.简述 public interface Map<K,V> 类型参数: K - 此映射所维护的键的类型 key V - 映射值的类型 value 该集合提供键--值的映射.key不能重复,一对对的存储方式 将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值. 1.2.方法 嵌套类摘要 static interface Map.Entry<K,V> 映射项(键-值对). 方法摘要 void clear() 从此映射中移除所有映射关系(可选操

Java新手学习路线,0基础学习Java怎样效率更高?

Java是老牌编程语言,拥有扎实的群众基础和广阔的市场应用,从业人员薪资也普遍较高.很多人想要加入到Java开发行列,不过0基础学习Java怎样效率更高? 很多0基础学习Java的同学想知道怎样学习效率更高?小编以为,学习Java需要一个系统的过程,而根据你未来的职位方向不同,学习也各有侧重.目前来说,Java就业方向包括Web开发.大数据开发.Android开发以及各种后端服务开发领域,但不论你选择哪一个,都要从最基础的知识点学习. Java基础知识点多且杂,初学者在开始的时候需要认识什么是J