Spring data jpa 使用

spring data jpa介绍

首先了解JPA是什么?
JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate,TopLink,JDO等ORM框架各自为营的局面。值得注意的是,JPA是在充分吸收了现有Hibernate,TopLink,JDO等ORM框架的基础上发展而来的,具有易于使用,伸缩性强等优点。从目前的开发社区的反应上看,JPA受到了极大的支持和赞扬,其中就包括了Spring与EJB3.0的开发团队。
注意:JPA是一套规范,不是一套产品,那么像Hibernate,TopLink,JDO他们是一套产品,如果说这些产品实现了这个JPA规范,那么我们就可以叫他们为JPA的实现产品。

spring data jpa

Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率!

添加spring-data-jpa的支持



 org.springframework.boot
 spring-boot-starter-data-jpa

spring data jpa让我们解脱了DAO层的操作,基本上所有CRUD(增删改查)都可以依赖于它来实现

编写实体类
package com.mengma.tensquare_base.pojo;


import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "tb_label") //name = 表名
public class Label {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false) // 与表字段一致 则可以不加
    private String id;

    private String labelname;

    private String state;

    private Long count;

    private String recommend;

    private Long fans;

    public Label(String id, String labelname, String state, Long count, String recommend, Long fans) {
        this.id = id;
        this.labelname = labelname;
        this.state = state;
        this.count = count;
        this.recommend = recommend;
        this.fans = fans;
    }

    public Label() {
        super();
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id == null ? null : id.trim();
    }

    public String getLabelname() {
        return labelname;
    }

    public void setLabelname(String labelname) {
        this.labelname = labelname == null ? null : labelname.trim();
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state == null ? null : state.trim();
    }

    public Long getCount() {
        return count;
    }

    public void setCount(Long count) {
        this.count = count;
    }

    public String getRecommend() {
        return recommend;
    }

    public void setRecommend(String recommend) {
        this.recommend = recommend == null ? null : recommend.trim();
    }

    public Long getFans() {
        return fans;
    }

    public void setFans(Long fans) {
        this.fans = fans;
    }
}
编写Repository接口
//此接口不需要添加注解
//当需要条件查询时,需要继承JpaSpecificationExecutor 
public interface LabelDao extends JpaRepository,JpaSpecificationExecutor
编写实现层
package com.mengma.tensquare_base.service;

import com.mengma.common.utils.UUIDUtil;
import com.mengma.tensquare_base.dao.LabelDao;
import com.mengma.tensquare_base.pojo.Label;
import org.apache.commons.lang.StringUtils;
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.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author Administrator
 * @Title: LabelRepositoryService
 * @ProjectName tensquare_abu
 * @Description: TODO
 * @date 2019/1/11 0:32
 */
@Service
public class LabelRepositoryService {
    @Autowired
    private LabelDao labelDao;
    public Label insert(Label label){
        String id = UUIDUtil.getOrderIdByUUId();
        label.setId(id);
//     新增
        return  labelDao.save(label);
    }
    public List
package com.mengma.tensquare_base.controller;

import com.mengma.common.VO.PageResult;
import com.mengma.common.commons.ServerResponse;
import com.mengma.tensquare_base.dao.LabelDao;
import com.mengma.tensquare_base.pojo.Label;
import com.mengma.tensquare_base.service.LabelRepositoryService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Administrator
 * @Title: LabelController
 * @ProjectName tensquare_abu
 * @Description: TODO
 * @date 2019/1/10 15:17
 */
@RestController
@RequestMapping("/")
public class LabelController {
    @Autowired
    private LabelRepositoryService labelRepositoryService;
    /**
    * @Description: 增加标签
    * @Param:  
    * @return:  
    * @Author: ABU
    * @Date: 2019/1/10 
    */
    @PostMapping("label")
    public ServerResponse insert(@RequestBody Label label){
        Label insert = labelRepositoryService.insert(label);
        if(insert==null){
            return ServerResponse.createByErrorMessage("添加失败");
        }
        return ServerResponse.createByflagMessage("添加成功");
    }
    @GetMapping("label")
    public ServerResponse getLists(){
        return  ServerResponse.createByflag(labelRepositoryService.getList());
    }
    @GetMapping("label/toplist")
    public ServerResponse topLists(){
        return ServerResponse.createByflag(labelRepositoryService.findByRecommend("1"));
    }
    @GetMapping("label/list")
    public ServerResponse stateLists(){
        return ServerResponse.createByflag(labelRepositoryService.findByState("1"));
    }
    @GetMapping("label/{labelId}")
    public ServerResponse getById(@PathVariable String labelId){
        return ServerResponse.createByflag(labelRepositoryService.findById(labelId));
    }
    @PutMapping("/label/{labelId}")
    public ServerResponse update(@PathVariable String labelId,
                                 @RequestBody Label label){
        //sava 既可以做保存 又可以做修改 根据传入的类的id 进行查询,没有就新增 反之
        label.setId(labelId);
        Label save = labelRepositoryService.update(label);
        if (save==null){
            return ServerResponse.createByErrorMessage("失败");
        }
        return ServerResponse.createByflagMessage("成功!");
    }
    @DeleteMapping("label/{labelId}")
    public ServerResponse delete(@PathVariable String labelId){
        labelRepositoryService.delete(labelId);
       return ServerResponse.createByflagMessage("成功!");
    }

    @PostMapping("label/search")
    public ServerResponse pageSearch(@RequestBody Label label){
        return ServerResponse.createByflag(labelRepositoryService.pageSearch(label));
    }
    @PostMapping("label/search/{page}/{size}")
    public ServerResponse page(@PathVariable Integer page,
                               @PathVariable Integer size,
                               @RequestBody  Label label){
        Page

在此处介绍一下上面提到的自定义Repository继承的两个接口,如果你的查询列表是没有查询条件,只是列表展示和分页,只需继承JpaRepository接口即可,但是如果你的查询列表是带有多个查询条件的话则需要继承JpaSpecificationExecutor接口,这个接口里面定义的多条件查询的方法。当然不管继承哪个接口,当你做分页查询时,都是需要调用findAll方法的,这个方法是jap定义好的分页查询方法。

下面介绍一下一些简单的默认查询

自定义简单查询

自定义的简单查询就是根据方法名来自动生成SQL,主要的语法是
findXXBy,readAXXBy,queryXXBy,countXXBy, getXXBy后面跟属性名称:

也使用一些加一些关键字 And、 Or

User findByUserNameOrEmail(String username, String email);

修改、删除、统计也是类似语法

Long deleteById(Long id);

Long countByUserName(String userName)

基本上SQL体系中的关键词都可以使用,例如:LIKE、 OrderBy。

List findByEmailLike(String email);
    
List findByUserNameOrderByEmailDesc(String email);

具体的关键字,使用方法和生产成SQL如下表所示

Spring data jpa 使用_第1张图片
image.png

Spring data jpa 使用_第2张图片
image.png
复杂查询

在实际的开发中我们需要用到分页、删选、连表等查询的时候就需要特殊的方法或者自定义SQL
分页查询
分页查询在实际使用中非常普遍了,spring data jpa 已经帮我们实现了分页的功能,在查询的方法中,需要传入参数Pageable
,当查询中有多个参数的时候 Pageable建议做为最后一个参数传入

Page findALL(Pageable pageable);
    
Page findByUserName(String userName,Pageable pageable);

Pageable 是spring封装的分页实现类,使用的时候需要传入页数、每页条数和排序规则

@Test
public void testPageQuery() throws Exception {
    int page=1,size=10;
    Sort sort = new Sort(Direction.DESC, "id");
    Pageable pageable = new PageRequest(page, size, sort);
    userRepository.findALL(pageable);
    userRepository.findByUserName("testName", pageable);
}
限制查询

有时候我们只需要查询前N个元素,或者支取前一个实体。

User findFirstByOrderByLastnameAsc();

User findTopByOrderByAgeDesc();

Page queryFirst10ByLastname(String lastname, Pageable pageable);

List findFirst10ByLastname(String lastname, Sort sort);

List findTop10ByLastname(String lastname, Pageable pageable);
自定义SQL查询

其实Spring data 觉大部分的SQL都可以根据方法名定义的方式来实现,但是由于某些原因我们想使用自定义的SQL来查询,spring data也是完美支持的;在SQL的查询方法上面使用 @Query注解,如涉及到删除和修改在需要加上@Modifying.也可以根据需要添加 @Transactional对事物的支持,查询超时的设置等

@Modifying
@Query("update User u set u.userName = ?1 where c.id = ?2")
int modifyByIdAndUserId(String  userName, Long id);
    
@Transactional
@Modifying
@Query("delete from User where id = ?1")
void deleteByUserId(Long id);
  
@Transactional(timeout = 10)
@Query("select u from User u where u.emailAddress = ?1")
    User findByEmailAddress(String emailAddress);

你可能感兴趣的:(Spring data jpa 使用)