方法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. Moviepy音视频开发:开发视频转gif动画或jpg图片exe图形化工具的案例

    ☞ ░ 前往老猿Python博文目录 ░ 一.引言 老猿之所以学习和研究Moviepy的使用,是因为需要一个将视频转成动画的工具,当时在网上到处搜索查找免费使用工具,结果找了很多自称免费的工具,但转完 ...

  2. 第6章 Python中的动态可执行方法 第6.1节 Python代码编译

    在介绍动态可执行方法前,本节先介绍一下Python代码编译有关的知识,因为部分内容和动态执行有些关联. 一.    Python解释器的功能 Python虽然是解释型语言,但Python代码也是可编译 ...

  3. 第14.17节 爬虫实战3: request+BeautifulSoup实现自动获取本机上网公网地址

    一. 引言 一般情况下,没有特殊要求的客户,宽带服务提供商提供的上网服务,给客户家庭宽带分配的地址都是一个宽带服务提供商的内部服务地址,真正对外访问时通过NAT进行映射到一个公网地址,如果我们想确认自 ...

  4. [BJDCTF2020]Cookie is so stable && [GWCTF 2019]枯燥的抽奖

    [BJDCTF2020]Cookie is so stable 进入环境后看到有hint,点击之后查看源代码 提示我们cookie有线索 flag页面是: 需要输入一个username,或许这道题目是 ...

  5. 自己整理了一个 Dapper的Helper助手类

    链接字符串配置: <connectionStrings> <add name="db" connectionString="server=.;datab ...

  6. Scrum 冲刺 第四篇

    Scrum 冲刺 第四篇 每日会议照片 昨天已完成工作 队员 昨日完成任务 黄梓浩 初步完成app项目架构搭建 黄清山 完成部分个人界面模块数据库的接口 邓富荣 完成部分后台首页模块数据库的接口 钟俊 ...

  7. js 彻底搞懂事件循环机制 Event Loop

    我们都知道javascript是单线程语言,就是因为单线程的特性,就不得不提js中的同步和异步 一.同步和异步 所谓单线程,无非就是同步队列和异步队列,js代码是自上向下执行的,在主线程中立即执行的就 ...

  8. jsonp使用post方法

    来源https://www.jb51.net/article/68980.htm

  9. 微信小程序-卡券开发(前端)

    刚完成一个微信小程序卡券开发的项目.下面记录开发前,自己困惑的几个问题. 因为我只负责了前端.所以下面主要是前端的工作. 项目概述:按照设计图开发好首页上的优惠券列表,点击某个优惠券,输入手机号,点击 ...

  10. 看图知Docker

    0.https://www.docker.com/ 1.Why Docker 可参考: https://www.cnblogs.com/kex1n/p/6933039.html https://www ...