根据个人使用Hibernate的经验,介绍一下Hibernate的多种不同的查询和CUD操作,这些东西在日常开发中非常常用,希望对大家有所帮助。
首先两张表:member和userinfo,member帐号信息表外键关联userinfo用户基本信息表,主键自动生成即可
最后映射出的POJO如下:
public class Userinfo implements Serializable{ // primary key }
public class Member implements Serializable{ // primary key
// fields
private java.lang.String loginCode; private java.lang.String password; private java.lang.Integer deleteFlag; private java.lang.Integer id; // collections
private java.util.Set
//省略 getter setter // fields
private java.lang.String name; private java.lang.String code; private java.lang.String birthday; private java.lang.String address; private java.util.Date createTime; private java.lang.Integer deleteFlag; private java.lang.Integer id;
}
// many to one
private com.bless.model.Userinfo fkUserinfo; //省略getter setter
1、Hibernate提供多种方法查询数据库数据
下面以一个最简单的查询为例:SELECT * FROM TABLE为例 1-1简单HQL语句查询
Hibernate提供了HQL查询,HQL是Hibernate推荐语句,它屏蔽了不同数据库SQL不兼容的问题,使用HQL写的查询语句在主流数据库上都能执行。
执行HQL需要创建Query对象:getSession().createQuery(hql语句);
简单HQL格式:FROM POJO 对应SQL语句:SELECT * FROM POJO对应的表名
千万注意:HQL语句中的表名和字段名不是数据库的表名和字段名,而是对应ORM映射POJO的类名和属性名!
Query query = baseDao.getQuery(\); List
System.out.println(\fk_id:\ }
结果:一句SQL将所有结果查询出来
如果修改一下for循环的代码,查询FK的name: for (Member member : lstM) {
System.out.println(\fk_id:\ }
结果:一句SQL查询Member表,每一次for循环又发一句SQL查询Userinfo表
总结:被查询表中如果有外键关联,在执行查询时能将外键关联字段的值查询出来,但如果想查询关联表的其它字段会另外发SQL,这个特别要注意!
1-2简单SQL语句查询
Hibernate同样支持写SQL,对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口。
SQLQuery sql = baseDao.getSQLQuery(\); //查询出的结果放到指定POJO中
sql.addEntity(Member.class); List
System.out.println(\fk_id:\
}
结果:一句SQL将所有结果查询出来
如果修改一下for循环的代码,查询FK的name,结果与前面使用HQL查询一样:一句SQL查询Member表,随后每一次for循环又发一句SQL查询Userinfo表
1-3Hibernate条件查询(Criteria)
HQL极为强大,但是有些人希望能够动态的使用一种面向对象API创建查询,而非在他们的Java代码中嵌入字符串。对于那部分人来说,Hibernate提供了直观的Criteria查询API。
获取Hibernate的Criteria对象方法:getSession().createCriteria(Class对象); Criteria crit = baseDao.getCriteria(Member.class); List
其实上面这种方式就是发了一句SQL:SELECT * FROM member 结果:一句SQL将所有结果查询出来
如果修改一下for循环的代码,查询FK的name,结果与前面情况一样
2、在简单的select from table基础上,加上分页和排序 以此为例:查询第11条~20条数据,按照ID降序排列
2-1使用HQL
Query query = baseDao.getQuery(\); query.setFirstResult(10); query.setMaxResults(10);
List
2-2使用SQL
SQLQuery sql = baseDao.getSQLQuery(\* FROM member m ORDER BY m.id DESC\);
sql.setFirstResult(10); sql.setMaxResults(10); //查询出的结果放到指定POJO中
sql.addEntity(Member.class); List
System.out.println(\+member.getId()+\fk_id:\+member.getFkUserinfo().getId());
System.out.println(\+member.getId()+\fk_id:\+member.getFkUserinfo().getId());
System.out.println(\fk_id:\
2-3使用Criteria
Criteria crit = baseDao.getCriteria(Member.class); crit.setFirstResult(10); crit.setMaxResults(10);
crit.addOrder(Order.desc(\)); List
3、数据库查询核心是条件,绝大多数SQL都会带有WHERE子句,下面介绍简单的WHERE查询 以此为例:SELECT * FROM member m WHERE m.login_code like ?kaka%? AND m.password in (?12345?, ‘123451?,?123452?) AND m.delete_flag=0;这里面有like、in和=三种查询
特别注意:绝对不推荐直接在SQL语句后面拼接参数值:“*** WHERE id=”+id+” AND name like ”+name+”%”;这种方式可能会造成很严重的后果:每一个不同的id值都会在内存中创建一个SQL请求对象,如果id多并且多次执行该句SQL很可能出现宕机状况!推荐使用下面这些赋值方式,下面的方式都只会在内存中创建一个SQL请求对象。 3-1-1使用HQL“WHERE 字段=?”的形式给条件赋值
这种打?号传值的方式在JDBC是非常常见的了,使用HQL语句也可以通过这种方式赋值:
Query query = baseDao.getQuery(\AND m.password in (?,?,?) AND m.deleteFlag=?\); query.setParameter(0, \); query.setParameter(1, \); query.setParameter(2, \); query.setParameter(3, \); query.setParameter(4, 0);
List
通过query.setParameter(int,Obejct)方法即可给每个?赋值,注意第一个参数是从下标0开始!
3-1-2使用HQL “WHERE 字段=:key”的形式给条件赋值
这种赋值方式是HQL特有的,什么意思呢,直接看例子分析: Query query = baseDao.getQuery(\Member m WHERE m.loginCode LIKE :code AND m.password in (:pwd) AND m.deleteFlag=:flag\); query.setParameter(\, \); query.setParameterList(\, new String[]{\,\,\}); query.setParameter(\, 0);
System.out.println(\+member.getId()+\fk_id:\+member.getFkUserinfo().getId());
System.out.println(\+member.getId()+\fk_id:\+member.getFkUserinfo().getId());
List
上面例子关键代码是Query调用setParameter(String,Object)和setParameterList两个方法,前者是赋单一值,后者是赋多个值(特别适合in查询赋值)。这两种赋值方法都需要传两参数:第一个参数是key值,对应HQL语句中的“:xxx”;第二个参数是value值,就对应key的实际值。这种传值比3-1-1更准确方便:一来不用担心下标错位的问题,二来如果存在”xx,xx,xx”这种格式的参数可以使用setParameterList方法,屡试不爽!
3-2-1使用SQL“WHERE 字段=?”的形式给参数赋值
SQLQuery sql = baseDao.getSQLQuery(\m.login_code LIKE ? AND m.password in (?,?,?) AND m.delete_flag=?\); sql.setParameter(0, \); sql.setParameter(1, \); sql.setParameter(2, \); sql.setParameter(3, \); sql.setParameter(4, 0); sql.addEntity(Member.class); List
上面这段代码与3-1-2的代码极其相似,但是有以下几点区别:①使用SQLQuery的形式查询;②SQL语句m.login_code和m.delete_flag与前面的HQL里面不对应,前面说了HQL里面对应的是POJO(也就是Member类)的属性,而SQL语句是直接对应数据库的字段名!
3-2-2使用SQL “WHERE 字段=:key”的形式给条件赋值
注意这种key/value赋值的形式是通过SQLQuery对象创建的SQL才能用,下面这段代码是能查询出结果的
SQLQuery sql = baseDao.getSQLQuery(\m.login_code LIKE :code AND m.password in (:pwd) AND m.delete_flag=:flag\);
sql.setParameter(\, \);
sql.setParameterList(\, new String[]{\,\,\}); sql.setParameter(\, 0); sql.addEntity(Member.class); List
System.out.println(\+member.getId()+\fk_id:\+member.getFkUserinfo().getId());
System.out.println(\+member.getId()+\fk_id:\+member.getFkUserinfo().getId());
System.out.println(\+member.getId()+\fk_id:\+member.getFkUserinfo().getId());