简单示例

本节以一个简单的分页查询演示基本的代码构成。

数据对象(实体)

Foo.java
package com.example.demo.entity;

import lombok.Data;

import javax.persistence.*;

@Entity
@Data
public class Foo {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @ManyToOne
    private Bar bar;
}
Bar.java
package com.example.demo.entity;

import lombok.Data;
import lombok.ToString;

import javax.persistence.*;
import java.util.List;

@Entity
@Data
@ToString(exclude = "fooList")
public class Bar {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @OneToMany
    private List<Foo> fooList;
}

除基本的JPA注解之外,使用lombok提供的@Data注解简化POJO配置。注意使用@ToString注解排除可能造成循环依赖的字段。

数据传输对象(DTO)

FooDto.java
package com.example.demo.dto;

import com.example.demo.entity.Bar;
import com.taocares.commons.beans.annotation.Nested;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel("Foo数据传输对象")
public class FooDto {

    @ApiModelProperty("唯一标识")
    private Long id;

    @ApiModelProperty("名字")
    private String name;

    @ApiModelProperty("关联的Bar")
    @Nested(thisClass = BarDto.class, thatClass = Bar.class)
    private BarDto bar;
}
BarDto.java
package com.example.demo.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel("Bar数据传输对象")
public class BarDto {

    @ApiModelProperty("唯一标识")
    private Long id;

    @ApiModelProperty("名字")
    private String name;
}

针对数据传输的需求,配置和实体字段的映射关系,定义Swagger数据模型。使用lombok简化代码。

数据查询对象(QO)

FooQo.java
package com.example.demo.qo;

import com.taocares.commons.jpa.ConditionType;
import com.taocares.commons.jpa.QueryCondition;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel("Foo查询条件对象")
public class FooQo {

    @ApiModelProperty(value = "Foo的名字", notes = "模糊匹配开始")
    @QueryCondition(type = ConditionType.STARTS_WITH)
    private String name;

    @ApiModelProperty(value = "Bar的名字", notes = "严格匹配")
    @QueryCondition(targetField = "bar.name")
    private String barName;
}

根据查询需求定义数据查询对象,定义Swagger数据模型。使用lombok简化代码。

数据持久层(Repository)

FooRepository.java
package com.example.demo.repository;

import com.example.demo.entity.Foo;
import com.taocares.commons.jpa.RepositoryEnhancer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface FooRepository extends JpaRepository<Foo, Long>, JpaSpecificationExecutor<Foo>, RepositoryEnhancer {
}

实现JpaRepositoryJpaSpecificationExecutor接口即可,如果需要自定义查询语句,只需额外实现RepositoryEnhancer接口即可。

业务逻辑层(Service)

FooService.java
package com.example.demo.service;

import com.example.*;
import com.taocares.commons.beans.BeanUtils;
import com.taocares.commons.jpa.SpecificationFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.*;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class FooService {

    @Autowired
    private FooRepository fooRepository;

    public Page<FooDto> findAll(FooQo fooQo, Pageable pageable) {
        Specification<Foo> specification = SpecificationFactory.getSpecification(fooQo);
        Page<Foo> page = fooRepository.findAll(specification, pageable);
        List<FooDto> dtoList = BeanUtils.copyProperties(page.getContent(), FooDto.class);
        return new PageImpl<>(dtoList, pageable, page.getTotalElements());
    }
}

进行业务逻辑操作

请求控制层(Controller)

FooController.java
package com.example.demo.controller;

import com.example.demo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.*;

@RestController
@RequestMapping("/foos")
@Slf4j
@Api(tags = "Foo CRUD服务")
public class FooController {

    @Autowired
    private FooService fooService;

    @GetMapping("/")
    @ApiOperation("根据条件分页查询结果")
    public Page<FooDto> findAll(FooQo fooQo, Pageable pageable) {
        log.debug("Query Object: {}; pageable: {}", fooQo, pageable);
        return fooService.findAll(fooQo, pageable);
    }
}

映射HTTP请求,使用Swagger定义接口

Last updated