hibernate对jdbc进行了一些列的封装,最重要就是对我们的SQL进行封装,我们在对数据库进行CRUD的时候我们基本上都是调用H的各种操作方法,而不用去编写实际的SQL,这个数据库所需要的SQL是H根据对应的语法自动生成的,而在查询这个地方由于查询的复杂程度很高,所以hibernate提供了4中查询的方式
1、根据主键查询数据
2、利用HQL进行数据查询 hiberante的查询语句
3、利用纯面向对象Criteria查询,
4、原生的SQL查询
主键查询
根据主键查询主要是两个方法 get 和 load,这两个方法的区别见hibernate面试题详解,
HQL查询
public void getAccountByMoney(int money) {
Session session1 = this.sessionFactory.openSession();
//HQL查询余额大于100的账户信息
String hql = "from Account where money > ?";
List<Account> list = session1.createQuery(hql).setInteger(0, money).list();
session1.close();
}
此处我们需要注意:HQL语句是需要使用hibernate的查询规则,
以前是查询表,在HQL里面是查询对象 所以表名的地方要写类名,字段的地方要写属性,其他地方和SQL基本一样
HQL查询实现分页,
public void getAccountByPage(int page) {
Session session1 = this.sessionFactory.openSession();
//HQL查询余额大于100的账户信息
String hql = "from Account order by id desc";
int start = (page-1) * 2;
List<Account> list = session1.createQuery(hql)
.setFirstResult(start) //分页起始位置
.setMaxResults(2) //每页返回的条数
.list();
System.out.println(list);
session1.close();
}
在hibernate中分页也是利用方法了来进行实现的,设置起始位置和每页条数
连接查询 inner join left join right join + fetch
public void getAccountByPage(int page) {
Session session1 = this.sessionFactory.openSession();
//HQL查询余额大于100的账户信息
String hql = "from Account a inner join fetch a.admin where a.id>2 order by a.id desc";
int start = (page-1) * 2;
List<Account> list = session1.createQuery(hql)
.setFirstResult(start) //分页起始位置
.setMaxResults(2) //每页返回的条数
.list();
System.out.println(list);
session1.close();
}
hibernate纯面向对象查询,Criteria
public void getAccountByPage2(int page) {
Session session1 = this.sessionFactory.openSession();
List<Account> list2 = session1.createCriteria(Account.class)
.setFirstResult(1)
.setMaxResults(2)
.list();
// System.out.println(list2);
session1.close();
}
条件添加:
public void getAccountByPage2(int page) {
Session session1 = this.sessionFactory.openSession();
List<Account> list2 = session1.createCriteria(Account.class)
.add(Restrictions.lt("id", 2))
.addOrder(Order.asc("id"))
.setFirstResult(0)
.setMaxResults(2)
.list();
System.out.println(list2);
session1.close();
}
在Criteria这个查询方式中,由于没有了HQL和SQL的编写,所以针对查询时候的条件,我们也需要调用方法来进行实现,
Restrictions接口定义了我们SQL的常规的查询条件,比如大于,等于,小于。like
Order接口定义了排序的规则
此处发现一个BUG,在Criteria的时候,对于我们的关系映射解析是有问题,如果我们在查询对象去访问了我们关联对象的属性,而关联对象又访问了我们该对象的属性,那我们这个Criteria接口就会以死循环的形式进行数据查询
解决方案就是需要控制另外一端不返回访问关联映射的属性
原生SQL查询: 在现有的项目当中,很多公司都是用原生SQL在进行数据操作
public void getAccountByPage3(int page) {
Session session1 = this.sessionFactory.openSession();
String sql = "select * from account";
List<Account> list2 = session1.createSQLQuery(sql)
.addEntity(Account.class)
.setFirstResult(0)
.setMaxResults(2)
.list();
System.out.println(list2);
session1.close();
}
如果项目开发需要使用原生SQL查询来操作,一般会引入一个hibernate的依赖,这个依赖对hibernate进行了 再次封装,
暴露出来4个方法
查询SQL
修改SQL
增加SQL
删除SQL
这样我们hibernate也可以达到轻量级的开发,
简述HQL和SQL的区别? – 面试题