Hibernate概念篇(二)

Hibernate使用Criteria进行分页查询

分页,从第3个开始,一共查询5个Product:

c.setFirstResult(2); 表示从第3条数据开始
c.setMaxResults(5); 表示一共查询5条数据

public class TestHibernate {
    public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
  
        Session s = sf.openSession();
        s.beginTransaction();
  
        String name = "iphone";
          
        Criteria c= s.createCriteria(Product.class);
        c.add(Restrictions.like("name", "%"+name+"%"));    // Criteria.add增加约束,模糊查询匹配
        c.setFirstResult(2);          // 表示从第3条数据开始
        c.setMaxResults(5);           // 表示一共查询5条数据
         
        List<Product> ps = c.list();
        for (Product p : ps) {
            System.out.println(p.getName());
        }
          
        s.getTransaction().commit();
        s.close();
        sf.close();
    }
}

在这里插入图片描述
在这里插入图片描述

比较Hibernate两种获取方式

(一)

  1. load方式是延迟加载,只有属性被访问的时候才会调用sql语句
  2. get方式是非延迟加载,无论后面的代码是否会访问到属性,马上执行sql语句

(二)对于id不存在的对象的处理

  1. get方式会返回null
  2. load方式会抛出异常

Hibernate获得session的两种方式

openSession和getCurrentSession 的区别在于 :

  1. 获取的是否是同一个session对象
    openSession每次都会得到一个新的Session对象 ;
    getCurrentSession在同一个线程中,每次都是获取相同的Session对象,但是在不同的线程中获取的是不同的Session对象 ;
  2. 事务提交的必要性
    openSession只有在增加,删除,修改的时候需要事务,查询时不需要的
    getCurrentSession是所有操作都必须放在事务中进行,并且提交事务后,session就自动关闭,不能够再进行关闭
  • OpenSession每次都会得到一个新的Session对象
public class TestHibernate {
    public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
  
        Session s1 = sf.openSession();
        Session s2 = sf.openSession();
         
        System.out.println(s1==s2);    //结果为false
        //equal比较的是内容是否一致,==直接比较的是内存地址是否一致。上述查询的是是否开启了新的session。比较的是内存地址
         
        s1.close();
        s2.close();
        sf.close();
    }
}
  • 相同线程的getCurrentSession,每次获取的都是相同的Session
public class TestHibernate {
    public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
 
        Session s1 = sf.getCurrentSession();
        Session s2 = sf.getCurrentSession();
 
        System.out.println(s1 == s2);       //返回true
 
        s1.close();
//      s2.close();
        sf.close();
    }
}
  • 不同线程的getCurrentSession,每次获取的都是不同的Session
public class TestHibernate {
    static Session s1;
    static Session s2;
 
    public static void main(String[] args) throws InterruptedException {
 
        final SessionFactory sf = new Configuration().configure().buildSessionFactory();
 
        Thread t1 = new Thread() {            //线程1
            public void run() {
                s1 = sf.getCurrentSession();
            }
        };
        t1.start();
 
        Thread t2 = new Thread() {            //线程2
            public void run() {
                s2 = sf.getCurrentSession();
            }
        };
        t2.start();
        t1.join();   //用join()线程是顺序执行的,不用时是并行执行的
        t2.join();
 
        System.out.println(s1 == s2);          //返回false
    }
 
}
  • getCurrentSession所有操作都必须放在事务中
public class TestHibernate {
 
    public static void main(String[] args) throws InterruptedException {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
        Session s1 = sf.getCurrentSession();
 //     s1.beginTransaction();         注释掉了事务运行会报错
      
        s1.get(Product.class, 5);
 
        s1.close();
        sf.close();
    }
 
}

在这里插入图片描述

  • getCurrentSession在提交事务后,session自动关闭
public class TestHibernate {
 
    public static void main(String[] args) throws InterruptedException {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
        Session s1 = sf.getCurrentSession();
 
        s1.beginTransaction();      //事务开启
        s1.get(Product.class, 5);
 
        s1.getTransaction().commit();      //提交事务后,session自动关闭
         
        s1.close();          //因为提交事务时session已关闭,再次试图关闭session运行便会报错
        sf.close();
    }
 
}

在这里插入图片描述

Hibernate使用Iterator实现N+1

N+1的定义

如果要查询N条数据:
list查n次得到n个对象,即直接查数据库;Iterator是先查一次得到所有id,然后最多再查n次得到n个对象(因为缓存中可能有,就不用查数据库了
即N+1中的1,就是指只返回id的SQL语句N指的是如果在缓存中找不到对应的数据,就到数据库中去查

案例:

public class TestHibernate {
    public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
        Session s = sf.openSession();
        s.beginTransaction();
  
        String name = "iphone";
         
        Query q =s.createQuery("from Product p where p.name like ?");
         
        q.setString(0, "%"+name+"%");      //只设置了参数还未真正开始查询
        
        Iterator<Product> it= q.iterate();    //首先通过Query的iterator把所有满足条件的Product的id查出来
        while(it.hasNext()){   //it.hasNext() 判断集合里是不是已经没有元素了 如果有就用 it.next();
            Product p =it.next();            //再通过it.next()查询每一个对象,如果这个对象在缓存中,就直接从缓存中取了
            System.out.println(p.getName());
        }
        
        s.getTransaction().commit();
        s.close();
        sf.close();
    }
  
}

Hibernate查询总数

首先还是准备一个有统计函数的语句,根据这条SQL语句创建一个Query对象,调用Query对象的uniqueResult()方法,返回一个long型的数据,即查询总数。

select count(*) from …

public class TestHibernate {
    public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
        Session s = sf.openSession();
        s.beginTransaction();
  
        String name = "iphone";
         
        Query q =s.createQuery("select count(*) from Product p where p.name like ?");  //SQL语句
        q.setString(0, "%"+name+"%");     //参数赋值
        long total= (Long) q.uniqueResult();     //执行sql语句并并返回一个long型的数据
        System.out.println(total);            //输出结果即为查询总数
        s.getTransaction().commit();
        s.close();
        sf.close();
    }
  
}

在这里插入图片描述
喜欢的朋友可以关注我的个人公众号,后台回复java资料可免费领取资源。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值