Hibernate常规用法见解.docx

上传人:b****6 文档编号:5957340 上传时间:2023-01-02 格式:DOCX 页数:14 大小:84.41KB
下载 相关 举报
Hibernate常规用法见解.docx_第1页
第1页 / 共14页
Hibernate常规用法见解.docx_第2页
第2页 / 共14页
Hibernate常规用法见解.docx_第3页
第3页 / 共14页
Hibernate常规用法见解.docx_第4页
第4页 / 共14页
Hibernate常规用法见解.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

Hibernate常规用法见解.docx

《Hibernate常规用法见解.docx》由会员分享,可在线阅读,更多相关《Hibernate常规用法见解.docx(14页珍藏版)》请在冰豆网上搜索。

Hibernate常规用法见解.docx

Hibernate常规用法见解

Hibernate常用API详解

根据个人使用Hibernate的经验,介绍一下Hibernate的多种不同的查询和CUD操作,这些东西在日常开发中非常常用,希望对大家有所帮助。

 

 

以下示例均以两张表为例:

member和userinfo,member帐号信息表外键关联userinfo用户基本信息表,主键自动生成即可

 

然后映射出的POJO如下:

publicclassUserinfo  implementsSerializable{

//primarykey

    private java.lang.Integer id;

 

    //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;

 

    //collections

    private java.util.Set members;

        

         //省略 gettersetter

}

 

publicclassMemberimplementsSerializable{

//primarykey

    private java.lang.Integer id;

 

    //fields

    private java.lang.String loginCode;

    private java.lang.String password;

    private java.lang.Integer deleteFlag;

 

    //manytoone

    private com.bless.model.Userinfo fkUserinfo;

 

         //省略gettersetter

}

 

 

 

 

1、Hibernate提供多种方法查询数据库数据

下面以一个最简单的查询为例:

SELECT*FROMTABLE为例

1-1简单HQL语句查询

Hibernate提供了HQL查询,HQL是Hibernate推荐语句,它屏蔽了不同数据库SQL不兼容的问题,使用HQL写的查询语句在主流数据库上都能执行。

执行HQL需要创建Query对象:

getSession().createQuery(hql语句);

简单HQL格式:

FROMPOJO 对应SQL语句:

SELECT*FROMPOJO对应的表名

 

千万注意:

HQL语句中的表名和字段名不是数据库的表名和字段名,而是对应ORM映射POJO的类名和属性名!

 

Java代码  

1.Query query = baseDao.getQuery("FROM Member");  

2.List lstM = query.list();  

3.for (Member member :

 lstM) {  

4.System.out.println("id:

"+member.getId()+"   fk_id:

"+member.getFkUserinfo().getId());  

5.}  

 

 结果:

一句SQL将所有结果查询出来

 

如果修改一下for循环的代码,查询FK的name:

 

Java代码  

1.for (Member member :

 lstM) {  

2.System.out.println("id:

"+member.getId()+"   fk_id:

"+member.getFkUserinfo().getName());  

3.}  

 

 结果:

一句SQL查询Member表,每一次for循环又发一句SQL查询Userinfo表

总结:

被查询表中如果有外键关联,在执行查询时能将外键关联字段的值查询出来,但如果想查询关联表的其它字段会另外发SQL,这个特别要注意!

 

 

1-2简单SQL语句查询

 

Hibernate同样支持写SQL,对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口

 

Java代码  

1.SQLQuery sql = baseDao.getSQLQuery("SELECT * FROM member");  

2.//查询出的结果放到指定POJO中  

3.sql.addEntity(Member.class);  

4.List lstM = sql.list();  

5.for (Member member :

 lstM) {  

6.    System.out.println("id:

"+member.getId()+"   fk_id:

"+member.getFkUserinfo().getId());  

7.}  

 结果:

一句SQL将所有结果查询出来

 

如果修改一下for循环的代码,查询FK的name,结果与前面使用HQL查询一样:

一句SQL查询Member表,随后每一次for循环又发一句SQL查询Userinfo表

 

1-3Hibernate条件查询(Criteria)

 

HQL极为强大,但是有些人希望能够动态的使用一种面向对象API创建查询,而非在他们的Java代码中嵌入字符串。

对于那部分人来说,Hibernate提供了直观的Criteria查询API。

 

获取Hibernate的Criteria对象方法:

getSession().createCriteria(Class对象);

 

Java代码  

1.Criteria crit = baseDao.getCriteria(Member.class);  

2.List lstM = crit.list();  

3.for (Member member :

 lstM) {  

4.    System.out.println("id:

"+member.getId()+"   fk_id:

"+member.getFkUserinfo().getId());  

5.}  

 其实上面这种方式就是发了一句SQL:

SELECT*FROMmember

 

结果:

一句SQL将所有结果查询出来

如果修改一下for循环的代码,查询FK的name,结果与前面情况一样

 

 

2、在简单的selectfromtable基础上,加上分页和排序

以此为例:

查询第11条~20条数据,按照ID降序排列

 

2-1使用HQL

 

Java代码  

1.Query query = baseDao.getQuery("FROM Member m ORDER BY m.id DESC");  

2.query.setFirstResult(10);  

3.query.setMaxResults(10);  

4.List lstM = query.list();  

5.for (Member member :

 lstM) {  

6.    System.out.println("id:

"+member.getId()+"   fk_id:

"+member.getFkUserinfo().getId());  

7.}  

 

 

2-2使用SQL

 

Java代码  

1.SQLQuery sql = baseDao.getSQLQuery("SELECT * FROM member m ORDER BY m.id DESC");  

2.sql.setFirstResult(10);  

3.sql.setMaxResults(10);  

4.//查询出的结果放到指定POJO中  

5.sql.addEntity(Member.class);  

6.List lstM = sql.list();  

7.for (Member member :

 lstM) {  

8.    System.out.println("id:

"+member.getId()+"   fk_id:

"+member.getFkUserinfo().getId());  

9.}  

 

 

2-3使用Criteria

 

Java代码  

1.Criteria crit = baseDao.getCriteria(Member.class);  

2.crit.setFirstResult(10);  

3.crit.setMaxResults(10);  

4.crit.addOrder(Order.desc("id"));  

5.List lstM = crit.list();  

6.for (Member member :

 lstM) {  

7.    System.out.println("id:

"+member.getId()+"   fk_id:

"+member.getFkUserinfo().getId());  

8.}  

 

 

 

 

3、数据库查询核心是条件,绝大多数SQL都会带有WHERE子句,下面介绍简单的WHERE查询

以此为例:

SELECT*FROMmembermWHEREm.login_codelike‘kaka%’ANDm.passwordin(‘12345’,‘123451’,’123452’)ANDm.delete_flag=0;这里面有like、in和=三种查询

 

特别注意:

绝对不推荐直接在SQL语句后面拼接参数值:

“***WHEREid=”+id+”ANDnamelike”+name+”%”;这种方式可能会造成很严重的后果:

每一个不同的id值都会在内存中创建一个SQL请求对象,如果id多并且多次执行该句SQL很可能出现宕机状况!

推荐使用下面这些赋值方式,下面的方式都只会在内存中创建一个SQL请求对象。

 

 

3-1-1使用HQL“WHERE 字段=?

”的形式给条件赋值

 

这种打?

号传值的方式在JDBC是非常常见的了,使用HQL语句也可以通过这种方式赋值:

 

Java代码  

1.Query query = baseDao.getQuery("FROM Member m WHERE m.loginCode LIKE ?

 AND m.password in (?

?

?

) AND m.deleteFlag=?

");  

2.query.setParameter(0, "kaka%");  

3.query.setParameter(1, "12345");  

4.query.setParameter(2, "123451");  

5.query.setParameter(3, "123452");  

6.query.setParameter(4, 0);  

7.List lstM = query.list();  

8.for (Member member :

 lstM) {  

9.    System.out.println("id:

"+member.getId()+"   fk_id:

"+member.getFkUserinfo().getId());  

10.}  

 

 通过query.setParameter(int,Obejct)方法即可给每个?

赋值,注意第一个参数是从下标0开始!

 

 

 

3-1-2使用HQL “WHERE 字段=:

key”的形式给条件赋值

 

这种赋值方式是HQL特有的,什么意思呢,直接看例子分析:

Java代码  

1.Query query = baseDao.getQuery("FROM Member m WHERE m.loginCode LIKE :

code AND m.password in (:

pwd) AND m.deleteFlag=:

flag");  

2.query.setParameter("code", "kaka%");  

3.query.setParameterList("pwd", new String[]{"12345","123451","123452"});  

4.query.setParameter("flag", 0);  

5.List lstM = query.list();  

6.for (Member member :

 lstM) {  

7.    System.out.println("id:

"+member.getId()+"   fk_id:

"+member.getFkUserinfo().getId());  

8.}  

 上面例子关键代码是Query调用setParameter(String,Object)和setParameterList两个方法,前者是赋单一值,后者是赋多个值(特别适合in查询赋值)。

这两种赋值方法都需要传两参数:

第一个参数是key值,对应HQL语句中的“:

xxx”;第二个参数是value值,就对应key的实际值。

这种传值比3-1-1更准确方便:

一来不用担心下标错位的问题,二来如果存在”xx,xx,xx”这种格式的参数可以使用setParameterList方法,屡试不爽!

 

3-2-1使用SQL“WHERE 字段=?

”的形式给参数赋值

Java代码  

1.SQLQuery sql = baseDao.getSQLQuery("SELECT * FROM Member m WHERE m.login_code LIKE ?

 AND m.password in (?

?

?

) AND m.delete_flag=?

");  

2.sql.setParameter(0, "kaka%");  

3.sql.setParameter(1, "12345");  

4.sql.setParameter(2, "123451");  

5.sql.setParameter(3, "123452");  

6.sql.setParameter(4, 0);  

7.sql.addEntity(Member.class);  

8.List lstM = sql.list();  

9.for (Member member :

 lstM) {  

10.    System.out.println("id:

"+member.getId()+"   fk_id:

"+member.getFkUserinfo().getId());  

11.}  

 上面这段代码与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才能用,下面这段代码是能查询出结果的

Java代码  

1.SQLQuery sql = baseDao.getSQLQuery("SELECT * FROM Member m WHERE m.login_code LIKE :

code AND m.password in (:

pwd) AND m.delete_flag=:

flag");  

2.sql.setParameter("code", "kaka%");  

3.sql.setParameterList("pwd", new String[]{"12345","123451","123452"});  

4.sql.setParameter("flag", 0);  

5.sql.addEntity(Member.class);  

6.List lstM = sql.list();  

7.for (Member member :

 lstM) {  

8.    System.out.println("id:

"+member.getId()+"   fk_id:

"+member.getFkUserinfo().getId());  

9.}  

 

3-3使用Criteria来实现查询

其实Criteria出现的主要原因就是为了处理复杂的条件查询,开发人员在使用SQL编写复杂查询条件时很容易出错,Hibernate就提供了Criteria这样一个方便的API,开发人员用Java来写查询条件,最后由Hibernate转换成SQL去执行。

Java代码  

1.Criteria crit = baseDao.getCriteria(Member.class);  

2.crit.add(Restrictions.like("loginCode", "kaka%"));  

3.crit.add(Restrictions.in("password", new String[]{"12345","123451","123452"}));  

4.crit.add(Restrictions.eq("deleteFlag", 0));  

5.List lstM = crit.list();  

6.for (Member member :

 lstM) {  

7.    System.out.println("id:

"+member.getId()+"   fk_id:

"+member.getFkUserinfo().getId());  

8.}  

 Criteria对象通过add方法添加查询条件,Restrictions提供了各种各样的查询条件API:

like、in、eq、between、or等等。

这里要注意一点:

像Restrictions.like(key,value)这些方法的key就是POJO中的属性,而不是数据库中的字段!

 

 

4、有时候我们调用SQL时不希望查询出表的所有字段(特别是大数据量项目更要考虑),使用纯JDBC写这样的SQL就能实现,但是如果用JDBC,得到值后还要通过ResultSet.getXXX来获取对应数据,这种方式非常麻烦。

Hibernate提供了很多解决方案,使我们摆脱频繁的getXX操作。

以此为例:

我希望查询Member表的id和fk_userinfo这两个字段

4-1HQL获取指定字段推荐采用面向对象的形式来实现

什么意思呢,假设Member类有一个构造函数Member(intid,intfkId),我们通过newMember(xx,xx)赋值这样就把值放入Member中了,使用HQL也是这样的:

第一步编写Member构造函数

Java代码

1.public BaseMember(Integer id, Integer fkId) {  

2.    this.id = id;  

3.    Userinfo fkUserinfo = new Userinfo(fkId);  

4.    this.fkUserinfo = fkUserinfo;  

5.}  

 第二步编写HQL,注意看SELECT后面的写法,这种写法看起来非常像Java的newMember是吧,只要这样写,通过Query.list()返回的结果就直接存放在List中了

Java代码  

1.Query query = baseDao.getQuery("SELECT NEW com.bless.model. Member(m.id,m.fkUserinfo.id) FROM Member m");  

2.List lstM = query.list();  

3.for (Member member :

 lstM) {  

4.    System.out.println("id:

"+member.getId()+"   fk_id:

"+member.getFkUserinfo().getId());  

5.}  

 

两点说明:

①理论上在编写上面那句HQL时可以这样写的:

SELECTNEWMember(m.id,m.fkUserinfo.id)FROMMemberm(就是把Member的包名去掉),因为Member类是在Hibernate映射文件Member.hbm.xml中指定了路径的。

但是Member在HQL里面是关键字,如果不加包名执行查询的话会报如下错误:

java.lang.ClassCastException:

org.hibernate.hql.ast.tree.SqlNodecannotbecasttoorg.hibernate.hql.ast.tree.PathNode。

那么如果POJO对象不是*.hbm.xml中映射的类,则注意一定要加上POJO的全路径!

②上面HQL语句有这样一段代码“m.fkUserinfo.id”,这是一种面向对象的写法,表示m对象(Member)下的fkUserinfo属性(Userinfo)下的id,之所以这样写是因为Member表里的fk_userinfo外键关联Userinfo表的id,在编写hbm.xml时通常是将字段fk_userinfo设置成Userinfo对象方便关联自动查询,这也就是为什么在1-1例子中调用.getName()时会自动发送SQL的原因。

 

 

4-2使用SQL查询字段

在1-2中我使用setEntity将SELECt*查询出的数据直接映射到Member集合中,但是如果只查询Member表的部分字段就不能这样写了,先看下面这段可正确运行的代码:

Java代码  

1.SQLQuery sql = baseDao.getSQLQuery("SELECT m.id,m.login_code,m.fk_userinfo FROM Member m");  

2.sql.addScalar("login_code", Hibernate.STRING);  

3.sql.addScalar("id", Hibernate.INTEGER);  

4.List lstM = sql.list();  

5.for (Object[] objects :

 lstM) {  

6.    Syst

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1