JavaWeb框架——Hiernate(二)

1、Hibernate中的实体规则和对象状态
这里写图片描述
这里写图片描述
这里写图片描述
主键生成策略配置以及对象状态代码示例
Customer.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping package="cn.ctgu.domain">
    <class name="Customer" table="customer">
        <id name="id"  column="id">
            <!-- generator:主键生成策略
                就是每条记录录入时,主键的生成规则(7个)
                identity:主键自增,有数据库来维护主键值,录入时不需要指定主键
                increment(不用,存在线程安全问题,当多个线程同时插入数据事可能会产生覆盖):主键自增,由hibernate来维护,每次插入时会先查询表中id最大值,+1作为新主键值
                sequence:Oracle中的主键生成策略
                hilo(不用,同样存在线程安全问题):高低位算法,主键自增,由hibernate来维护,开发时不使用
                native:hilo+sequence+identity 自动三选一策略
                uuid:产生随机字符串作为主键,主键类型必须为String类型,否则会报错
                assigned:自然主键生成策略,hibernate不会管理主键值,由开发人员自己录入
             -->
            <generator class="native"></generator>
        </id>
        <property name="name" column="NAME" ></property>
        <property name="source" column="source"></property>
        <property name="industry" column="industry"></property>
        <property name="level" column="LEVEL"></property>
        <property name="phone" column="phone"></property>
        <property name="mobile" column="mobile"></property>
    </class>
</hibernate-mapping>
package cn.ctgu.state;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.ctgu.domain.Customer;
import cn.ctgu.utils.HibernateUtils;

//测试对象的三种状态
public class Demo {
    @Test
    //三种状态特点
    //save方法:其实不能理解成保存,理解成将瞬时状态转换成持久状态的方法
    //主键自增:执行save方法是为了将对象转换成持久化状态,必须生成id值,所以需要执行insert语句生成
    //increment:执行save方法,为了生成id,会执行查询id最大值的sql语句
    public void fun1() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        Customer c=new Customer();//没有id,没有与session关联=》瞬时状态

        c.setName("联想");//瞬时状态

        session.save(c);//持久化状态,有id,有关联
        //4、提交事务,关闭资源
        tx.commit();
        session.close();//游离|托管状态,有id,没有关联
    }

    @Test
    //持久化状态特点: 持久化状态对象的任何变化都会自动同步到数据库中
    public void fun2() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        Customer c=session.get(Customer.class, 1l);//持久化状态对象    
        c.setName("微软");

        session.save(c);//持久化状态,有id,有关联
        //4、提交事务,关闭资源
        tx.commit();
        session.close();//游离|托管状态,有id,没有关联
    }
}

2、Hibernate一级缓存快照及事务
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
相应配置及代码示例
hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- 必选配置 5个-->

        <!-- 数据库驱动 -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <!-- 数据库url -->
        <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
        <!-- 数据库用户名 -->
        <property name="hibernate.connection.username">root</property>
         <!-- 数据库连接密码 -->
        <property name="hibernate.connection.password">123456</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>


        <property name="hibernate.show_sql">true</property>
          <!--将hibernate生成的sql语句格式化(语法缩进)  -->
        <property name="hibernate.format_sql">true</property>

        <!-- 
        ## auto schema export  自动到处表结构,自动建表,意思就是即使数据库中没有建立与实体相对应的表,它也不会插入数据
        失败,因为它会自动创建一个表到数据库中,然后在插入数据

        #hibernate.hbm2ddl.auto create-drop 自动建表,每次框架运行都会将所有表删除(开发环境中使用)
        #hibernate.hbm2ddl.auto create  自动建表,每次框架运行都会创建新的表,以前的表将会被覆盖,表数据会丢失(开发环境中测试使用)
        #hibernate.hbm2ddl.auto update  (推荐使用)自动生成表,如果已经存在就不会生成,如果表有变动,自动更新表(不会删除任何数据)
        #hibernate.hbm2ddl.auto validate    校验,不自动生成表,每次启动会校验数据库中表是否正确,也就是校验是否与实体匹配,校验失败则抛出异常
         -->
        <property name="hibernate.hbm2ddl.auto">update</property>       

         <!--指定hibernate操作数据库时的隔离级别

            ## specify a JDBC isolation level

            #hibernate.connection.isolation 1|2|4|8
            0001    1   读未提交
            0010    2   读已提交
            0100    4   可重复读
            1000    8   串行化
           -->
           <property name="hibernate.connection.isolation">4</property>

           <!-- 指定session与当前线程绑定 -->
           <property name="hibernate.current_session_context_class">thread</property>

        <mapping resource="cn/ctgu/domain/Customer.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

缓存以及快照测试代码

package cn.ctgu.cache;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.ctgu.domain.Customer;
import cn.ctgu.utils.HibernateUtils;

//测试一级缓存
public class Demo {
    @Test
    //证明一级缓存的存在
    public void fun1() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        Customer c1=session.get(Customer.class, 1l);
        Customer c2=session.get(Customer.class, 1l);
        Customer c3=session.get(Customer.class, 1l);
        Customer c4=session.get(Customer.class, 1l);
        Customer c5=session.get(Customer.class, 1l);
        System.out.println(c3=c5);//true,只会执行一次,其它的直接在缓存中取

        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }

    @Test
    //快照
    public void fun2() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        Customer c1=session.get(Customer.class, 1l);

        c1.setName("haha");
        c1.setName("谷歌");//直接取快照中的数据,而不再操作数据库,由于跟数据库中的数据c1一样

        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }

    @Test
    //持久化状态对象其实就是放入session缓存中的对象
    public void fun3() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        Customer c1=new Customer();
        c1.setId(1l);//托管|游离状态

        session.update(c1);//c1被放入session缓存了,由游离状态变为持久化状态
        Customer c2=session.get(Customer.class, 1l);

        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }
}

测试getCurrentSession

package cn.ctgu.tx;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.ctgu.domain.Customer;
import cn.ctgu.utils.HibernateUtils;
//测试getCurrentSession
public class Demo {
    @Test
    //证明获取到的是同一个线程,前提必须得再主配置文件中配置
    public void fun1() {
        //1、获得session
        Session session1=HibernateUtils.getCurrentSession();
        Session session2=HibernateUtils.getCurrentSession();

        System.out.println(session1==session2);//true,表示session1和session2是同一个session

    }
}

3、Hibernate中的批量查询
3.1 HQL查询
这里写图片描述
这里写图片描述
这里写图片描述
代码示例

package cn.ctgu.hql;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.ctgu.domain.Customer;
import cn.ctgu.utils.HibernateUtils;

public class Demo {
    @Test
    //基本查询
    public void fun1() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        //1、书写HQL语句
    //  String hql="select * from cn.ctgu.domain.Customer";
    //  String hql="from cn.ctgu.domain.Customer";
        String hql="from Customer";//以上三种都是查询所有Customer对象,注意后面接的实体的完整类名(只有不重复Customer类时才可以这样用)

        //2、根据HQL语句创建查询对象
        Query query=session.createQuery(hql);
        //3、根据查询对象获得查询结果
        List<Customer>list=query.list();//返回list结果
        //query.uniqueResult();//接收唯一的查询结果
        System.out.println(list);
        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }

    @Test
    //条件查询
    //HQ语句中不可能出现任何数据库相关的信息的
    public void fun2() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        //1、书写HQL语句
        String hql="from Customer where id=1";//以上三种都是查询所有Customer对象

        //2、根据HQL语句创建查询对象
        Query query=session.createQuery(hql);
        //3、根据查询对象获得查询结果
        Customer c=(Customer) query.uniqueResult();//接收唯一的查询结果
        System.out.println(c);
        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }

    @Test
    //条件查询
    //问号占位符
    public void fun3() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        //1、书写HQL语句
        String hql="from Customer where id=?";//以上三种都是查询所有Customer对象

        //2、根据HQL语句创建查询对象
        Query query=session.createQuery(hql);
        //设置参数
        //query.setLong(0, 1l);//参数设置方式一:设置第一个参数为1l,注意:是从0开始的
        query.setParameter(0, 1l);//参数设置方式二,不需要管它参数是什么类型
        //3、根据查询对象获得查询结果
        Customer c=(Customer) query.uniqueResult();//接收唯一的查询结果
        System.out.println(c);
        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }

    @Test
    //条件查询
    //命名占位符
    public void fun4() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        //1、书写HQL语句
        String hql="from Customer where id=:cus_id";//以上三种都是查询所有Customer对象

        //2、根据HQL语句创建查询对象
        Query query=session.createQuery(hql);
        //设置参数
        query.setParameter("cus_id", 1l);//参数设置方式二,不需要管它参数是什么类型
        //3、根据查询对象获得查询结果
        Customer c=(Customer) query.uniqueResult();//接收唯一的查询结果
        System.out.println(c);
        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }

    @Test
    //分页查询
    public void fun5() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        //1、书写HQL语句
        String hql="from Customer limit ?,?";//以上三种都是查询所有Customer对象

        //2、根据HQL语句创建查询对象
        Query query=session.createQuery(hql);
        //设置分页信息  相当于limit ?,?
        query.setFirstResult(0);
        query.setMaxResults(1);


        //3、根据查询对象获得查询结果
        List<Customer>list=query.list();//接收唯一的查询结果
        System.out.println(list);
        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }
}

3.2 Criteria查询
这里写图片描述
这里写图片描述
这里写图片描述
代码示例

package cn.ctgu.criteria;

import java.util.List;

import org.hibernate.Criteria;
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 cn.ctgu.domain.Customer;
import cn.ctgu.utils.HibernateUtils;
//测试criteria查询
public class Demo {
    @Test
    public void fun1() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        //查询所有的Customer对象
        Criteria criteria=session.createCriteria(Customer.class);
        List<Customer>list=criteria.list();
        System.out.println(list);

        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }


    @Test
    //条件查询
    public void fun2() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        //查询所有的Customer对象
        Criteria criteria=session.createCriteria(Customer.class);
        //添加criteria查询对象=>查询id为1的Customer对象
        /*
         * >        gt
         * >=       ge
         * <=       lt
         * ==       eq
         * !=       ne
         * in       in
         * between and      between
         * like     like
         * is not null      isNotNull
         * is null      isNull
         * or       or
         * and      and 
         * */
        criteria.add(Restrictions.eq("id", 1l));
        //执行查询获得结果
        Customer c=(Customer)criteria.uniqueResult();
        System.out.println(c);

        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }

    @Test
    //分页查询
    public void fun3() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        //查询所有的Customer对象
        Criteria criteria=session.createCriteria(Customer.class);
        //设置分页查询limit ?,?
        criteria.setFirstResult(0);
        criteria.setMaxResults(1);
        //执行查询获得结果
        List<Customer>list=criteria.list();
        System.out.println(list);
        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }

    @Test
    //查询总记录数
    public void fun4() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        //查询所有的Customer对象
        Criteria criteria=session.createCriteria(Customer.class);
        //设置查询的聚合函数=>总行数
        criteria.setProjection(Projections.rowCount());
        //执行查询获得结果
        Long count=(Long) criteria.uniqueResult();
        System.out.println(count);
        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }
}

3.3 原生SQL查询
这里写图片描述
这里写图片描述
这里写图片描述
代码示例

package cn.ctgu.sql;

import java.util.Arrays;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.ctgu.domain.Customer;
import cn.ctgu.utils.HibernateUtils;

//测试原生sql查询
public class Demo {
    @Test
    //基本查询
    public void fun1() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        //1、书写sql语句
        String sql="select * from Customer";
        //2、创建sql查询对象
        SQLQuery query=session.createSQLQuery(sql);
        //指定将结果集封装到哪个对象中
        query.addEntity(Customer.class);
        //3、调用方法查询结果
        List<Customer>list=query.list();
        //query.uniqueResult();

        System.out.println(list);


        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }

    @Test
    //条件查询
    public void fun2() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        //1、书写sql语句
        String sql="select * from Customer where id=?";
        //2、创建sql查询对象
        SQLQuery query=session.createSQLQuery(sql);

        query.setParameter(0, 1l);
        //将指定结果封装到哪个对象中
        query.addEntity(Customer.class);
        //3、调用方法查询结果
        List<Customer>list=query.list();
        //query.uniqueResult();

        System.out.println(list);


        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }

    @Test
    //分页查询
    public void fun3() {
        //1、获得session
        Session session=HibernateUtils.openSession();
        //2、控制事务
        Transaction tx=session.beginTransaction();
        //3、执行操作
        //1、书写sql语句
        String sql="select * from Customer limit ?,?";
        //2、创建sql查询对象
        SQLQuery query=session.createSQLQuery(sql);

        query.setParameter(0, 0);
        query.setParameter(1, 1);
        //将指定结果封装到哪个对象中
        query.addEntity(Customer.class);
        //3、调用方法查询结果
        List<Customer>list=query.list();
        //query.uniqueResult();

        System.out.println(list);


        //4、提交事务,关闭资源
        tx.commit();
        session.close();
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值