方法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.27节 Python中__getattribute__与property的fget、@property装饰器getter关系深入解析

    一. 引言 在<第7.23节 Python使用property函数定义属性简化属性访问的代码实现>和<第7.26节 Python中的@property装饰器定义属性访问方法gette ...

  2. Python基础篇学习感悟:学如不及,犹恐失之

    从2019年3月底开始学习Python,4月12日在CSDN发表第一篇博文,时至今日已有4个月零12天. 4个多月的学习,老猿从一个Python小白成长到今天,可以说对Python这门语言已经略知一二 ...

  3. 建立windows认证模式下的用户登录

    第一步:点击控制面板-----管理工具------计算机管理 ,在操作系统的计算机管理界面下,展开本地用户和组,在用户下建立三个用户u1,u2,u3,密码与用户名相同,如图所示. 然后新建一个组叫QQ ...

  4. [BJDCTF 2nd]Schrödinger && [BJDCTF2020]ZJCTF,不过如此

    [BJDCTF 2nd]Schrödinger 点进题目之后是一堆英文,英语不好就不配打CTF了吗(流泪) 复制这一堆英文去谷歌翻译的时候发现隐藏文字 移除test.php文件,访问test.php ...

  5. 你必须掌握的关于JVM知识点

    对本文所持态度 抓住主要矛盾,抓住重点学习,然后从这些点展开学. 不管是面试别人,还是参加面试.都可以有收获. JDK体系结构与JVM架构解析 jdk jre javac jvm Java是怎么实现跨 ...

  6. C# operator 关键字的用法

    operator 只要是运算符都能重载 operator 关键字的主要作用是用来重载运算符的,还可以用于类或结构中类型的自定义转换. 下面看个例子 class Feige { //定义两个全局变量 i ...

  7. NameSilo的DDNS动态域名解析

    用Java写的,一个实时检测IP变化并更新DNS状态的工具,适用于在NameSilo购买的域名,如果你的域名是在其他商家购买的,修改为你自己的api就行.代码我放github了,地址: https:/ ...

  8. js日期格式化-----总结

    1. // 对Date的扩展,将 Date 转化为指定格式的String // 月(M).日(d).小时(h).分(m).秒(s).季度(q) 可以用 1-2 个占位符, // 年(y)可以用 1-4 ...

  9. Java8的StreamAPI常用方法总结

    目录 什么是Stream? Stream的创建 测试API 新建测试数据 findFirst.findAny anyMatch.noneMatch filter max.count peek.map ...

  10. pyhon 自动化 logger

    #!/Users/windows8.1/PycharmProjects/pythonapi# @Software: PyCharm Community Edition# -*- coding: utf ...