springboot jpa之返回表中部分字段的处理详解

目录
  • springboot jpa返回表中部分字段
  • JPA 自定义返回字段

springboot jpa返回表中部分字段

使用springboot jpa操作数据库可以加快我们的开发效率,对于简单的crud操作来说,使用jpa来开发不要太爽,但是说实话对于一些复杂的数据库操做jpa使用起来就不是这么爽了。

在开发中很多时候我们要返回的可能只是数据库表中或某个类中的一部分字段,这个要是用mybatis的话就很简单,直接在sql中select字段就好了,规范一点就数据传输类接一下,偷个懒的话直接用map接就完事了。但就是这么个小操作在jpa中就不能这么直接。

废话一大堆(⊙_⊙)下面是我在jpa中处理返回部分字段的方法。

/**
 * 房间已经预定的时间统计表
 */
public interface RoomOrderTimeRepository extends JpaRepository<RoomOrderTime,Integer>{
    @Query("select  new com.ddzrh.dto.RoomOrderTimeOutPut(r.orderTime,COUNT(r.orderTime) )" +
            " from RoomOrderTime as r " +
            " where r.roomTypeId =:roomId"+
            " GROUP BY r.orderTime" )
    List<RoomOrderTimeOutPut> queryRoomOrderTime(@Param("roomId") Integer roomId);
}

看完上面的代码相比大家也能猜到,是的没什么好方法,我将要返回的数据都封装到了RoomOrderTimeOutPut类中。

@Data
public class RoomOrderTimeOutPut {
    private Date orderTime;
    private Long orderNum;
    public RoomOrderTimeOutPut(Date orderTime, Long orderNum) {
        this.orderTime = orderTime;
        this.orderNum = orderNum;
    }
}

像上面的代码,我希望查询返回某个时间某间房的预定数,我就将希望返回的预定时间和预定数封装至RoomOrderTimeOutPut并写以这两个字段为入参的构造函数,这个构造函数一定要写。看Query中的sql 有一个new RoomOrderTimeOutPut 的操作,这里就调用了构造函数,根据构造函数的入参将数据库查出的值传入。

JPA 自定义返回字段

实体类:User.java

@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "user")
public class User extends AbstractEntity {
    @Column(unique = true)
    private String username;
    private String password;
    private String nickname;
    private String email;
    @Column(name = "org_id")
    private Long orgId;
    @Column(name = "org_name")
    private String orgName;
}

DTO类:UserDTO.java

import lombok.Value;
/**
 * @author wu qilong
 * @date 2019/4/11
 * @Description: 自定义返回值,字段名称要和User实体类中的一致,加上lombok.@Value注解。
 */
@Value
public class UserDTO {
    private String username;
    private String nickname;
    private String email;
}

repository类:UserRepository.java

/**
 * @author Wu Qilong
 * @date 2019/4/11
 * @Description:
 */
public interface UserRepository extends JpaRepository<User, Long> {

    /**
     * 用户名查询
     *
     * @param username
     * @return
     */
    Optional<User> findByUsername(String username);

    /**
     * 用户名查询
     * @param username
     * @return
     */
    <T> Optional<T> findByUsername(String username, Class<T> type);
}

测试:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UoServerApplicationTests {
    @Autowired
    UserRepository userRepository;
    @Test
    public void contextLoads() {
        UserDTO userDTO = userRepository.findByUsername("wuqilong", UserDTO.class).get();
        Console.log(userDTO);
    }
}

注意:返回的DTO中属性名称需要和实体类中字段名一致,且加上lombok包中的@Value注解,这种方式对于只需要返回表中部分的字段很方便,如果需要自定义返回字段名称,可以参考以下方法:

需求:统计注册人数

定义一个返回对象

使用@Query(value = "select new com.wd.cloud.uoserver.dto.TjVO(u.orgId ,count(u.orgId)) from User u group by orgId")进行查询。

@Value
public class TjVO {
    Long orgId;
    Long registerCount;
}
/**
     * 按机构统计注册人数
     * @param pageable
     * @return
     */
    @Query(value = "select new com.wd.cloud.uoserver.dto.TjVO(u.orgId ,count(u.orgId)) from User u group by orgId")
    Page<TjVO> tjByOrgId(Pageable pageable);

或者也可以用下面的方法:

定义一个接口,用getXxx定义返回字段。xxx需要和返回字段的别名一致。

如果不一致,可以使用org.springframework.beans.factory.annotation包中的@Value进行映射

public interface TjDTO {
    /**
     * 所属机构
     * @return
     */
    Long getOrgId();
    /**
     * 注册时间
     * @return
     */
    String getRegisterDate();

    /**
     * 注册数量
     * @return
     */
    String getRegisterCount();

    /**
     * 管理员数量 当别名与该getXXX名称不一致时,可以使用该注解调整
     * @return
     */
    @Value("#{target.adminCount}")
    Long getManagerCount();
}

repository类:UserRepository.java添加方法tjByOrgId(),返回orgId和registerCount

 /**
     * 按天统计注册人数
     * @return
     */
    @Query(value = "select DATE_FORMAT(gmt_create,\"%Y-%m-%d\") as registerDate,count(*) as registerCount from user group by registerDate",nativeQuery = true)
    List<TjDTO> tj();

    /**
     * 按机构统计注册人数
     * @param pageable  分页
     * @return
     */
    @Query(value = "select org_id as orgId,count(*) as registerCount from user group by orgId",
            countQuery = "select count(*) from user group by org_id", nativeQuery = true)
    Page<TjDTO> tjByOrgId(Pageable pageable);

测试:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UoServerApplicationTests {
    @Autowired
    UserRepository userRepository;
    @Test
    public void contextLoads() {
        List<TjDTO> tjDTOList = userRepository.tj();
        tjDTOList.forEach(tjDTO -> {
            Console.log("registerDate={},registerCount={}", tjDTO.getRegisterDate(), tjDTO.getRegisterCount());
        });
    }
}

结果日志:

Hibernate: select DATE_FORMAT(gmt_create,"%Y-%m-%d") as registerDate,count(*) >as registerCount from user group by registerDate
registerDate=2019-01-28,registerCount=7393
registerDate=2019-03-07,registerCount=1

需求:根据机构分组,统计机构总人数和用户类型为2的人数

@Component
public class SpecBuilder {
    @PersistenceContext
    private EntityManager entityManager;
    public List<Object[]> tj(Long orgId) {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
        Root<User> root = query.from(User.class);
        //拼接where条件
        List<Predicate> predicateList = new ArrayList<Predicate>();
        if (orgId != null) {
            predicateList.add(cb.equal(root.get("orgId"), orgId));
        }
        //加上where条件
        query.where(ArrayUtil.toArray(predicateList, Predicate.class));
        query.multiselect(root.get("orgId"),
                cb.count(root),
                cb.sum(cb.<Integer>selectCase().when(cb.equal(root.get("userType"), 2), 1).otherwise(0)));
        query.groupBy(root.get("orgId"));
        //最终sql:  select org_id,count(id),sum(case when user_type=2 then 1 else 0 end) from user where org_id=?1 group by org_id;
        TypedQuery<Object[]> typedQuery = entityManager.createQuery(query);
        return typedQuery.getResultList();
    }
}

测试:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UoServerApplicationTests {
    @Autowired
    SpecBuilder specBuilder;

    @Test
    public void contextLoads() {
        List<Object[]> tjDTOList1 = specBuilder.tj(169L);
        tjDTOList1.forEach(tjDTO -> {
            Console.log("orgId={},总人数={},管理员人数={}", tjDTO[0], tjDTO[1], tjDTO[2]);
        });
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • spring data jpa 查询自定义字段,转换为自定义实体方式

    目标:查询数据库中的字段,然后转换成 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

  • SpringBoot JPA实现查询多值

    JPA是java Persistence API简称,中文名:java持久层API,JPA是JCP组织发布的J2EE标准之一 1.创建DataSource连接池对象 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- 数据库驱动 -

  • springboot 之jpa高级查询操作

    springboot的jpa可以根据方法名自动解析sql 非常方便, 只需要在 dao接口中定义方法即可; 下面是一个 demo package com.bus365.root.dao; import java.io.Serializable; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.reposi

  • SpringBoot使用JPA实现查询部分字段

    目录 SpringBoot JPA查询部分字段 自定义简单的查询方法 SpringBoot JPA查询部分字段 用过JPA的都知道,只需要继承JpaRepository 根据Jpa的函数命名规范写出接口中的函数,不需要实现,底层就可以自动解析成各种数据库的sql语句,进行增删改查等操作. 自定义简单的查询方法 如findByUserName,findByUserNameOrEmail(String username, String email)等条件的属性名称与个数要与参数的位置与个数一一对应,

  • springboot jpa之返回表中部分字段的处理详解

    目录 springboot jpa返回表中部分字段 JPA 自定义返回字段 springboot jpa返回表中部分字段 使用springboot jpa操作数据库可以加快我们的开发效率,对于简单的crud操作来说,使用jpa来开发不要太爽,但是说实话对于一些复杂的数据库操做jpa使用起来就不是这么爽了. 在开发中很多时候我们要返回的可能只是数据库表中或某个类中的一部分字段,这个要是用mybatis的话就很简单,直接在sql中select字段就好了,规范一点就数据传输类接一下,偷个懒的话直接用m

  • springboot jpa分库分表项目实现过程详解

    这篇文章主要介绍了springboot jpa分库分表项目实现过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 分库分表场景 关系型数据库本身比较容易成为系统瓶颈,单机存储容量.连接数.处理能力都有限.当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库.优化索引,做很多操作时性能仍下降严重.此时就要考虑对其进行切分了,切分的目的就在于减少数据库的负担,缩短查询时间. 分库分表用于应对当前互联网常见的两个场景--大数

  • c++获取sqlite3数据库表中所有字段的方法小结

    常用方法: 1.使用sqlite3_get_table函数 2.获取sqlite创建表的sql语句字符串,然后进行解析获取到相应的字段 3.采用配置文件的方式,将所有字段名写入配置文件 下面针对这三个方法给大家逐一详细介绍. 方法1:使用sqlite3_get_table函数 代码: char *dbname = "test.db"; int rc = sqlite3_open(dbname, &db); if (rc == SQLITE_OK) { char sql[256]

  • 如何使用MySQL一个表中的字段更新另一个表中字段

    1,修改1列 update student s, city c set s.city_name = c.name where s.city_code = c.code; 2,修改多个列 update a, b set a.title=b.title, a.name=b.name where a.id=b.id •子查询 update student s set city_name = (select name from city where code = s.city_code); oracle

  • mysql创建存储过程实现往数据表中新增字段的方法分析

    本文实例讲述了mysql创建存储过程实现往数据表中新增字段的方法.分享给大家供大家参考,具体如下: 需求: 往某数据库的某个表中新增一个字段(若该字段已存在,则不做操作:若该字段不存在,则新增) 百度了n久,没有符合要求的例子,只有参考加自己琢磨,最终终于给弄出来了,以下是几个版本的更迭 第一版: DELIMITER $$ CREATE PROCEDURE insert_column() BEGIN IF NOT EXISTS(SELECT 1 FROM information_schema.c

  • 关于在IDEA中SpringBoot项目中activiti工作流的使用详解

    记录一下工作流的在Springboot中的使用,,顺便写个demo,概念,什么东西的我就不解释了,如有问题欢迎各位大佬指导一下. 1.创建springboot项目后导入依赖 <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter-basic</artifactId> <version>6.0.0</version&

  • SpringBoot在RequestBody中使用枚举参数案例详解

    前文说到 优雅的使用枚举参数 和 实现原理,本文继续说一下如何在 RequestBody 中优雅使用枚举. 本文先上实战,说一下如何实现.在 优雅的使用枚举参数 代码的基础上,我们继续实现. 确认需求 需求与前文类似,只不过这里需要是在 RequestBody 中使用.与前文不同的是,这种请求是通过 Http Body 的方式传输到后端,通常是 json 或 xml 格式,Spring 默认借助 Jackson 反序列化为对象. 同样的,我们需要在枚举中定义 int 类型的 id.String

  • JPA设置默认字段及其长度详解

    目录 String 定义 Integer 和 Long 有区别吗 定义Integer和int有区别吗 boolean类型 日期 浮点数格式的设置 大文本 使用jpa去生成对应的值的长度和默认值是如何设置的呢 @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface Column { String name() default ""; boo

  • Spring JPA联表查询之OneToOne源码详解

    目录 前言 源码 注解属性 单向联表 user 实体类 car 实体类 查询结果 双向联表 user 实体 car 实体 查询结果 延迟加载(懒加载) user 实体 查询结果: 查询完会发现,控制台又打印了一个 JPQL: 最后结论 前言 前面几篇我们学习的都是单表查询,就是对一张表中的数据进行查询.而实际项目中,基本都会有多张表联合查询的情况,今天我们就来了解下JPA的联表查询是如做的. 源码 @OneToOne 注解实现一对一关系映射.比如用户跟车辆的关系(这里假设一个人只能有一辆车),一

  • Springboot项目中使用redis的配置详解

    程序结构: 一.配置 1. 在pom.xml中添加依赖 pom.xml文件如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=&q

随机推荐