SpringBoot集成Jpa极简教程-Spring专区论坛-技术-SpringForAll社区

SpringBoot集成Jpa极简教程

简介

基本概念

Jpa(Java Persistence API)即 java 持久化api规范,并不是一个ORM框架,而是一种访问数据的接口定义,通过与数据访问框架或者ORM框架配合,可以简单方便的处理与数据库的交互。这种概念有点类似 slf4j 和 logback 的关系。

SpringDataJpa是对JPA规范的封装,旨在提高开发效率,同时不失灵活性,它提供了一种简单、一致的方式来访问不同种类的数据源,包括关系数据库、非关系数据库、MapReduce 框架等。Spring Data JPA 还提供了一些高级特性,如动态查询、多表查询、嵌套查询、存储过程和函数调用等。

在SpringBoot中,jpa默认情况下的orm实现是 hibernate。

图片[1]-SpringBoot集成Jpa极简教程-Spring专区论坛-技术-SpringForAll社区

优点

封装了 JPA 的细节,提供了更高层次的抽象,简化了数据访问层的开发,提高了开发效率;支持多种数据源,包括关系型数据库和非关系型数据库;提供了一些高级特性,如动态查询、多表查询、嵌套查询、存储过程和函数调用等;可与其他 Spring 框架无缝集成,如 Spring Boot、Spring Cloud 等。

缺点

对于一些复杂的查询,仍需要手动编写 SQL 语句;默认的实现可能存在性能问题,需要手动优化。

基础实践

pom


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.20</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.76</version>
</dependency>

yml

主要配置了数据库访问参数,没有显示配置数据库连接池,默认使用的是 HikariPool 。

通过配置 show-sql = true 来打印sql


spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://ip:3306/test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: root
    password: 123456
  jpa:
    show-sql: true

entity


package com.ramble.ramblespringboot.springdatajpa.entity;
import lombok.Data;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;

@Data
@Entity
@Table(name = "user")
public class UserEntity implements Serializable {

    @Id
    private String id;
    @Column(name = "name")
    private String name;
    @Column(table = "user", name = "state")
    private Integer state;
    
}

  • Entity:表示此类为一个数据库实体
  • Tabel:映射到数据库的哪个表
  • Id:表的主键,必须
  • Column:属性对应的表字段

repository


package com.ramble.ramblespringboot.springdatajpa.repository;
import com.ramble.ramblespringboot.springdatajpa.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;

@Repository
public interface UserRepository extends JpaRepository<UserEntity, String> {

    UserEntity findByName(String name );
    
    @Query("select u from UserEntity u where u.name like %?1 and u.id = ?2")
    List<UserEntity> find(String name, String id);
    
    @Query(nativeQuery = true, value = " select * from user where name = ?1 ")
    List<UserEntity> findByNativeQuery(String name);
    
    //启动的时候报异常,不可  param.name 访问
//    @Query("select u from UserEntity u where u.name like %:us.name and u.id = :us.id")
//    List<UserEntity> findByParam(@Param("us") UserEntity us);

    @Query("select u from UserEntity u where u.name like %:name and u.id = :id")
    List<UserEntity> findByParam(@Param("id") String id, @Param("name") String name);



    @Modifying
    @Query(" update UserEntity u  set u.state=?2  where  u.id = ?1")
    Integer updateSate(String id,  Integer state);
    
}

  • Repository:表示此接口是一个持久层,同时注入到容器中,供其他容器对象访问
  • JpaRepository:实现JpaRepository 接口,便于使用默认的crud接口。其中第一个泛型参数UserEntity 为数据库实体的名字,第二泛型参数String 为数据库表主机的数据类型
  • findByName:StringDataJpa会根据方法名称自行生成查询sql
  • Query:显示指定查询的sql,这里又分为两种方式,一种是jpa方式,一种是本地查询方式,通过指定nativeQuery=true设置。
  • JPAQuery:当为jpa模式的时候表名称写实体名称
  • NativeQuery:表名写数据库表的名称
  • 参数处理:参数赋值有多种方式:
    • ?1: 表示获取方法第一个参数
    • :id:表示通过param指定的参数名称获取参数
  • Modifying:当update/delete操作的时候需要添加此注解

controller


package com.ramble.ramblespringboot.springdatajpa.controller;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.ramble.ramblespringboot.springdatajpa.entity.UserEntity;
import com.ramble.ramblespringboot.springdatajpa.repository.UserRepository;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.*;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/test")
public class TestController {

    private UserRepository userRepository;
    @PostMapping("/")
    public Boolean create() {
        UserEntity user = new UserEntity();
        user.setId(IdUtil.fastSimpleUUID());
        user.setName(RandomUtil.randomString(4));
        user.setState(RandomUtil.randomInt());
        UserEntity result = userRepository.save(user);
        return true;
    }
    
    @DeleteMapping("/{id}")
    public Boolean delete(@PathVariable("id") String id) {
        //userRepository.deleteById(id);
        UserEntity user = new UserEntity();
        user.setId(id);
        userRepository.delete(user);
        return true;
    }
    
    @GetMapping("/crud")
    public String crud() {
        long count = userRepository.count();
        UserEntity byId = userRepository.getById("ecde5544eb0647ef8b005ca9f6ff68db");
        List<UserEntity> all = userRepository.findAll();
        List<UserEntity> all1 = userRepository.findAll(Sort.by("id"));
        UserEntity user = new UserEntity();
        user.setId("ecde5544eb0647ef8b005ca9f6ff68db");
        user.setName("明");
        ExampleMatcher matcher = ExampleMatcher.matching();
        matcher.withMatcher("id", m -> m.startsWith());
        matcher.withMatcher("name", m -> m.contains());
        Example<UserEntity> example = Example.of(user, matcher);
        List<UserEntity> allExample = userRepository.findAll(example);
        Pageable page = PageRequest.of(0, 20);
        Page<UserEntity> allPage = userRepository.findAll(example, page);
        return JSON.toJSONString(allPage);
    }
    
    /**
     * 执行 update /delete 必须添加 事务注解  Transactional
     *
     * @return
     */
    @Transactional
    @GetMapping("/query")
    public Boolean query() {
        UserEntity byName = userRepository.findByName("明");
        List<UserEntity> find = userRepository.find("明", "f2bcbe98ef88450b955f76bb063c1cf8");
        List<UserEntity> nativeQuery = userRepository.findByNativeQuery("明");
//        UserEntity user = new UserEntity();
//        user.setName("明");
//        List<UserEntity> byParam = userRepository.findByParam(user);
        Integer update = userRepository.updateSate("f2bcbe98ef88450b955f76bb063c1cf8", 2);
        List<UserEntity> byParam = userRepository.findByParam("f2bcbe98ef88450b955f76bb063c1cf8", "明");
        return true;
    }
    
}

注意事项

  • 执行 update /delete 必须添加 事务注解  Transactional

思考

  • repository接口传参如何传 dto , 测试代码中我传递 @Param(“us”) UserEntity us 这样一个参数,无法使用 :us.name 的方式获取

  • 打印的sql没有输出参数,是不支持还是姿势不对?

引用

官网:https://spring.io/projects/spring-data-jpa

请登录后发表评论

    没有回复内容