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两种获取方式
(一)
- load方式是延迟加载,只有属性被访问的时候才会调用sql语句
- get方式是非延迟加载,无论后面的代码是否会访问到属性,马上执行sql语句
(二)对于id不存在的对象的处理
- get方式会返回null
- load方式会抛出异常
Hibernate获得session的两种方式
openSession和getCurrentSession 的区别在于 :
- 获取的是否是同一个session对象
openSession每次都会得到一个新的Session对象 ;
getCurrentSession在同一个线程中,每次都是获取相同的Session对象,但是在不同的线程中获取的是不同的Session对象 ;- 事务提交的必要性
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资料可免费领取资源。