方法1:

 1 StringBuffer sb = new StringBuffer(300);
2 sb.append("SELECT v.id, v.container_number, v.error_feedback,v.is_handled,v.job_type,v.remark,v.vessel_voyage_number,");
3 sb.append("e.error_code,e.error_description");
4 sb.append(" FROM vessel_container_error v");
5 sb.append(" JOIN error e ON e.error_id = v.error_id");
6 sb.append(" where v.vessel_voyage_number = '").append(vesselVoyageNumber).append("' and v.container_number = '").append(containerNumber).append("'");
7 sb.append(" and v.job_type = '").append(jobType).append("' and is_handled = 0");
8
9 List<Object[]> re = this.vesselContainerErrorRespository.listBySQL(sb.toString());
10 List<VesselContainerErrorsBean> list = new ArrayList<>();
11 re.forEach(
12 objects -> {
13 VesselContainerErrorsBean errorsBean = new VesselContainerErrorsBean();
14 errorsBean.setId(objects[0] == null ? 0 : (int) objects[0]);
15 errorsBean.setContainerNumber(objects[1] == null ? "" : objects[1].toString());
16 errorsBean.setErrorFeedback(objects[2] == null ? "" : objects[2].toString());
17 errorsBean.setHandled(objects[3] == null ? false : (Boolean) objects[3]);
18 errorsBean.setJobType(objects[4] == null ? "" : objects[4].toString());
19 errorsBean.setRemark(objects[5] == null ? "" : objects[5].toString());
20 errorsBean.setVesselVoyageNumber(objects[6] == null ? "" : objects[6].toString());
21 errorsBean.setErrorCode(objects[7] == null ? "" : objects[7].toString());
22 errorsBean.setErrorDescription(objects[8] == null ? "" : objects[8].toString());
23 list.add(errorsBean);
24 }
25 );

优点:

1. 原生Sql , 可以使用数据库自带的方法

2. 适应不定查询条件数量的情况

缺点:

1. 读出来的是 List<Ojbect[]> , 数据转换时要人工对数组下标,判 null

方法2:

 1 StringBuilder countSelectSql = new StringBuilder(300);
2 countSelectSql.append("select count(*) ");
3
4 StringBuilder selectSql = new StringBuilder(500);
5 selectSql.append("select new net.pingfang.yard.core.domain.bo.JobPlanAndInsAndEquBO(");
6 selectSql.append("i.id,i.containerNumber,i.isoCode,i.originalPositionType,i.originalPositionValue,");
7 selectSql.append("i.targetPositionType,i.targetPositionId,i.targetPositionValue,i.instructionStatusCode,i.planStart,i.actualStart,i.createBy,i.equipmentId,");
8 selectSql.append("j.jobPlanCode,j.jobTypeCode)");
9
10 StringBuilder fromSql = new StringBuilder(250);
11 fromSql.append(" from InstructionEntity i join JobPlanEntity j on i.jobPlanId = j.id");
12
13 StringBuilder whereSql = new StringBuilder();
14 whereSql.append(" where j.jobPlanCode = :jobPlanCode");
15
16 Map<String, Object> params = new HashMap<>();
17 params.put("jobPlanCode", jobPlanCode);
18
19 if (!StringUtils.isEmpty(containerNumber)) {
20 whereSql.append(" and i.containerNumber = :containerNumber");
21 params.put("containerNumber", containerNumber);
22 }
23 if (!StringUtils.isEmpty(equipmentCode)) {
24 fromSql.append(" join EquipmentEntity e on i.equipmentId = e.id");
25 whereSql.append(" and e.equipmentCode = :equipmentCode");
26 params.put("equipmentCode", equipmentCode);
27 }
28 if (null != instructionStatusCode && !instructionStatusCode.isEmpty()) {
29 whereSql.append(" and i.instructionStatusCode in :instructionStatusCode");
30 params.put("instructionStatusCode", instructionStatusCode);
31 }
32
33 int total = this.getTotalByHql(countSelectSql.append(fromSql).append(whereSql).toString(), params);
34 PageBean page = new PageBean(total, pageNumber, pageSize);
35 if (total > 0) {
36 List<JobPlanAndInsAndEquBO> result = this.searchByHql(selectSql.append(fromSql).append(whereSql).toString(), JobPlanAndInsAndEquBO.class, params, pageNumber, pageSize);
37 page.setContent(result.stream().map(this::toJobPlanAndInsAndEquDTO).collect(Collectors.toList()));
38 }

优点:

1. Hql, 没有使用 JPA  , 而是使用了 EntityManager

2. 适应不定查询条件数量的情况

3. 解决了方法1的缺点

缺点:

1. 解决了方法1 中 List<Ojbect[]> 的问题,但也产生了一个要注意的地方,select 后面使用了一个 POJO 把从数据库读出来的属性包起来了

  1.1 POJO里面构造函数的参数的顺序与从数据库读出来的属性的顺序要一一对应

  1.2 select 后面的 POJO 要写全路径

方法3:

1 @Query(value = "select i.targetPositionId as wagonId,sum(c.containerSize) as containerSize" +
2 " from InstructionEntity i join ContainerDetailEntity c on i.containerId = c.id" +
3 " where i.instructionStatusCode <> 'done' and i.targetPositionType = 'train' and i.targetPositionId = ?1" +
4 " group by i.targetPositionId")
5 ContainersInWagonInterface findInstructionByWagonId(int wagonId);
1 public interface ContainersInWagonInterface extends ContainersInterface {
2
3 Integer getWagonId();
4 String getWagonNumber();
5 }

优点:

1. 这种方法返回是个接口,也可以是接口的列表,属性的顺序不要求与接口中的属性顺序一致

缺点:

1. hql 语句 select 后面的属性必须使用别名且与接口里的方法名一致

2. hql 读出来的属性可能为 null , 使用时要 判 null

3. 适用于查询条件数量固定的情况 , 条件数量不固定推荐使用 方法2

方法1是我以前常用的方法,方法2和方法3 是最近用到的,个人感觉比方法1好多,这里作个记录。当然 JPA 自带其它方法可以解决 sql 级联查询的问题,如标签 @onetomany 、@manytomany 。若不需要级联查询,用 JPA提供的方法就足够了。

Spring boot JPA读取数据库方法的更多相关文章

  1. # spring boot + mybatis 读取数据库

    spring boot + mybatis 读取数据库 创建数据库 use testdb; drop table if exists t_city; create table t_city( id i ...

  2. Spring Boot+Jpa(MYSQL)做一个登陆注册系统(前后端数据库一站式编程)

    Spring Boot最好的学习方法就是实战训练,今天我们用很短的时间启动我们第一个Spring Boot应用,并且连接我们的MySQL数据库. 我将假设读者为几乎零基础,在实战讲解中会渗透Sprin ...

  3. Spring Boot + JPA(hibernate 5) 开发时,数据库表名大小写问题

      (转载)Spring Boot + JPA(hibernate 5) 开发时,数据库表名大小写问题   这几天在用spring boot开发项目, 在开发的过程中遇到一个问题hibernate在执 ...

  4. Spring boot Jpa添加对象字段使用数据库默认值

    Spring boot Jpa添加对象字段使用数据库默认值 jpa做持久层框架,项目中数据库字段有默认值和非空约束,这样在保存对象是必须保存一个完整的对象,但在开发中我们往往只是先保存部分特殊的字段其 ...

  5. spring cloud spring boot JPA 克隆对象修改属性后 无法正常的执行save方法进行保存或者更新

    2019-12-1220:34:58 spring cloud spring boot JPA 克隆对象修改属性后 无法正常的执行save方法进行保存或者更新 未解决

  6. Spring Boot JPA 连接数据库

    本文将介绍怎样在Spring Boot project中加入JPA作为持久化方式. 改动 pom.xml 依赖 与上一篇介绍的 jdbc 不同的是 spring-boot-starter-jdbc 改 ...

  7. Spring Boot JPA 中transaction的使用

    文章目录 @Transactional的实现 @Transactional的使用 Transaction的传播级别 REQUIRED SUPPORTS MANDATORY NEVER NOT_SUPP ...

  8. Spring Boot实战之数据库操作

    上篇文章中已经通过一个简单的HelloWorld程序讲解了Spring boot的基本原理和使用.本文主要讲解如何通过spring boot来访问数据库,本文会演示三种方式来访问数据库,第一种是Jdb ...

  9. Spring Boot(二):数据库操作

    本文主要讲解如何通过spring boot来访问数据库,本文会演示三种方式来访问数据库,第一种是JdbcTemplate,第二种是JPA,第三种是Mybatis.之前已经提到过,本系列会以一个博客系统 ...

随机推荐

  1. 第8.14节 Python类中内置方法__str__详解

    一. object类内置方法__str__和函数str 类的内置方法__str__和内置函数str实际上实现的是同一功能,实际上str调用的就是__str__方法,只是调用方式不同,二者的调用语法如下 ...

  2. Asp.NetCore之AutoMapper进阶篇

    应用场景 在上一篇文章--Asp.NetCore之AutoMapper基础篇中我们简单介绍了一些AutoMapper的基础用法以及如何在.NetCore中实现快速开发.我相信用过AutoMapper实 ...

  3. 自搭建jetbrains系列ide授权服务器

    1.下载 LicenseServer 地址:https://mega.nz/#!7B5UVY6b!Hae2ceTBPIrTowQN0sV9fQ5lGOKzGxas2ug02RZAdGU,里面有不同的服 ...

  4. 【Tomcat 源码系列】源码构建 Tomcat

    一,前言 这篇博客写于 12 月 12 日,从 github[1] 上 fork 了一份 tomcat 的源代码,clone 到了本地.最近想把 tomcat 的源代码分析一下,寒假的时候有完整的时间 ...

  5. 使用uniapp开发项目来的几点心得体会,供新手参考参考

    先说一下提前须要会的技术 要想快速入手uniapp的话,你最好提前学会vue.微信小程序开发,因为它几乎就是这两个东西的结合体,不然,你就只有慢慢研究吧. 为什么要选择uniapp??? 开发多个平台 ...

  6. Vue-router hash模式微信登录授权验证,#号处理

    微信授权登录验证会把网址中的#号去掉,这样在跳转的时候Vue拿不到Code.所以做了以下处理 let href = window.location.href; if (href.includes(&q ...

  7. VMware提示Device/Credential Guard不兼容

    问题环境 win10系统版本 win10 2004企业版 vmware 版本 vmware 15 pro 问题 虚拟机开启时候弹窗提示:"VMware与Device/Credential G ...

  8. css进阶 01-CSS中的非布局样式

    01-CSS中的非布局样式 #前言 CSS中,有很多非布局样式,这些样式(属性)和与布局无关,包括: 字体.字重.颜色.大小.行高 背景.边框 滚动.换行 装饰性属性(粗体.斜体.下划线)等. 这篇文 ...

  9. js上 初识JavaScript

    1.JavaScript简介 **JavaScript ** 是什么?(重点) Js是一种专门为网页交互设计的客户端(浏览器端)的脚本语言: Js与html和css有相似之处,都在浏览器端解析: Js ...

  10. vue第十五单元(熟练使用vue-router插件)

    第十五单元(熟练使用vue-router插件) #课程目标 1.掌握路由嵌套 2.掌握导航守卫 #知识点 #一.路由嵌套 很多时候,我们会在一个视口中实现局部页面的切换.这时候就需要到了嵌套路由. 也 ...