首页 > 其他分享 >Spring Data JPA使用规则和自动审计的学习

Spring Data JPA使用规则和自动审计的学习

时间:2023-07-20 18:37:38浏览次数:43  
标签:userRepository name JPA Spring void List userList import Data

一、创建项目引入依赖

完整的pom文件如下所示:

<?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="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.13</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>FunlyDemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>FunlyDemo</name>
    <description>FunlyDemo</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.31</version>
        </dependency>
        <!--jpa-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
 
</project>

二、application.properties配置文件

#mysql
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/funly?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456
 
#jpa
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

三、创建用户实体类

package com.example.funlydemo.bean;
 
import lombok.Data;
import lombok.ToString;
 
import javax.persistence.*;
 
/**
 * @author qx
 * @date 2023/07/19
 * @desc 用户实体类
 */
@Entity
@Table(name = "t_user")
@Data
@ToString
public class User {
 
    /**
     * ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    /**
     * 姓名
     */
    private String name;
    /**
     * 年龄
     */
    private Integer age;
}

四、JPA自带规则认识

项目启动自动创建好数据表后,我们添加一些测试数据到user表。

Spring Data JPA使用规则和自动审计的学习_自动审计

我们通过一个表格学习一下JPA的默认规则

关键字

举例

JPQL片段

And

findAllByNameAndAge

where user0_.name=? and user0_.age=?

Or

findAllByNameOrAge

where user0_.name=? or user0_.age=?

is,Equals

findAllByName

findAllByNameIs,findAllByNameEquals,

where user0_.name=?

Between

findAllByAgeBetween

where user0_.age between ? and ?

LessThan

findAllByAgeLessThan

where user0_.age<?

LessThanEqual

findAllByAgeLessThanEqual

where user0_.age<=?

GreaterThan

findAllByAgeGreaterThan

where user0_.age>?

GreaterThanEqual

findAllByAgeGreaterThanEqual

where user0_.age>=?

IsNull

findAllByAgeIsNull

where user0_.age is null

IsNotNull

findAllByAgeIsNotNull

where user0_.age is not null

Like

findAllByNameLike

where user0_.name like ? escape ?

NotLike

findAllByNameNotLike

where user0_.name not like ? escape ?

StartingWith

findAllByNameStartingWith

where user0_.name like ?(后置%) escape ?

EndingWith

findAllByNameEndingWith

where user0_.name like ?(前置%) escape ?

Containing

findAllByNameContaining

where user0_.name like ?(双%) escape ?

OrderBy

findAllByNameOrderByAgeDesc

where user0_.name=? order by user0_.age desc

Not

findAllByNameNot

where user0_.name<>?

In

findAllByAgeIn

where user0_.age in (? , ?)

NotIn

findAllByAgeNotIn

where user0_.age not in  (? , ?)

五、持久层方法编写

package com.example.funlydemo.repository;
 
import com.example.funlydemo.bean.User;
import org.springframework.data.jpa.repository.JpaRepository;
 
import java.util.List;
 
public interface UserRepository extends JpaRepository<User, Long> {
 
    List<User> findAllByNameAndAge(String name, Integer age);
 
    List<User> findAllByNameOrAge(String name, Integer age);
 
    List<User> findAllByNameIs(String name);
 
    List<User> findAllByNameEquals(String name);
 
    List<User> findAllByName(String name);
 
 
    List<User> findAllByAgeBetween(Integer age1, Integer age2);
 
    List<User> findAllByAgeLessThan(Integer age);
 
    List<User> findAllByAgeLessThanEqual(Integer age);
 
    List<User> findAllByAgeGreaterThan(Integer age);
 
    List<User> findAllByAgeGreaterThanEqual(Integer age);
 
    List<User> findAllByAgeIsNull();
 
    List<User> findAllByAgeIsNotNull();
 
    List<User> findAllByNameLike(String name);
 
    List<User> findAllByNameNotLike(String name);
 
    List<User> findAllByNameStartingWith(String name);
 
    List<User> findAllByNameEndingWith(String name);
 
    List<User> findAllByNameContaining(String name);
 
    List<User> findAllByNameOrderByAgeDesc(String name);
 
    List<User> findAllByNameNot(String name);
 
    List<User> findAllByAgeIn(List<Integer> ageList);
 
    List<User> findAllByAgeNotIn(List<Integer> ageList);
}

六、单元测试

package com.example.funlydemo;
 
import com.example.funlydemo.bean.User;
import com.example.funlydemo.repository.UserRepository;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
 
import java.util.List;
 
@SpringBootTest
class FunlyDemoApplicationTests {
 
    @Autowired
    private UserRepository userRepository;
 
    @Test
    void testAnd() {
        List<User> userList = userRepository.findAllByNameAndAge("aa", 11);
        System.out.println(userList);
    }
 
    @Test
    void testOr() {
        List<User> userList = userRepository.findAllByNameOrAge("aa", 11);
        System.out.println(userList);
    }
 
    @Test
    void testEquals() {
        List<User> userList = userRepository.findAllByNameIs("aa");
        System.out.println(userList);
 
        List<User> userList1 = userRepository.findAllByNameEquals("aa");
        System.out.println(userList1);
 
        List<User> userList2 = userRepository.findAllByName("aa");
        System.out.println(userList2);
    }
 
    @Test
    void testBetween() {
        List<User> userList = userRepository.findAllByAgeBetween(12, 13);
        System.out.println(userList);
    }
 
    @Test
    void testLessThan() {
        List<User> userList = userRepository.findAllByAgeLessThan(12);
        System.out.println(userList);
    }
 
    @Test
    void testLessThanEqual() {
        List<User> userList = userRepository.findAllByAgeLessThanEqual(12);
        System.out.println(userList);
    }
 
    @Test
    void testGreaterThan() {
        List<User> userList = userRepository.findAllByAgeGreaterThan(12);
        System.out.println(userList);
    }
 
    @Test
    void testGreaterThanEqual() {
        List<User> userList = userRepository.findAllByAgeGreaterThanEqual(12);
        System.out.println(userList);
    }
 
    @Test
    void testIsNull() {
        List<User> userList = userRepository.findAllByAgeIsNull();
        System.out.println(userList);
    }
 
    @Test
    void testIsNotNull() {
        List<User> userList = userRepository.findAllByAgeIsNotNull();
        System.out.println(userList);
    }
 
    @Test
    void testLike() {
        List<User> userList = userRepository.findAllByNameLike("b%");
        System.out.println(userList);
    }
 
    @Test
    void testNotLike() {
        List<User> userList = userRepository.findAllByNameNotLike("b%");
        System.out.println(userList);
    }
 
    @Test
    void testStartingWith() {
        List<User> userList = userRepository.findAllByNameStartingWith("b");
        System.out.println(userList);
    }
 
    @Test
    void testEndingWith() {
        List<User> userList = userRepository.findAllByNameEndingWith("x");
        System.out.println(userList);
    }
 
    @Test
    void testContaining() {
        List<User> userList = userRepository.findAllByNameContaining("a");
        System.out.println(userList);
    }
 
    @Test
    void testOrderBy() {
        List<User> userList = userRepository.findAllByNameOrderByAgeDesc("aa");
        System.out.println(userList);
    }
 
    @Test
    void testNot() {
        List<User> userList = userRepository.findAllByNameNot("aa");
        System.out.println(userList);
    }
 
    @Test
    void testIn() {
        List<User> userList = userRepository.findAllByAgeIn(Lists.newArrayList(11, 12));
        System.out.println(userList);
    }
 
    @Test
    void testNotIn() {
        List<User> userList = userRepository.findAllByAgeNotIn(Lists.newArrayList(11, 12));
        System.out.println(userList);
    }
}

七、自定义规则

我们可以使用JPQL和书写原生SQL的方式实现自定义的规则。JPQL最突出的特点就是以Java Bean为操作对象,遵循JPA规范屏蔽了数据库 之间的差异,使同一套代码可以用在任意数据库上;而SQL方式是以表为操作 对象的,因此可以使用某种数据库特有的功能,比如某个MySQL独有的功能, 但是切换到Oracle时就不能使用了。

JPQL使用示例代码如下:

@Query("select u from User u where u.name=?1")
    List<User> getDataByName(String name);

原生SQL使用示例代码如下:

@Query(value = "select * from t_user where name=?1",nativeQuery = true)
    List<User> getUserFromName(String name);
}

设置nativeQuery属性为true,说明使用原生SQL。

八、自动审计功能

我们的业务数据的插入时间、最后更新时间、创建人及最后更新人的记录对每个 系统都很重要,但如果每次操作时都需要手动记录这些信息,就会非常枯燥且 烦琐。作为一个成熟的持久层框架,Spring Data JPA应该学会自己审计了。

1.启动类开启审计

package com.example.funlydemo;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
 
@SpringBootApplication
// 开启审计
@EnableJpaAuditing
public class FunlyDemoApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(FunlyDemoApplication.class, args);
    }
 
}

2.把审计需要的属性封装到一个公共类

package com.example.funlydemo.bean;
 
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;
 
/**
 * @author qx
 * @date 2023/07/19
 * @desc
 */
@Getter
@Setter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity {
 
    @CreatedBy
    @Column(updatable = false)
    private String creater;
 
    @LastModifiedBy
    private String modifier;
 
    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createTime;
 
    @LastModifiedDate
    private LocalDateTime updateTime;
 
 
}

@Column(updatable=false)将字段设置不可修改,只允许一次赋值。创建者和创建时间只需要插入一次,不需要更新。

我们可以使用@MappedSuperclass注解,通过这个注解,我们可以将该实体类当成基类实体,它不会映射到数据库表,但继承它的子类实体在映射时会自动扫描该基类实体的映射属性,添加到子类实体的对应数据库表中。

@EntityListeners里面配置的是监听器对象,用于捕获监听信息,当Entity发生持久化和更新操作时会调用自动审计。

3.用户类继承公共基类

package com.example.funlydemo.bean;
 
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
 
import javax.persistence.*;
 
/**
 * @author qx
 * @date 2023/07/19
 * @desc 用户实体类
 */
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "t_user")
@Data
@ToString
public class User extends BaseEntity {
 
    /**
     * ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    /**
     * 姓名
     */
    private String name;
    /**
     * 年龄
     */
    private Integer age;
}

4.创建一个获取当前操作人的接口实现类

package com.example.funlydemo.uti;
 
import org.springframework.data.domain.AuditorAware;
import org.springframework.stereotype.Component;
 
import java.util.Optional;
 
/**
 * @author qx
 * @date 2023/07/19
 * @desc 获取当前操作人的接口
 */
@Component
public class AuditorImpl implements AuditorAware<String> {
    @Override
    public Optional<String> getCurrentAuditor() {
        return Optional.of("admin->" + (int) (Math.random() * 10));
    }
}

5.测试审计

我们在单元测试中,测试添加用户

@Test
    void testAddUser() {
        User user = new User();
        user.setName("qq");
        user.setAge(20);
        userRepository.save(user);
    }

执行方法后,我们查看数据表,发现自动添加上了创建者和创建时间。

Spring Data JPA使用规则和自动审计的学习_Spring Data JPA_02

接下来我们测试修改用户的方法

  @Test
    void testUpdateUser(){
        Optional<User> optional = userRepository.findById(2L);
        User user = optional.get();
        user.setAge(22);
        userRepository.save(user);
    }

执行方法后,我们查看数据表,发现自动修改了更新时间和修改操作人。

 

Spring Data JPA使用规则和自动审计的学习_自动审计_03

这样我们就学习了JPA的默认规则和自定义规则和使用自动审计功能实现自动添加修改人、修改时间的功能。


标签:userRepository,name,JPA,Spring,void,List,userList,import,Data
From: https://blog.51cto.com/u_13312531/6789672

相关文章

  • springboot学习之十一(统一返回结果)
    SpringBoot统一返回结果在实际开发中,为了降低开发人员之间的沟通成本,一般返回结果会定义成一个统一格式,具体的格式根据实际开发业务不同有所区别,但至少包括三要素:code状态码:由后端统一定义各种返回结果的状态码message描述:本次接口调用的结果描述data数据:本次返回的数据。{......
  • springboot i18n 国际化
    默认一:1、配置#主Springspring:messages:basename:i18n.rsltMessage,i18n.errorCodeMessage 2、多语言文件在resources下新建i18n文件夹 ,在在这个下面建立多语言:rsltMessage.propertiesrsltMessage_ar_SA.propertiesrsltMessage_en_US.propertiesrsltMe......
  • Spring框架
    day01-下载,概述.监听器Spring4学习路线第一天:Spring的概述,SpringIOC入门(XML),Spring的Bean管理,Spring属性注入第二天:Spring的IOC的注解方式,Spring的AOP开发(XML)第三天:Spring的AOP的注解开发,Spring的声明式事务,jdbcTemplate第四天:SSH的整合,HibernateTemplate的使用,OpenSessionInV......
  • JAVA面试之SpringMVC
    一、工作流程流程 1、用户发送请求至前端控制器DispatcherServlet 2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。 3、处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。 4、DispatcherServlet调用Han......
  • idea创建spring boot项目没有Spring Initializr
    使用Idea创建SpringBoot项目没有SpringInitializr的方法在使用Idea开发Java项目时,通常可以通过SpringInitializr来快速创建SpringBoot项目。但是,有些情况下我们可能无法使用SpringInitializr来创建项目,比如网络环境受限,无法访问SpringInitializr的在线服务。那么有没有其他......
  • idea database连接hive很慢
    优化Hive数据库连接速度的步骤和代码示例概述在实际开发中,我们经常需要使用Hive作为数据库进行数据分析和处理。但有时候,我们可能会遇到连接Hive数据库很慢的情况,这会严重影响我们的开发效率和用户体验。为了解决这个问题,我们可以采取一些优化措施来提高Hive数据库连接的速度。......
  • 开源的Datadog?可观测性平台SigNoz是否名副其实?
    SigNoz号称自己是开源领域的Datadog,基于OpenTelemetry做了一套可观测性方案。夜莺从V6版本开始,也希望做全栈可观测性方案,巧了,大家目标一致,今天我们一起来对SigNoz做个初步了解,看看其产品设计如何,也帮大家未来选型做参考。1.SigNoz介绍SigNozisanopen-sourceapplicationp......
  • SpringCloud实现浏览器端大文件分块上传
    ​ 1.创建SpringBoot项目本项目采用springboot+mybatis-plus+jquery+thymeleaf组成2.项目流程图 ​编辑3.在pom中添加以下依赖12345678910111213141516171819202122232425262728293031<!--lombok依赖-->  <dependency> ......
  • Vue+springboot集成PageOffice实现在线编辑Word、excel文档
    说明:PageOffice是一款在线的office编辑软件,帮助Web应用系统或Web网站实现用户在线编辑Word、Excel、PowerPoint文档。可以完美实现在线公文流转,领导批阅,盖章。可以给文件添加水印,在线安全预览防止用户下载和复制文件等一、环境要求前端Vue项目:Node.js10及以上版本(当前集成方式......
  • Idea SpringBoot 项目启动时提示程序包不存在和找不到符号
    从git上克隆了一个SpringBoot项目,并且使用Maven编译也通过了,奇怪的是当BuildProject时却提示符号不存在。如下图: 先查看导入的类是否存在,如果不存在的话,那查看一下是否缺少了maven依赖。我这边是可以访问到类的,并且jar包也导入成功了。 也尝试了网上的解决方法,设置Proj......