springboot-data-jpa快速入门

一.Jpa简介

        Java Persistence API(JPA)是Java EE技术的一部分,它为关系型数据提供了一个对象/关系映射解决方案。它允许开发人员使用面向对象的方式操作数据库,而不是使用SQL语言。JPA是Java EE规范的一部分,它是Hibernate等ORM框架的实现。

        JPA是一个非常强大的ORM框架,它可以帮助开发人员在Java中使用关系型数据库。它提供了一个高度抽象的API,使得开发人员可以使用面向对象的方式来操作数据库。这种方式比使用SQL语言更加直观和易于理解。JPA还提供了一些高级特性,例如缓存、懒加载和级联操作等,这些特性可以帮助开发人员编写更好的Java应用程序。

        JPA很好的一个特性就是用JPA语法规范写的SQL,会根据当前系统使用的数据库类型改变生成的SQL语法,兼容数据库类型的切换,如之前使用的是MySQL,现在换成Oracle,由于不同类型的数据库,SQL语法会有区别,如果使用的是mybatis,就需要手动去改SQL兼容Oracle,而JPA就不用啦,无缝对接.

二.Jpa注解

@Entity

@Entity注解用于将Java类声明为JPA实体。这意味着该类将映射到数据库中的表。实体类必须具有一个无参构造函数,并且必须具有一个可以唯一标识该实体的@Id属性。

@Table

@Table注解用于指定实体将映射到的数据库表的名称。如果未指定,则使用实体的名称。

@Id

@Id注解用于指定实体的主键。它可以用于指定单个属性作为主键,也可以用于指定由多个属性组成的复合主键。

@GeneratedValue

@GeneratedValue注解用于指定主键的生成策略。它可以用于自动分配主键值。

@Column

@Column注解用于指定实体属性与数据库表中的列的映射。它可以用于指定列的名称,长度,是否允许为空等信息。

@OneToMany

@OneToMany注解用于指定实体之间的一对多关系。它可以用于指定实体之间的关系,包括如何在实体之间进行关联和如何在实体之间进行级联操作。

@ManyToOne

@ManyToOne注解用于指定实体之间的多对一关系。它可以用于指定实体之间的关系,包括如何在实体之间进行关联和如何在实体之间进行级联操作。

@JoinColumn

@JoinColumn注解用于指定实体之间的关联关系。它可以用于指定用于关联实体的数据库表和列的名称。

@NamedQuery

@NamedQuery注解用于定义一个命名查询。命名查询是一个在实体管理器上下文中定义的查询,可以在多个实体之间共享。命名查询可以提高代码的可读性和可维护性。

注解

作用

常用属性

@Data

给实体类加get/set/toString/EqualsAndHashCode方法,是lombok的注解

@Entity

指定当前类是实体类

@Table

指定实体类和表之间的对应关系

name:指定数据库表的名称

@EntityListeners

在实体类增删改的时候监听,为创建人/创建时间等基础字段赋值

value:指定监听类

@Id

指定当前字段是主键

@SequenceGenerator

指定数据库序列别名

sequenceName:数据库序列名name:取的别名

@GeneratedValue

指定主键的生成方式

strategy :指定主键生成策略generator:选择主键别名

@Column

指定实体类属性和数据库表之间的对应关系

name:指定数据库表的列名称。unique:是否唯一nullable:是否可以为空nserttable:是否可以插入updateable:是否可以更新columnDefinition: 定义建表时创建此列的DDL

@CreatedBy

自动插入创建人

@CreatedDate

自动插入创建时间

@LastModifiedBy

自动修改更新人

@LastModifiedDate

自动修改更细时间

@Version

自动更新版本号

@JsonFormat

插入/修改/读取的时间转换成想要的格式

pattern:展示格式timezone:国际时间

 

三.核心概念

        Spring 数据存储库抽象中的中心接口是 Repository 。它采用要管理的域类以及域类的标识符类型作为类型参数。此接口主要充当标记接口,用于捕获要使用的类型,并帮助您发现扩展此接口的接口。 CrudRepositoryListCrudRepository 接口为正在管理的实体类提供复杂的 CRUD 功能。

 使用jpa时我们创造的接口在继承Repository时要在泛型中填写对应表的实体类,和主键类型.

public interface CrudRepository<T, ID> extends Repository<T, ID> {

  <S extends T> S save(S entity);           //1   

  Optional<T> findById(ID primaryKey);      //2

  Iterable<T> findAll();                    //3

  long count();                             //4   

  void delete(T entity);                    //5

  boolean existsById(ID primaryKey);        //6

  // … more functionality omitted.
}
1保存给定的实体。
2返回由给定 ID 标识的实体。
3返回所有实体。
4返回实体数。
5删除给定实体。
6指示具有给定 ID 的实体是否存在。

此接口中声明的方法通常称为 CRUD 方法。 ListCrudRepository 提供了等效的方法,但它们返回 List ,其中 CrudRepository 方法返回 Iterable

还提供了特定于持久性技术的抽象,例如 JpaRepositoryMongoRepository 。这些接口扩展了 CrudRepository 并公开了底层持久性技术的功能,以及相当通用的持久性技术不可知的接口(如 CrudRepository )。

除了 CrudRepository 之外,还有一个 PagingAndSortingRepository 抽象,它添加了额外的方法来简化对实体的分页访问:

public interface PagingAndSortingRepository<T, ID>  {

  Iterable<T> findAll(Sort sort);

  Page<T> findAll(Pageable pageable);
}

若要访问页面大小为 20 的 User 的第二页,可以执行以下操作:

PagingAndSortingRepository<User, Long> repository = // … get access to a bean
Page<User> users = repository.findAll(PageRequest.of(1, 20));

注意: jpa分页查询, 默认从第0页算第一页

四.命名规则和自定义sql

Spring Data Jpa定义了一些命名规则,可以通过方法名自动生成SQL查询,以下是一些常见的命名规则和对应的where条件:

1.命名规则

命名规则

对应的where条件

findBy + 属性名

属性等于给定值

findBy + 属性名 + Between

属性在两个值之间

findBy + 属性名 + LessThan

属性小于给定值

findBy + 属性名 + GreaterThan

属性大于给定值

findBy + 属性名 + Like

属性模糊匹配

findBy + 属性名 + In

属性在给定集合中

findBy + 属性名 + Not

属性不等于给定值

findAllBy + 属性名 + OrderBy + 属性名 + Desc/Asc

根据属性排序

2.自定义sql

除了使用命名规则自动生成SQL查询,还可以使用@Query注解手动编写SQL查询,如下面的例子:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    @Query("SELECT u FROM User u WHERE u.firstName = :firstName AND u.lastName = :lastName")
    List<User> findByFirstNameAndLastName(@Param("firstName") String firstName, @Param("lastName") String lastName);

}

在@Query注解中可以编写自定义的SQL查询语句,使用:参数名来引用方法参数。同时,还可以使用@Param注解来指定方法参数名和SQL语句中的参数名对应关系。

总之,Spring Data Jpa提供了多种查询方法,开发者可以根据实际情况选择最适合的方法进行查询。

下面是一个使用Spring Data JPA完成的连表查询案例:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    @Query(value = "SELECT u.id, u.name, r.role_name FROM user u LEFT JOIN user_role ur ON u.id = ur.user_id LEFT JOIN role r ON ur.role_id = r.id WHERE u.id = :userId", nativeQuery = true)
    List<Object[]> findUserAndRoleById(@Param("userId") Long userId);

}

在这个案例中,我们使用了原生SQL语句来进行连表查询。通过LEFT JOIN将user表、user_role表和role表连接起来,然后使用WHERE条件过滤出指定用户的信息。最后,使用@Query注解将SQL语句与方法关联起来。

在返回值中,我们使用了Object[]类型来存储查询结果。数组中的第一个元素是用户的id,第二个元素是用户的姓名,第三个元素是用户的角色名。

需要注意的是,在使用原生SQL进行查询时,返回值的类型应该与查询结果的数据类型相匹配。否则,程序可能会抛出类型转换异常等错误。

3.@Query注解

@Query注解使用起来很简单,默认的属性是value,就是当前写的SQL语句,有时会用到nativeQuery属性,这个属性是用来标记当前的SQL是本地SQL,还是符合JPA语法规范的SQL。这里需要解释一下本地SQL和JPA语法规范的SQL区别。

本地SQL,是根据实际使用的数据库类型写的SQL,这种SQL中使用到的一些语法格式不能被JPA解析以及可能不兼容其他数据库,这种SQL称为本地SQL,此时需要将nativeQuery属性设置为true,否则会报错。

JPA语法规范的SQL,往往这种SQL本身是不适用于任何数据库的,需要JPA将这种SQL转换成真正当前数据库所需要的SQL语法格式。

	@Query("select u from JpaUser u")
    List<JpaUser> findQuan();

	@Query("from JpaUser")
    List<JpaUser> findQuan2();

    @Query("select u from JpaUser u where u.createdBy=:cb and u.name=:nm")
    JpaUser findUser(@Param("cb") String createBy, @Param("nm") String name);

    @Query("select u from JpaUser u where u.createdBy=?1 and u.name=?2")
    JpaUser findUser2(String createBy, String name);

在SQL上使用占位符的两种方式,第一种是使用":“后加变量的名称,第二种是使用”?“后加方法参数的位置。如果使用”:“的话,需要使用@Param注解来指定变量名;如果使用”?"就需要注意参数的位置。

SQL语句中直接用实体类代表表名,因为在实体类中使用了@Table注解,将该实体类和表进行了关联

4.@Modifying注解

相信在正常的项目开发中都会涉及到修改数据信息的操作,如逻辑删除、封号、解封、修改用户名、头像等等。在使用JPA的时候,如果@Query涉及到update就必须同时加上@Modifying注解,注明当前方法是修改操作。

	@Transactional
    @Modifying
    @Query("update JpaUser u set u.name=:#{#obj.name} where u.createdBy=:#{#obj.createdBy}")
    int update2(@Param("obj") JpaUser jpaUser);

    @Transactional
    @Modifying
    @Query(value = "insert into jpa_user(id, name, created_by) values (:#{#obj.id}, :#{#obj.name}, :#{#obj.createdBy})", nativeQuery = true)
    int add(@Param("obj") JpaUser jpaUser);

经常使用的查询方式:

关键字

方法命名

sql where字句

And

findByNameAndPwd

where name = ? and pwd= ?

Or

findByNameOrSex

where name = ? or sex =?

Between

findByIdBetween

where id between ? and ?

LessThan

findByIdLessThan

where id <?

LessThanEqual

findByIdLessThanEqual

where id <=?

GreaterThan

findByIdGreaterThan

where id > ?

GreaterThanEqual

findByIdGreaterThanEqual

where id >= ?

After

findByIdAfter

where id > ?

Before

find ByIdBefore

where id < ?

IsNull

findByNameIsNull

where name is null

IsNotNull,NotNull

findByNameIsNotNullfindByNameNotNull

where name is not null

Like

findByNameLike

where name like ?

NotLike

findByNameNotLike

where name not like ?

StartingWith

findByNameStartingWith

where name like ‘?%’

EndingWith

findByNameEndingWith

where name like ‘%?’

Containing

findByNameContaining

where name like ‘%?%’

OrderBy

findByIdOrderByAgeDescAndIdAsc

where id = ? order by age desc,id asc

Not

findByNameNot

where name <> ?

In

findByNameIn

where name in (?)

NotIn

findByIdNotIn

where id not in (?)

True

findByDelStatusTrue

where delStatus = true

False

findByDelStatusFalse

where delStatus = false

IgnoreCase

findByNameIgnoreCase

where UPPER(name) = UPPER(?)

举例说明:

select * 
from t_user 
where 
user_name like '%er' 
and id >=100 
and (age between 20 and 35)  
order by age DESC,id ASC
List<User> findByUserNameLikeAndIdGreaterThanEqualAndAgeBetweenOrderByAgeDescAndIdAsc(String userName,Long id,Integer startAge,Integer endAge);

说明:userName、id分别匹配前面两个参数,由于age是between范围查询,是在两个值之间,需要对应到两个参数。所以做种的参数是四个,且位置要按照顺序传入,不能错位.

模糊查询

List<User> findByUserNameLike(String userName);        //1
List<User> findByUserNameNotLike(String userName);     //2
List<User> findByUserNameStartingWith(String userName);//3   
List<User> findByUserNameEndingWith(String userName);  //4
List<User> findByUserNameContaining(String userName);  //5

1:表示按照userName字段模糊查询,会自动加上like关键字,但是不会在userName对应的值上面添加%或者_,需要在传入值的时候,手动将占位符和实际值组装起来;

2:会自动加上not like关键字,占位符需要自己手动添加;

3:自动加上like关键字,这里不需要手动添加占位符,会自动在字段值的前面加上%,转换后:like '%Joker';

4:和第三句差不多,差别就是占位符%放置的位置调整,放在了字段值的后面;

5:相当于第三句和第四句的综合,会在字段值的前后加上占位符%。

五.实体类主键策略

1.Mysql自增长主键策略:GenerationType.IDENTITY

@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
  • 当生成策略为IDENTITY时,@GeneratedValue单独使用
  • @GeneratedValue(strategy = GenerationType.IDENTITY),只需要这一个注解就可以实现mysql的主键自增长,我们知道mysql建表的时候可以给主键声明auto_increment,这就实现了自增长了,所以注解也相对简单。

在@GeneratedValue注解中我们只需要生成策略为IDENTITY,即可完成mysql数据库的主键自增长。

2.万能自增长主键策略:GenerationType.TABLE

@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.TABLE, generator = "sequence_table")
@TableGenerator(name = "sequence_table",
allocationSize = 1,
table = "sequence_table",
pkColumnName = "sequence_name",
valueColumnName = "sequence_count")
private Long id;
  • 当生成策略为TABLE时,@GeneratedValue要配合@TableGenerator使用
  • @TableGenerator(name = "id_sequence", allocationSize = 1, table = "sequence_table",pkColumnName = "sequence_max_id", valueColumnName = "sequence_count"),它代表着需要在数据库建立一张索引表来帮助我们实现主键自增
    • name属性值:建立的索引表在java中要映射成的名字
    • allocationSize属性值:这个序列的自增长步长是几
    • table属性值:建立的序列表的表名,缺省值:SEQUENCE
    • pkColumnName属性值:建立的序列表的第一个列的列名,此列自动填充需要序列作为主键自增长的表的表名,缺省值:SEQ_NAME
    • valueColumnName属性值:建立的序列表的第二个列的列名,此列自动填充pkColumnName所代表的表的下一个序列值,缺省值:SEQ_COUNT
  • @GeneratedValue(strategy = GenerationType.TABLE, generator = "id_sequence"),代表着这个主键采取什么样的生成策略,和Oracle中的解释一样
    • strategy属性值:采取的主键策略是什么
    • generator属性值:使用的映射名是什么,这个映射名就是@SequenceGenerator中name的值

spring:
jpa:
hibernate:
ddl-auto: update #自动更新
show-sql: true #日志中显示sql语句
  • ddl-auto: create:启动时删除上一次生成的表,并根据实体类生成表,表中数据会被清空

    ddl-auto: create-drop:启动时根据实体类生成表,程序关闭时表会被删除

    ddl-auto: update:启动时会根据实体类生成表,当实体类属性变动的时候,表结构也会更新,在初期开发阶段使用此选项

    ddl-auto: validate:启动时验证实体类和数据表是否一致,在数据结构稳定时采用此选项

    ddl-auto: none:不采取任何措施

    建议只使用update和none,前者适合初期建表,后者适合建表完成后保护表结构

  • show-sql: true,这个属性代表是否开启显示sql语句,为true我们就可以在每一次对数据库的操作在控制台看到所使用的sql语句了,方便找错,很方便的属性,建议开发时开启,上线后关闭

ddl-auto: update时,jpa会根据实体类帮助我们创建表~

3.AUTO自动判断主键策略(缺省策略)

@Id

@Column(name = "ID")

@GeneratedValue(strategy = GenerationType.AUTO)

private Long id;
  • 当生成策略为AUTO时,@GeneratedValue单独使用
  • @GeneratedValue(strategy = GenerationType.AUTO),JPA会自己从从 Table 策略,Sequence 策略和 Identity 策略三种策略中选择合适的主键生成策略;
    • strategy属性值:主键生成策略,什么都不写即缺省值即为AUTO

4.总结-主键策略

1.主键生成策略分为四种:SEQUENCE策略、IDENTITY策略、TABLE策略、AUTO策略;

2.SEQUENCE策略适合拥有序列的数据库,比如Oracle;

3.IDENTITY策略适合拥有主键自增长的数据库,比如Mysql;

4.TABLE策略是通过一张序列表来维护主键插入的值的,所以适合所有数据库;

5.AUTO策略是jpa自行判断使用上面三个中的哪一个作为主键生成策略;

6.推荐使用SEQUENCE和IDENTITY策略,开发人员应该自行判断使用的是何种数据库,而不是由jpa进行判断。

六.自动注入字段属性

  • @Version:版本号;进行update操作时启动乐观锁,@Version修饰的字段值与数据库中字段值一致才能进行修改
  • @CreatedDate :创建时间;进行insert操作时,将当前时间插入到@CreatedDate修饰字段中;进行update操作时,会随实体类中的@CreatedDate修饰的字段值进行修改
  • @CreatedBy:创建人;进行insert操作时,将当前用户名插入到@CreatedBy修饰字段中;进行update操作时,会随实体类中的@CreatedBy修饰的字段值进行修改
  • @LastModifiedDate:最后一次修改时间;进行update操作时,将当前时间修改进@LastModifiedDate修饰字段中;进行insert操作时,将当前时间插入到@LastModifiedDate修饰字段中
  • @LastModifiedBy :最后一次修改的修改人;进行update操作时,将当前修改人修改进@LastModifiedBy修饰的字段中;进行insert操作时,将当前用户名插入到@LastModifiedBy修饰字段中

1.启动审计

1.1在Springboot启动类上加上启动审计注解:@EnableJpaAuditing

@EnableJpaAuditing
@SpringBootApplication
public class SpringContextApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringContextApplication.class, args);
    }
}

1.2在实体类上方加上监听注解:@EntityListeners(AuditingEntityListener.class)

@Data
@Entity
@Table(name = "JPA_USER")
@EntityListeners(AuditingEntityListener.class)
public class JpaUser {
    //...
}
  • @EntityListeners该注解用于指定Entity或者superclass上的回调监听类;
  • AuditingEntityListener这个类是一个JPA Entity Listener,用于捕获监听信息,当Entity发生新增和更新操作时进行捕获。

当设置完这两个注解后@CreatedDate、@LastModifiedBy这两个注解对于创建时间和修改时间的注入就ok了,但是对创建人、修改人的注入却为null,毕竟jpa并不知道当前是谁在操作数据,需要我们来进行提供.

2.注入创建人和更新人

2.1建立配置文件夹config,创建配置类UserAuditor

import com.itszt22.springdatajpa.entity.JpaUser;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.AuditorAware;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Optional;

//将来JpaUser入库的时候, Jpa会自动调用getCurrentAuditor方法, 将返回的结果, 自动插入到对象的创建人和更新人字段中
@Configuration
public class UserAuditor implements AuditorAware<String> {

    /**
     * - *获取当前创建或修改的用户*
     * - **
     * - *@return 获取当前创建或修改的用户Uid*
     * -
     */
    @Override
    public Optional<String> getCurrentAuditor() {
        HttpServletRequest request;

// 工号
        String username = "anonymous";
// 拿到Session
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        if (requestAttributes != null) {
            request = requestAttributes.getRequest();
            HttpSession session = request.getSession();
            Object obj = session.getAttribute("jpaUser");
            if (obj instanceof JpaUser) {
                JpaUser jpaUser = (JpaUser) obj;

                username = jpaUser.getName();

            }

            username = request.getParameter("username");

        }

        return Optional.of(username);
    }

}

很容易理解的一个配置,它返回一个Optional<String>对象,对象内的String值便是创建人和更新人根据实际情况去注入的值。

关于Optional<?>,不了解的同学可以去度娘,java8很好的一个防止空指针的类

session大家应该耳熟能详,但一般我们是在controller层拿到request,再拿session,或者直接在controller层拿到session,在其他非controller类中如何拿session呢,使用RequestContextHolder上下文容器

具体解析一下代码:

  • 声明一个HttpServletRequest对象request,声明一个username字符串,默认值为anonymous(匿名)
  • 通过RequestContextHolder拿到request的属性,转换成可以得到request对象的ServletRequestAttributes
  • 判断是否当前线程的请求属性为空,为空则直接返回username默认值,不为空继续
  • 不为空就可以拿到我们熟悉的request对象啦,它里面存着session信息
  • 用Object类接收约定好的key值(我这里叫jpaUser),如果存储了session,那么拿到的对象类型一定是JpaUser,进行强转后拿到存储在其中的name值
  • 再返回拥有真实用户名的username,接下来就交给jpa审计去注入了

七.springboot中使用Jpa

1.引入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

2.application.yml配置文件

spring:
  datasource:
#    url配置有一个自动建库的配置, 很重要的前提 mysql安装的时候已经配置了utf8mb4默认字符集
    url: jdbc:mysql://这里填自己的ip地址:3306/jpa?createDatabaseIfNotExist=true&useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: xxx
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update #自动更新
    show-sql: true #日志中显示sql语句

注意: 这个jpa启动的时候会自动建表, 先检查有没有表名称, 如果有, 则不创建, 否则建表; 如果实体类结构发生修改, 也会自动修改对应的表结构.

3.springboot启动类

        除了@SpringBootApplication启动注解外,还有一个注解@EnableJpaAuditing,它是用来启动Jpa的审计功能,比如说在使用建表中经常会加入 版本号、创建时间、修改时间 、创建者、修改者 这五个字段。因此为了简化开发, 我们可以将其交给jpa来自动填充。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;


@EnableJpaAuditing
@SpringBootApplication
public class DemojpaApplication {


   public static void main(String[] args) {
      SpringApplication.run(DemojpaApplication.class, args);
   }


}

4.CRUD增删改查

实体类

@Data
@Entity
@Table(name = "JPA_USER")
@EntityListeners(AuditingEntityListener.class)
public class JpaUser {

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "NAME")
    private String name;

    @Column(name = "OBJECT_VERSION" )
    @Version
    private Long objectVersion;

    @Column(name = "CREATED_BY")
    @CreatedBy
    private String createdBy;

    @Column(name = "CREATED_DATE")
    @CreatedDate
    private Date createdDate;

    @Column(name = "LAST_UPDATED_BY" )
    @LastModifiedBy
    private String lastUpdatedBy;

    @Column(name = "LAST_UPDATED_DATE" )
    @LastModifiedDate
    private Date lastUpdatedDate;
}

public interface JpaUserRepository extends JpaRepository<JpaUser, Long> {

}

1.增加

@RestController
@RequestMapping(value = "/jpa")
public class JpaTestController {

    @Autowired
    private JpaUserRepository jpaUserRepository;

    @PostMapping(value = "/add")
    public JpaUser addUser(@RequestBody JpaUser user) {
        return jpaUserRepository.save(user);
    }
}

2.删除

@RestController
@RequestMapping(value = "/jpa")
public class JpaTestController {

    @Autowired
    private JpaUserRepository jpaUserRepository;

    @DeleteMapping(value = "/delete/{id}")
    public void deleteUser(@PathVariable("id") Long id) {
        jpaUserRepository.deleteById(id);
    }
}

3.修改

@RestController
@RequestMapping(value = "/jpa")
public class JpaTestController {

    @Autowired
    private JpaUserRepository jpaUserRepository;

    @PutMapping(value = "/update")
    public JpaUser updateUser(@RequestBody JpaUser user) {
        return jpaUserRepository.save(user);
    }
}

4.查询

@RestController
@RequestMapping(value = "/jpa")
public class JpaTestController {

    @Autowired
    private JpaUserRepository jpaUserRepository;

    @GetMapping(value = "/get/{id}")
    public Optional<JpaUser> getUserById(@PathVariable("id") Long id) {
        return jpaUserRepository.findById(id);
    }

    @GetMapping(value = "/get_all")
    public List<JpaUser> getAllUsers() {
        return jpaUserRepository.findAll();
    }
}

最后安利大家看一个very wonderful 的电视剧,那就是少年歌行,特别好看...(♥∀♥)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值