Hibernate使用原生SQL查询

  Hibernate提供了原生的SQL语句的查询,通过createSQLQuery(String)和createNativeQuery(String),createSQLQuery(String)是Hibernate5.x之前的版本的,在Hibernate5.x和之后,都采用的是createNativeQuery(String),使用原生SQL虽然麻烦,但是一些复杂的查询明显可以使用原生SQL更加方便实现各种复杂的关联查询,这里主要记录一下原生SQL查询在开发中经常使用到的一些用法。主要参考了官方的文档:https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#sql

准备

  使用的Hibenate版本为5.4的;这里使用的数据库是MySQL,测试的数据库时sakila数据库,数据库初始化脚本: https://download.csdn.net/download/strive_or_die/11928949 ,如果需要但是没有积分,也可以在评论区留下邮箱号,看到了会直接发送到邮箱。。

普通的查询

  Hibernate会通过ResultSetMetadata来判断每个字段值的存放位置以及类型,返回一个Object[]类型的数组,其实这种结果集应用场景并不广,所以实际开发中使用起来也不方便。

//查询所有的列
List<Object[]> objList = session.createNativeQuery("select * from actor").list()
//查询指定的列
List<Object[]> list = session.createNativeQuery("select actor_id as actorId,first_name as firstName  from actor").setFirstResult(0).setMaxResults(5).list();

查询结果转为Map

  使用setResultTransformer转为Map,一般转为了Map比上面的方式要好很多了,可以通过一些反射进行转为对象。如下所示:

List<Map> mapList = session.createNativeQuery("select actor_id as actorId,first_name as firstName from actor").unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).setFirstResult(0).setMaxResults(5).list();

查询结果转为Bean对象

  使用setResultTransformer转为指定对象,如果会报Hibernate的类型和实体类的类型不匹配的错误,则需要使用addScalar指定结果列的Hibernate类型,使得两者类型匹配;例如下例中,Hibernate查出来的actorId是Short,而Entity中定义了为Integer,执行则会报错,所以添加了addScalar("actorId",IntegerType.INSTANCE)将Hibernate的类型修改为Integer

List<Actor> actors = session.createNativeQuery("select actor_id as actorId,first_name as firstName from actor").addScalar("actorId",IntegerType.INSTANCE).unwrap(NativeQueryImpl.class)//将查询结果列转为指定的对象,可以是实体类,也可以是非实体类例如VO和DTO.setResultTransformer(Transformers.aliasToBean(Actor.class)).setFirstResult(0).setMaxResults(5).list();

标量查询

  标量查询主要用于指定查询语句返回哪些字段的值,例如下列的select * from actor通过标量查询,进行指定结果列,这样就不会将所有结果列都查询出来,只查询我们需要的结果列。

 List<Object[]> listB = session.createNativeQuery("select *  from actor").addScalar("actor_id").addScalar("first_name").setFirstResult(0).setMaxResults(5).list();

转为实体对象

a.返回一个实体对象

  这种通过addEntity的查询方式,可以将结果查询转为指定的实体类,但是有个点需要特别注意,**如果使用了实体对象,那么在查询时要将实体对象中有的属性全部在SQL语句中查询出来,否则就会报错。**报的错误如:SQLException: Column 'actor_id' not found

 List<Actor> actorList  = session.createNativeQuery("select actor_id,first_name ,last_name,last_update from actor").addEntity("com.hibernate.learn.po.Actor").setFirstResult(0).setMaxResults(5).list();

b.返回多个实体对象

  通过addEntity指定别名和实体类,添加多个Entity,查询多个实体类结果。例如下列所示:

String multiEntitySQL = "select ac.*,fi.* from actor ac " +"inner join film_actor fa on ac.actor_id = fa.actor_id " +"inner join  film fi on fi.film_id = fa.actor_id";
List<Object[]> multiList =  session.createSQLQuery(multiEntitySQL).addEntity("ac",Actor.class).addEntity("fi", Film.class).setFirstResult(0).setMaxResults(5).list();
//多个实体,按照addEntity的顺序排列
for (Object[] multiEntity : multiList){System.out.println("actor :"+ ((Actor)multiEntity[0]));System.out.println("film :"+ ((Film)multiEntity[1]));
}

  当使用连接查询查询多个对象时,可以通过addEntity("xxx", XXX.class)方法来根据数据库表的别名来引入多个实体类,这时如果需要将查询出来的所有的对象分别存入实体类中,只需要在查询出来的对象上添加{}号即可,此时就会自动分类,{}这种方式主要用于返回多个实体对象,而且实体对象的列名可能存在相同的,那么就需要使用{},这样Hibernate就可以区分了。例如上面语句可以改为如下所示:

String multiEntitySQL = "select {ac.*},{fi.*} from actor ac " +"inner join film_actor fa on ac.actor_id = fa.actor_id " +"inner join  film fi on fi.film_id = fa.actor_id";
List<Object[]> multiList =  session.createSQLQuery(multiEntitySQL).addEntity("ac",Actor.class).addEntity("fi", Film.class).setFirstResult(0).setMaxResults(5).list();
//多个实体,按照addEntity的顺序排列
for (Object[] multiEntity : multiList){System.out.println("actor :"+ ((Actor)multiEntity[0]));System.out.println("film :"+ ((Film)multiEntity[1]));
}

总结

  一般来说,Hibernate提供的原生SQL查询的方式,常用的就是这些了,很多使用我们使用的都是将查询结果转为实体对象,这个可以通过addEntity方式实现,还有将连接查询的结果列转为VO或者DTO,这个可以通过setResultTransformer(Transformers.aliasToBean(XXX.class))实现,对于查询结果为Object[]数组的是在是不方便处理。更多的实现可以参考Hibernate的官方文档:https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#sql

Hibernate使用原生SQL查询相关推荐

  1. hibernate的native sql查询

    在我们的hibernate中,除了我们常用的HQL查询以外,还非常好的支持了原生的SQL查询,那么我们既然使用了hibernate,为什么不都采用hibernate推荐的HQL查询语句呢?这是因为HQ ...

  2. Hibernate原生SQL查询

    最近在做一个较为复杂的查询,hibernate基本的查询不能满足,只好使用其提供的原生sql查询.参考网上的一些资料,做一些总结. 对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行 ...

  3. Hibernate使用原生SQL语句(left join左连接查询)

    Hibernate使用原生SQL语句 以下是本人对Hibernate使用原生SQL语句的理解: 在项目开发当中使用Hibernate提供的HQL有时候不能满足需求,尤其是多表查询或者是多表中没创建主外 ...

  4. Hibernate5.2之原生SQL查询

    原文:http://www.cnblogs.com/miller-zou/p/5720048.html 一. 介绍  在上一篇博客中笔者通过代码的形式给各位读者介绍了Hibernate中最重要的检索方 ...

  5. jpa 原生sql 查询返回一个实体_JPA查询--使用原生sql 并且把查询结果转为实体对象...

    这篇文章主要记录 使用原生sql查询 并且把查询结果转为实体对象, 注意:这儿使用的数据库 是oracle数据库 这儿记录了三种查询:精确查询,模糊查询,分页查询. 1.把原生sql查询的结果转为实体 ...

  6. Hibernate对原生sql处理及结果集和VO的映射

    昨天解决一个看似很简单的需求, 我有一个类似下面的table(info_table),是收集产品使用的机型信息: id type model 1 nokia xxx1 2 nokia xxx2 3 M ...

  7. 【Flask项目】sqlalchemy原生sql查询,返回字典形式数据

    在原生sql查询的时候,返回一个list,内部是tuple,他们看似是tuple,实则并不是 而是一个特殊的类型"<class 'sqlalchemy.util._collection ...

  8. python graphql query返回一组字典数据_Python的sqlalchemy使用原生sql查询如何返回字典形式的数组?...

    首先使用一个变量接收你以上的查询结果.这个查询结果是一个list,在这个list中包含着一个或多个tuple,其实这并不是标准的Python tuple,而是一个特殊的类型"",这 ...

  9. hibernate将本地SQL查询结果封装成对象

    hibernate将本地SQL查询结果封装成对象 不知道大家有没有碰过这种情况,迫于很多情况只能用native SQL来查询(如:复杂统计等),然而使用native查询后,结果会被放到object里, ...

最新文章

  1. android 调用手机震动
  2. 连接远程数据库ORACLE11g,错误百出!
  3. 提升网站竞争力从这三方面着手努力!
  4. 【错误记录】编译 Android 版本的 ijkplayer 报错 ( You must define ANDROID_NDK before starting. | 下载指定版本 NDK )
  5. Linux 浏览网址汇集
  6. Y2011_M12_HeartChicken
  7. salt 文件push使用方法
  8. 一个JAVA WEB伪全栈的VUE入坑随笔,从零点零五学起
  9. Pytorch tensor基础知识
  10. JDK 运行参数 JAVA -Dxxx与System.setProperty()的关系
  11. “油猴脚本”获取百度云文件URL,百度云速度破解
  12. User Agreement(APP用户协议)
  13. 某云安全扫描对SQL Server潜入的观察日记
  14. 这款开源工具绝了!!!
  15. 高斯分布的性质(含代码)
  16. C++小实验之vector的 push_back 和 emplace_back 及其使用时机
  17. 微型计算机系统的发展历史,计算机的系统发展历史
  18. 中信国健临床通讯  2011年2月第1期
  19. 00 后程序员就要为“你”加班?呵呵
  20. 项目管理习题——挣钱分析法与成本预算和成本估算

热门文章

  1. php上传文件失败解决方案
  2. 黑鲨Android系统耗电高,已达安卓顶配,黑鲨2pro作为主力机,聊聊使用感受
  3. CSS系列之浮动详解
  4. 查询mysql并转成json_将数据库SQL查询结果直接转为JSON
  5. 蛋壳梦破:CEO被限制消费,资金链碎了一地
  6. Python——通过while、for、if—else完成一个地铁乘车消费计算器
  7. 学习Java编程入门书籍
  8. 数据库完整性--断言和触发器
  9. 工程师软技能~聊聊价值,价值观和价值积累
  10. 防止暴利破解,拒绝ip登陆