SpringDataJpa自定义投影映射

SpringDataJpa自定义投影映射


前言

今天为大家分享:SpringDataJpa自定义投影映射。

前面讲了SpringDataJpa自定义查询语句(JPQL),请查看博主的SpringDataJpa系列文章。欢迎关注!


为什么需要自定义投影映射

回忆我之前的文章使用Spring Data Jpa 持久层框架进行数据的查询操作时,只能获取一个对象或者对象集合,并不能获取对象中的指定的某个或者几个属性。但是在实际项目开发过程中,我们往往会有这种需求,那么我们应该怎
么办呢?不用担心,Spring Data Jpa框架也考虑到这种问题了,所以给我们提供了自定义投影映射来解决这种问题。


自定义投影映射的步骤

案例下载

github地址 https://github.com/chenxiban/SpringBoot-Simple.git

创建maven项目,搭建项目环境,项目目录如下:

在这里插入图片描述

配置pom.xml文件,代码如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.ysd</groupId>
  <artifactId>spring-boot-jpa-simple</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>spring-boot-jpa-simple</name>
  <url>http://maven.apache.org</url>

  <!-- Spring Boot 启动父依赖 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>
	<!-- 项目全局属性 -->
    <properties>
    	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
        <mybatis-spring-boot>1.2.0</mybatis-spring-boot>
        <mysql-connector>5.1.39</mysql-connector>
        <junit-version>4.12</junit-version>
    </properties>
    <dependencies>

        <!-- Spring Boot Web 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring Boot Test 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        
         <!-- Spring Boot devtools 热部署 依赖 -->
        <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>

        <!-- Spring Boot JPA 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- MySQL 连接驱动依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql-connector}</version>
        </dependency>

        <!-- Junit 单元测试   依赖 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit-version}</version>
		</dependency>
	</dependencies>

	<!-- SpringBoot 项目发布 打jar包 依赖 -->
	<build>
		<plugins>		
			<!-- SpringBoot 项目发布 打jar包 依赖 -->
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			
			<!-- Maven test junit 报告中文UTF-8编码 插件 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>2.6</version>
				<configuration>
					<forkMode>once</forkMode>
					<argLine>-Dfile.encoding=UTF-8</argLine>
				</configuration>
			</plugin>		
		</plugins>	
	</build>	
</project>
配置属性文件

在src/main/resources下配置application.properties,代码如下:

server: 
  port: 8090
  context-path: /mydemo
  tomcat:
    uri-encoding: UTF-8

spring: 
  datasource: 
    url: jdbc:mysql://localhost:3306/springbootjpasimple?useUnicode=true&characterEncoding=utf8
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect  #不加这句则默认为myisam引擎
    ##运行时输出jpa执行的sql语句
    show-sql: true
    ## spring-boot-starter-data-jpa自动映射创建表动作 配置: 有表更新,无表创建
    hibernate:
      ddl-auto: update
  #集中解决各种编码问题
  banner:
    charset: UTF-8
  http:
    encoding:
      charset: UTF-8
      enabled: true
      force: true
  messages:
    encoding: UTF-8
  #     spring mvc 视图解析器
  mvc:
    view:
      prefix: /
      suffix: .html
  # 时间格式化
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    # 时区设置
    time-zone: GMT+8
编写实体类

在com.ysd.springboot.entity下编写cat实体,代码如下:(这里没有用lombok,各位可以引入进去使用)

package com.ysd.springboot.entity;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity // HQL 使用,默认类名
@Table(name = "cattb") // 数据库原生SQL使用,默认表名
public class Cat implements Serializable {
	@Id // 实体类的主键
	@GeneratedValue // 自动增长列
	@OrderBy // 数据加载顺序
	@Column(columnDefinition = "int unsigned NOT NULL comment '备注:猫自动增长主键'  ")
	private Integer id;
	@Column(length = 20) // 字符长度20
	private String name;
	@Column(columnDefinition = "char(1) comment '备注:猫姓名' ")
	private String sex;
	@Column(columnDefinition = "int unsigned DEFAULT 0 comment '备注:猫年龄'  ")
	private Integer age;
	private Date birthday;
	@Column(columnDefinition = "TIMESTAMP", nullable = false, updatable = false, insertable = false)
	private Timestamp updateTime;
	@Transient // 临时参数,不映射到数据库表字段
	private String catParam;

	// ----------------------------- 以下是构造方法 ------------------------
	public Cat(String name, String sex, Integer age, String catParam) {
		super();
		this.name = name;
		this.sex = sex;
		this.age = age;
		this.birthday = new Date();
		this.catParam = catParam;
	}

	public Cat(String name, String sex, Integer age, Date birthday, String catParam) {
		super();
		this.name = name;
		this.sex = sex;
		this.age = age;
		this.birthday = birthday;
		this.catParam = catParam;
	}

	public Cat() {
		super();
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public Timestamp getUpdateTime() {
		return updateTime;
	}

	public void setUpdateTime(Timestamp updateTime) {
		this.updateTime = updateTime;
	}

	public String getCatParam() {
		return catParam;
	}

	public void setCatParam(String catParam) {
		this.catParam = catParam;
	}

	// ----------------------------- 以下是Getter和setter方法 ------------------------
	// 省略getter和setter方法
	// ----------------------------- 以下是重写的toString方法 ------------------------
	@Override
	public String toString() {
		return "Cat [id=" + id + ", name=" + name + ", sex=" + sex + ", age=" + age + ",   birthday=" + birthday
				+ ", updateTime=" + updateTime + ", catParam=" + catParam + "]";
	}
}
编写dao类

在com.ysd.springboot.dao下编写CatRepository接口,代码如下:

package com.ysd.springboot.dao;

import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import com.ysd.springboot.entity.Cat;

public interface CatRepository extends JpaRepository<Cat, Integer> {

	// ******************** []JPQL或者HQL 方式 ] 序号参数*******************

	@Query(" SELECT MAX(c.age) FROM Cat c ")
	public Long maxAge();

	@Query("select c from Cat c where  c.name like %:name% ")
	List<Cat> queryByname(@Param(value = "name") String name);

	// ----------------------------以下是自定义条件查询--------------------------------------
	// Like --- 等价于 SQL 中的 "like",比如 findByNameLike(String name);
	public List<Cat> findByNameLike(String name);

	// Like --- 等价于 SQL 中的 "like",比如 findByNameLike(String name);
	public List<Cat> findByNameLike(String name, Sort sort);

	public Page<Cat> findByNameLike(String name, Pageable pageable);

	// **************** 原生SQL********************
	@Query(value = " SELECT * FROM cattb WHERE NAME LIKE %:name% ", nativeQuery = true)
	List<Cat> queryBynameSQL(@Param(value = "name") String name);
}
编写业务接口

在com.ysd.springboot.service下,编写CatService接口,代码如下:

package com.ysd.springboot.service;

import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import com.ysd.springboot.entity.Cat;

public interface CatService {

	public Cat insert(Cat cat);

	public List<Cat> insert(List<Cat> list);

	public void delete(Integer id);

	public void delete(Cat cat);

	public void delete(List<Cat> list);

	public void deleteAll();

	public Cat update(Cat cat);

	public List<Cat> update(List<Cat> list);

	public Boolean exists(Integer id);

	public Long count();

	public Cat queryById(Integer id);

	public List<Cat> queryAll();

	public List<Cat> queryByNameLike(String name);

	public List<Cat> queryByName(String name);

	public List<Cat> queryByNameSQL(String name);

	public Long queryMaxAge();

	public List<Cat> queryAllSort(String fieldName);// 排序

	public Page<Cat> queryAllPage(Integer page, Integer size);// 分页,排序

	public List<Cat> queryNameLikeAllSort(String nameLike, String fieldName);// 带条件的排序

	public Page<Cat> queryNameLikeAllPage(String nameLike, Integer page, Integer size);// 带条件的分页
}
编写业务实现类

在com.ysd.springboot.ServiceImpl下,编写CatServiceImpl,代码如下

package com.ysd.springboot.ServiceImpl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import com.ysd.springboot.dao.CatRepository;
import com.ysd.springboot.entity.Cat;
import com.ysd.springboot.service.CatService;

@Service
public class CatServiceImpl implements CatService {

	@Autowired
	private CatRepository repository;

	@Override
	public Cat insert(Cat cat) {
		return repository.save(cat);
	}

	@Override
	public List<Cat> insert(List<Cat> list) {
		return repository.save(list);
	}

	@Override
	public void delete(Integer id) {
		repository.delete(id);
	}

	@Override
	public void delete(Cat cat) {
		repository.delete(cat);
	}

	@Override
	public void delete(List<Cat> list) {
		repository.delete(list);
	}

	@Override
	public void deleteAll() {
		repository.deleteAll();
	}

	@Override
	public Cat update(Cat cat) {
		return repository.save(cat);
	}

	@Override
	public List<Cat> update(List<Cat> list) {
		return repository.save(list);
	}

	@Override
	public Boolean exists(Integer id) {
		return repository.exists(id);
	}

	@Override
	public Long count() {
		return repository.count();
	}

	@Override
	public Cat queryById(Integer id) {
		return repository.findOne(id);
	}

	@Override
	public List<Cat> queryAll() {
		return repository.findAll();
	}

	@Override
	public List<Cat> queryAllSort(String fieldName) {// 排序
//		Sort sort = new Sort(Sort.Direction.DESC, "id"); 
//	    Pageable pageable = new PageRequest(page, size, sort);
		Sort sort = new Sort(Sort.Direction.DESC, fieldName, "id");
		return repository.findAll(sort);
	}

	@Override
	public Page<Cat> queryAllPage(Integer page, Integer size) {// 分页
		Sort sort = new Sort(Sort.Direction.ASC, "id");
		Pageable pageable = new PageRequest(page, size, null);
		return repository.findAll(pageable);
	}

	// ----------------------------以上是JpaRepository已经实现好的基本增删改查-----------------

	@Override
	public Long queryMaxAge() {
		return repository.maxAge();
	}

	@Override
	public List<Cat> queryByNameLike(String name) {
		return repository.findByNameLike("%" + name + "%");
	}

	@Override
	public List<Cat> queryByName(String name) {
		return repository.queryByname(name);
	}

	@Override
	public List<Cat> queryByNameSQL(String name) {
		return repository.queryBynameSQL(name);
	}

	@Override
	public List<Cat> queryNameLikeAllSort(String nameLike, String fieldName) {// 带条件的排序
//		Sort sort = new Sort(Sort.Direction.DESC, "id"); 
//	    Pageable pageable = new PageRequest(page, size, sort);
		Sort sort = new Sort(Sort.Direction.DESC, fieldName, "id");
		return repository.findByNameLike("%" + nameLike + "%", sort);
	}

	@Override
	public Page<Cat> queryNameLikeAllPage(String nameLike, Integer page, Integer size) {// 带条件的分页
		Sort sort = new Sort(Sort.Direction.ASC, "id");
		Pageable pageable = new PageRequest(page, size, sort);
		return repository.findByNameLike("%" + nameLike + "%", pageable);
	}
}
编写controller层

在com.ysd.springboot.controller下,编写CatController类,代码如下:

package com.ysd.springboot.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ysd.springboot.entity.Cat;
import com.ysd.springboot.service.CatService;

/**
 * SpringMVC控制器
 * 
 * @Description: 子模块
 *
 */
@RestController
public class CatController {

	@Autowired
	private CatService service;

	// 默认静态资源目录:http://localhost:8080/springbootjpasimple.sql

	/**
	 * 测试项目环境是否正常 http://localhost:8080/index
	 * 
	 * @return
	 */
	@RequestMapping("/index")
	public Cat index() {
		Cat cat = new Cat("张三", "男", 18, "预留参数");
		return cat;
	}

	/**
	 * 新增 http://localhost:8080/insertOne
	 * 
	 * @return
	 */
	@RequestMapping("/insertOne")
	public Cat add() {
		Cat cat = new Cat("张三", "男", 18, "预留参数");
		return service.insert(cat);
	}

	/**
	 * 排序 http://localhost:8080/orderBy
	 * 
	 * @return
	 */
	@RequestMapping("/orderBy")
	public List<Cat> orderBy() {
		return service.queryAllSort("age");
	}

	/**
	 * 条件模糊查询:[JPA关键字形式] http://localhost:8080/nameLike?name=m
	 * http://localhost:8080/nameLike?name=七
	 * 
	 * @return
	 */
	@RequestMapping("/nameLike")
	public List<Cat> nameLike(String name) {
		return service.queryByNameLike(name);
	}

	/**
	 * 条件模糊查询:[HQL形式] http://localhost:8080/queryName?name=m
	 * 
	 * @return
	 */
	@RequestMapping("/queryName")
	public List<Cat> queryName(String name) {
		return service.queryByName(name);
	}

	/**
	 * 条件模糊查询:[原生SQL形式] http://localhost:8080/queryNameSQL?name=m
	 * 
	 * @return
	 */
	@RequestMapping("/queryNameSQL")
	public List<Cat> queryNameSQL(String name) {
		return service.queryByNameSQL(name);
	}

	/**
	 * http://localhost:8080/queryMaxAge
	 * 
	 * @return
	 */
	@RequestMapping("/queryMaxAge")
	public Long queryMaxAge() {
		return service.queryMaxAge();
	}

	/**
	 * 分页查询 http://localhost:8080/queryPage
	 * 
	 * @return
	 */
	@RequestMapping("/queryPage")
	public Object queryPage() {
		Page<Cat> page = null;
		page = service.queryAllPage(1, 3);// 第2页,每页3条;第几页从零开始,每页显示几条.
		System.out.println("queryPage page=>" + page);
		Long total = page.getTotalElements();
		List<Cat> list = page.getContent();
		Map<String, Object> map = new HashMap<>();
		map.put("total", total);
		map.put("rows", list);
		return map;
	}

	/**
	 * 带条件的排序查询 http://localhost:8080/nameLikeorderBy?name=m
	 * 
	 * @return
	 */
	@RequestMapping("/nameLikeorderBy")
	public List<Cat> nameLikeorderBy(String name) {
		return service.queryNameLikeAllSort(name, "age");
	}

	/**
	 * 带条件的分页查询 http://localhost:8080/queryNameLikePage?name=m
	 * 
	 * @return
	 */
	@RequestMapping("/queryNameLikePage")
	public Object queryNameLikePage(String name) {
		Page<Cat> page = null;
		page = service.queryNameLikeAllPage(name, 0, 3);// 第1页,每页3条;第几页从零开始,每页显示几条.
		System.out.println("page=>" + page);
		Long total = page.getTotalElements();
		List<Cat> list = page.getContent();
		Map<String, Object> map = new HashMap<>();
		map.put("total", total);
		map.put("rows", list);
		return map;
	}
}
编写主项目类

在com.ysd.springboot下,编写主项目类,代码如下:

package com.ysd.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@EnableJpaRepositories(basePackages = "com.ysd.springboot.dao") // Spring Jpa 启用注解
@EntityScan(basePackages = "com.ysd.springboot.entity") // 扫描Jpa实体对象
@SpringBootApplication // Spring Boot 应用的标识
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);// 程序启动入口 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件
	}
}

启动项目,查看运行结果,测试路径可根据controller层给出的提示进行测试。


好了到这里也该结束了,各位要自己多动手才能学到真正的东西。加油各位


最后

  • 更多参考精彩博文请看这里:《陈永佳的博客》

  • 喜欢博主的小伙伴可以加个关注、点个赞哦,持续更新嘿嘿!


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈永佳

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值