JPA自定义原生SQL语句的查询结果如何转化为对象,三种方法

最近的感悟(多为废话,只为解决问题而来的可以从有代码的地方看)

  1. 这半年太忙了,好久没写博客了。写久了PHP项目,忽然想拾一拾JAVA项目,因为JAVA的消息队列、日志、分布式方案比较多,可以自己实现的功能比较多,具有比较高的性能,稳定性好,而且考虑到JAVA的开源中间件比较丰富,大数据生态多是JAVA的,适合搞大型项目,于是最近的项目后端采用了 Spring boot + JPA + Redis + MySQL,前端使用 Vue + Element + WebPack。
  2. Spring boot 的优点缺点不用我赘述,想必你在开始些项目之前已经深思熟虑了,不过对于我这样的非资深JAVA开发者,看日志DEBUG还真是困难,几十上百行的错误轨迹,看不到一个自己写过的文件,多次DEBUG到半夜【怎么解决?】。
  3. Spring boot热加载热部署,似乎不那么灵活,我用Spring boot + Vue开发一个商城,耗的时间是 PHP + Vue的两倍,当然都是前后端完全分离的项目,都使用Redis缓存,还是PHP敏捷,PHP再也不是PHP5.3之前那个设计糟糕的语言了,也不难理解为什么PHP会比Java Web份额大。
  4. 我用PHP开发的项目,到后期维护挺困难,因为自己当初急于求成没有按照一个好的规范进行,而JAVA的代码开发过程,比PHP的严格,不够灵活,但是严谨,如果能够用着PHP的灵活,并且代码规范起来,项目也会比较好维护和二次开发【具体怎么做?】。
  5. 如果再开发下一个JAVA项目,而且时间不紧急,我会选择目前更为流行的MyBatis而不是Hibernate【不为什么,喜新厌旧】。
  6. 技术五花八门,好多还没学会就过时了,身边用Nodejs做全栈的,用Python做全栈开发都有(我舍友、学妹都在用Python开发,帮忙解决问题,也算对Django不陌生了,另外 odoo这个开源Python ERP功能很丰富,值得学习),我研二的师兄在学习Go,技术辣么多,感觉是时候停下脚步,寻求更本质的东西了【编译原理,语言学,算法,设计范式,软件工程…】。
  7. 造轮子并不困那,造轮子也挺快乐,虽然有时会发现挺困难,但是总比搞不懂一个别人的牛逼轮子时舒服,那感觉就像”菜到给人抠脚都不配“,最佩服的就是那些用C语言开发出来的造福世界的开源项目,想有空了好好研究研究Redis、Nginx源码【 也许永远只是个flag】。
  8. 因为一直以来没有学C++,没用过C#,用Qt用的很不顺手, 对于客户端软件开发,总是找一些旁门左道,比如用java来做windows客户端.exe程序,后来熟悉了前端开发,遇到做客户端的需求想着程序中嵌入浏览器,浏览器展示界面从而实现有界面的客户端,找框架,最初接触有道开源的heX项目,一个把chromeium打包起来,页面本地化的客户端解决方案,后来了解到360卫士,QQ的界面也是html,然后是CEF(Chromium Embedded Framework),后来找到基于Electron/Cordova做跨一切平台客户端的方案。后来,发现开始流行起来VSCODE 就是一个Electron项目,后来发现电脑上的Docker的Kitematic界面、Tremius、Wordpress客户端、Typroa、幕布客户端、微信开发者工具、之前见到的一个arduino项目的PC端,Electron/Cordova开发出来的优秀项目越来越多

是什么让我选择了JPA

  1. JPA是一种规范,Hibernate是一种JPA规范的实现,感兴趣可以移步阅读此篇文章
  2. 定义Repository之后,几乎所有的单表非聚合操作,只需要写个函数名称就完成了,自动根据定义的函数名称完成查询。
  3. 使用MapStruct也可以很容易完成多对一,对对多,一对多查询,只需要简单定义一下,加个注解就能搞定,比当初学习Spring MVC时写大量的配置文件舒坦多了。
  4. Hibernate性能好,三级缓存,支持的数据库比较多(数据库无关性好),DAO层如上文所说,非常省代码量,另外Hibernate框架也比较成熟,对数据一致性维护比较好。
  5. 相比之下,MyBatis更为轻量,入门简单,学习门槛低,自己书写SQL语句方便,SQL自己写的调优容易,我选择Hibernate主要是因为想偶尔换一换口味,找到相同问题,不一样的解决方案,拓宽视野。
  6. Hibernate灵活性弱,数据库无关性好,用的合理了可以不依赖某个具体的SQL数据库,弊端是对原生SQL语句支持的不友好,对于熟练掌握SQL的人来说,反而比较抓狂。

使用Spring boot + JPA + Hibernate开发项目遇到的问题

  1. MapStruct并不那么好配置,我总是不得要领,屡试屡败?,MapStruct教程
  2. 想要自己写个SQL查询来实现很复杂的查询,如六七个表的多表查询,自己可以轻易地在SQL层面做好优化,如果用MapStruct恐怕会炸掉,但是会发现JPA对原生SQL查询非常不友好。
  3. 对原生SQL支持不友好体现在:
  • 如果希望定义好一个DTO或者Java Bean来接收查询结果,第一种方法需要按照查询结果字段的顺序来给Bean赋值,第二种方法不是原生SQL,是一种嵌入Java对象的SQL语句,具体实现可参考Spring Data Jpa框架自定义查询语句返回自定义实体的解决方案。
  • 如果不喜欢上述方法,可以定义有getXXXX方法的接口来接收原生SQL的结果(SQL语句中的字段和接口中的get方法的匹配遵循驼峰命名),如下例:
    接口如下:

public interface DateDbCount {
   /*
    SELECT dict_detail.label as dbType,
    date_format(data_set.create_time ,'%Y-%m-%d' ) as date,
    count(1) as value
    FROM data_set left join `dict_detail`  on dict_detail.value = data_set.type WHERE dict_detail.dict_id=6 GROUP by date_format(data_set.create_time ,'%Y-%m-%d' ),dict_detail.value

    */
   String getDbType();
   String getDate();
   Integer getValue();
}

JpaRepository这样写:


@Query(value="SELECT dict_detail.label as dbType, date_format(data_set.create_time ,'%Y-%m-%d' ) as date, count(1) as value FROM data_set left join `dict_detail`  on dict_detail.value = data_set.type WHERE dict_detail.dict_id=6 GROUP by date_format(data_set.create_time ,'%Y-%m-%d' ),dict_detail.value order by date ASC",nativeQuery = true)
    List<DateDbCount>  getDateDbCount();
    

写到这里,虽然气愤JPA + Hibernate的不够灵活,但是细想一下,不得不赞叹他的严谨性和对数据库一致性的严格维护。


2019年5月记录:
目前实现了的PDO接口的数据库 (可以理解为PHP语言中的’JDBC’):

目前实现了 PDO 接口:
支持的数据库
Cubrid    
FreeTDS / Microsoft SQL Server / Sybase    
Firebird/Interbase 6    
IBM DB2    
IBM Informix Dynamic Server    
MySQL 3.x/4.x/5.x    
Oracle Call Interface    
ODBC v3 (IBM DB2, unixODBC and win32 ODBC)    
PostgreSQL    
SQLite 3 及 SQLite 2    
Microsoft SQL Server / SQL Azure    
4D

目前实现了JDBC接口的数据库:
https://docs.oracle.com/cd/E19226-01/821-1340/gawms/
JPA自定义原生SQL语句的查询结果如何转化为对象,三种方法_第1张图片

你可能感兴趣的:(java,网站,项目经验)