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 extends Repository {

   S save(S entity);           //1   

  Optional findById(ID primaryKey);      //2

  Iterable 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  {

  Iterable findAll(Sort sort);

  Page findAll(Pageable pageable);
}

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

PagingAndSortingRepository repository = // … get access to a bean
Page 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 {

    @Query("SELECT u FROM User u WHERE u.firstName = :firstName AND u.lastName = :lastName")
    List 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 {

    @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 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 findQuan();

	@Query("from JpaUser")
    List 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 findByUserNameLikeAndIdGreaterThanEqualAndAgeBetweenOrderByAgeDescAndIdAsc(String userName,Long id,Integer startAge,Integer endAge);

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

模糊查询

List findByUserNameLike(String userName);        //1
List findByUserNameNotLike(String userName);     //2
List findByUserNameStartingWith(String userName);//3   
List findByUserNameEndingWith(String userName);  //4
List 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 {

    /**
     * - *获取当前创建或修改的用户*
     * - **
     * - *@return 获取当前创建或修改的用户Uid*
     * -
     */
    @Override
    public Optional 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值便是创建人和更新人根据实际情况去注入的值。

关于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.引入依赖

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

        
            com.mysql
            mysql-connector-j
            runtime
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

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 {

}

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 getUserById(@PathVariable("id") Long id) {
        return jpaUserRepository.findById(id);
    }

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

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

你可能感兴趣的:(java,spring,boot,后端,java,sql)