目标:查询数据库中的字段,然后转换成 JSON 格式的数据,返回前台。

环境:idea 2016.3.4, jdk 1.8, mysql 5.6, spring-boot 1.5.2 
背景:首先建立 entity 映射数据库(非专业 java 不知道这怎么说)

@Entity
@Table(name = "user")
public class User {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private String userName;    // 账号private String password;    // 密码// getter setter 方法略过
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

然后建立与之对应的 model

public class UserModel implements Serializable {// 一些属性
}
  • 1
  • 2
  • 3

这里我们分情况讨论

首先第一种情况:查询的字段与表中的字段全部对应(就是查表里所有的字段,但是使用 Model 作为接收对象)

这种情况比较简单,调用 Repository 提供的方法,返回一个 entity , 然后将 entity 的属性复制到 model 中。像这样

UserModel user = new UserModel();
User userEntity = new User();
// 一个工具类,具体使用方法请百度
BeanUtils.copyProperties(user, userEntity);
  • 1
  • 2
  • 3
  • 4

第二种情况:只查询指定的几个字段

现在我有张表,有字段如下:

@Entity
@Table(name = "user_info")
public class UserInfo {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private String name = "用户";     // 昵称private String signature;         // 个性签名private String gender = "未知";   // 性别private String description;       // 个人说明private String avatar;            // 头像private Long role;                // 权限private Boolean disable;          // 是否冻结private Date createTime;          // 创建时间private Boolean isDelete;         // 是否删除private Long userId;              // 用户 Id// ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

但是我只需要查询指定的几个字段,然后转换成 JSON,返回给前台,咋办呢?

第一种方法:使用 model 查询时转化

首先建立一个 model ,写上自己想要查询的字段,然后写上构造函数,这步很重要,因为spring jpa 转化时会调用这个构造方法

public class MyModel implements Serializable {private String userName;private String name;private String gender;private String description;public MyModel() {};public MyModel(String userName, String name, String gender, String description) {this.userName = userName;this.name = name;this.gender = gender;this.description = description;}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

然后在 dao 类中写查询方法

@Query(value = "select new pers.zhuch.model.MyModel(u.userName, ui.name, ui.gender, ui.description) from UserInfo ui, User u where u.id = ui.userId")
public List<MyModel> getAllRecord();
  • 1
  • 2

直接在查询语句中 new model 框架底层会调用它,然后返回这个对象(这里我写了完整的类路径,不写的时候它报错说找不到类型什么的)

然后就可以获得只有指定字段的 model 了。然后就把它转成 JSON 格式就 O 了。

第二种方法:在service 里边转换成 JSON

原理其实和第一种方法差不多,只是处理结果的方式不太一样,只是这种方法我们就不在 hql 中 new Model 了,直接写查询方法

@Query(value = "select new map(u.userName, ui.name, ui.gender, ui.description) from UserInfo ui, User u where u.id = ui.userId")
public List<Map<String, Object>> getCustomField();
  • 1
  • 2

直接new map(这里得是小写,不知道大写有木有问题,反正没试,编译器提示是要小写的) 
然后返回的结果是这样的

[{"0": "admin", "1": "你猜", "2": "男", "3": "一段描述"}, {"0": "abc", "1": "你猜人家", "2": "女", "3": "没事先挂了"}
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

然后在 service 层里直接封装成 JSON 对象,返回

List<JsonObject> list = new ArrayList();
for(Map map : result) {JsonObject j = new JsonObject();j.addProperty(attrName, val);...list.add(j);
}
gson.toJson(list);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

还有一种返回结果,这样写:

@Query(value = "select u.userName, ui.name, ui.gender, ui.description from UserInfo ui, User u where u.id = ui.userId")
public List<Object> getCustomField();
  • 1
  • 2

返回结果是这样的格式:

[["admin", "你猜", "男", "一段描述"], ["abc", "你猜人家", "女", "没事先挂了"]
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

返回的是数组,也一样可以通过上面的方法转成 json ,这里我的程序中出现了一点点 BUG,就是空值的字段不会在数组中,不知道为什么。

这种方法必须明确的知道查询了哪些字段,灵活性比较差,虽然它解决了手头的问题。还有就是版本的不同,有可能会出现丢失空字段的情况,我个人特别的不喜欢这样的方法,万一我实体几十个字段,写着写着忘了写到哪了,就 over 了

第三种方法:返回一个便于转换成 json 格式的 list

其实和上面很相似,都是 dao 层返回一个 List < Map < String, Object >>,但是上面的结果集返回的 Map 的 key 只是列的下标,这种方式稍微理想一点点,就是 Map 的 key 就是查询的列名。但是这种方式需要实现自定义 Repository( 这里不详细介绍,请自行百度 ),并且只是 jpa 集成 hibenate 的时候可以使用。

public List getCustomEntity() {String sql = "select t.id, t.name, t.gender, t.is_delete, t.create_time, t.description from t_entity t";Query query = em.createNativeQuery(sql);// Query 接口是 spring-data-jpa 的接口,而 SQLQuery 接口是 hibenate 的接口,这里的做法就是先转成 hibenate 的查询接口对象,然后设置结果转换器query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);return query.getResultList();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这种方法返回的就是比较标准的 JSON 格式的 java 对象了,只需要用 jackson 或者 Gson 转一下就是标准的 json 了

[{attr: val,...},{attr: val,...},
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这种方式其实已经比较理想了,因为直接就能返回到前台,但是有时候,结果不是一条 sql 能够解决的,得两条或者以上的 sql 来解决一个复杂的查询需求,这个过程中,结果比较需要转换成 pojo,以便于组装操作。

第四种方案:dao 中直接转成 pojo 返回

这个方案还是依赖于 hibenate,有点操蛋,但是更明确一些。

public List getCustomEntity() {String sql = "select t.id, t.name, t.gender, t.is_delete as isEnable, t.create_time as createTime, t.description from t_entity t";Query query = em.createNativeQuery(sql);query.unwrap(SQLQuery.class)// 这里是设置字段的数据类型,有几点注意,首先这里的字段名要和目标实体的字段名相同,然后 sql 语句中的名称(别名)得与实体的相同.addScalar("id", StandardBasicTypes.LONG).addScalar("name", StandardBasicTypes.STRING).addScalar("gender", StandardBasicTypes.STRING).addScalar("isEnable", StandardBasicTypes.BOOLEAN).addScalar("createTime", StandardBasicTypes.STRING).addScalar("description", StandardBasicTypes.STRING).setResultTransformer(Transformers.aliasToBean(EntityModel.class));return query.getResultList();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这次返回的就是 List 了。这里要注意的是 StandardBasicTypes这个常量类,在一些旧版本中,是 Hibenate 类,具体哪个包我不知道,我这个版本中是换成了前面的那个常量类

spring data jpa 查询自定义字段,转换为自定义实体相关推荐

  1. Spring Data JPA 查询方法的命名语法与参数

    3 Spring Data JPA 查询方法的命名语法与参数 在⼯作中,你是否经常为⽅法名的语义.命名规范⽽发愁?是否要为不同的查询条件写各种的 SQL 语句?是否为同⼀个实体的查询,写⼀个超级通⽤的 ...

  2. Spring Data JPA 从入门到精通~自定义实现Repository

    EntityManager 的获取方式 我们既然要自定义,首先讲一下 EntityManager 的两种获取方式. 1. 通过 @PersistenceContext 注解. 通过将 @Persist ...

  3. Spring Data JPA 查询方法支持的关键字

    Table 2.3. Supported keywords inside method names Keyword Sample JPQL snippet And findByLastnameAndF ...

  4. Spring Data JPA教程

    在Java类或对象与关系数据库之间管理数据是一项非常繁琐且棘手的任务. DAO层通常包含许多样板代码,应简化这些样板代码,以减少代码行数并使代码可重复使用. 在本教程中,我们将讨论Spring数据的J ...

  5. Spring Data JPA问题汇总

    刚进公司,发现都用的Spring Data JPA,一脸懵,知乎上遇到了一个大佬写的文章,非常详细,分享一下,我把大佬的文章整理了一下格式,比较好看了,原文链接:https://zhuanlan.zh ...

  6. spring data jpa使用详解(推荐)

    使用Spring data JPA开发已经有一段时间了,这期间学习了一些东西,也遇到了一些问题,在这里和大家分享一下. 前言: Spring data简介: Spring Data是一个用于简化数据库 ...

  7. spring data jpa使用的几种方式

    Spring data简介: Spring Data是一个用于简化数据库访问,并支持云服务的开源框架.其主要目标是使得对数据的访问变得方便快捷,并支持map-reduce框架和云计算数据服务. Spr ...

  8. spring data jpa使用详解

    Spring data简介: Spring Data是一个用于简化数据库访问,并支持云服务的开源框架.其主要目标是使得对数据的访问变得方便快捷,并支持map-reduce框架和云计算数据服务. Spr ...

  9. 使用Spring Data JPA进行分页和排序

    通过代码示例学习使用Spring Data JPA进行分页和排序 . 了解如何使用Springs PagingAndSortingRepository接口获取分页和排序结果. 1概述 在处理大量数据时 ...

最新文章

  1. Python startswith() 方法
  2. http-关于application/x-www-form-urlencoded等字符编码的解释说明
  3. CentOS7 搭建Ambari-Server,安装Hadoop集群(一)
  4. [spring]spring boot项目实例
  5. php中fread用法,php fread函数与fread函数用法_PHP教程
  6. 税控盘系统参数设置服务器,税控盘设置服务器地址
  7. 读《白帽子讲Web安全》有感
  8. 数字化营销转型,你的企业准备好了吗?
  9. 数据抽取的常见理论方法
  10. 模拟CMOS集成电路设计中的电流镜及用Cadence Virtuoso IC617设计并仿真有关电路
  11. mysql菜单表设计_多级联动菜单的数据库表如何设计?
  12. 台式电脑主板插线步骤图_机箱上的跳线接在主板那些位置?台式电脑主板接线示意图解教程...
  13. 【linux内核分析与应用-陈莉君】IO空间管理
  14. zabbix探究告警触发器Triggers
  15. 无任何网络提供程序接受指定的网络路径的解决
  16. 《惢客创业日记》2018.12.19(周三)创业从0到1的10个阶段(六)
  17. ubuntu20.04运行se2lam
  18. 1.54寸墨水屏模块 E-Paper电子纸显示屏STM32C8T6驱动代码以及调试过程
  19. PES,TS,PS,RTP等流的打包格式解析之RTP流
  20. Ubuntu把在效能器范畴起更重要的脚色

热门文章

  1. Web开发环境搭建(个人学习转载)
  2. 向添加前端静态页面之后,菜单栏显示正常,但是点击的时候报错main.js:978 Error: Cannot find module ‘./function (resolve) {。。。。。。
  3. 超神战记不显示服务器,难舍超神路 《超神战记》安卓版测试结束
  4. oracle oui gi是什么,Oracle 11g RAC手动打GI PSU补丁(11.2.0.4.8)
  5. 不可不知的结婚照摆放禁忌
  6. 在Windows10家庭版安装Docker遇到问题的解决方法
  7. java.beans_JavaBeans的介绍与使用
  8. golang读取chrome/edge浏览器本地cookies数据库
  9. 疯狂边缘的野兽:新浪微博繁华下的危机
  10. 基于FPGA的多级CIC滤波器实现四倍抽取三