SpringBoot在项目中结合Lombok使用Jpa(SpringDataJpa快速入门)实现增删改查

SpringBoot项目中使用Jpa(SpringDataJpa)


前言

  • 请查看博主的SpringDataJpa系列文章。欢迎关注!

  • JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关 系,并将运行期的实体对象持久化到数据库中。

  • 在ORM框架中,Hibernate是一支很大的部队,使用很广泛,也很方便,能力也很强,同时Hibernate也是和JPA整 合的比较良好,我们可以认为JPA是标准,事实上也是,JPA几乎都是接口,实现都是Hibernate在做,宏观上面看,在 JPA的统一之下Hibernate很良好的运行。

  • 我们都知道Spring的强大,到目前为止,企业级应用Spring几乎是无所不能,无所不在,已经是事实上的标准了, 企业级应用不使用Spring的几乎没有。而Spring整合第三方框架的能力又很强,他要做的不仅仅是个最早的IOC容器这 么简单一回事,现在Spring涉及的方面太广,主要是体现在和第三方工具的整合上。而在与第三方整合这方面,Spring 希望把持久化这块内容也拿下。于是就有了Spring-data-**这一系列包。包括,Spring-data-jpa,Spring-data- template,Spring-data-mongodb,Spring-data-redis,还有个民间产品,mybatis-spring,和前面类似,这是和 mybatis整合的第三方包,这些都是干的持久化工具干的事儿。

  • 这里介绍Spring-data-jpa,表示与Jpa的整合

  • SpringData:其实SpringData就是Spring提供了一个操作数据的框架。而SpringData JPA只是SpringData框架下的一个基于JPA标准操作数据的模块,总得包括以下:

    • ORM映射:支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系
    • API:操作实体对象来执行CRUD操作
    • 查询语言:通过面向对象而非面向数据库的查询语言(JPQL)查询数据,避免程序的SQL语句紧密耦合
  • SpringDataJPA:基于JPA的标准数据进行操作。简化操作持久层的代码。只需要编写接口就可以。

  • 后面博主会陆续写出Jpa的关联关系和增删改查以及连表查询操作,欢迎关注


什么是Spring Data Jpa

Spring Data Jpa是Spring Data家族的一部分,Spring Data JPA相对于Java EE中的JPA,配置更简单,以轻量级的方式实现了部分在 EJB 容器环境下才具有的功能,将 EntityManager 的创建与销毁、事务管理等代码抽取出来,并由其统一管理,并且极大的简化了数据库访问层的代码。
Spring Data包含众多子项目除了JPA还有Spring Data MongoDB等等


SpringJpa的运行原理

  1. SpringJPA的全称是Spring Data JPA 。其中JPA是Java Persistence API的缩写(Java持久化API),是
    SUN公司推出的一套接口,一套标准,Hibernate是一个具体的ORM的持久层框架(类似于Mybatis框
    架)实现了JPA接口 。
  2. Spring Data是Spring开发团队提供的一套标准API和不同持久层整合技术实现。Spring Data的出现就
    是为了简化、统一持久层的各种实现技术API。 (注:Spring Data在项目里以spring-data-commons这个jar存在 )
  3. Spring Data JPA既实现了Spring Data接口又实现了JPA接口,也是为了简化持久层的开发。
    注:Spring Data JPA在项目里以spring-data-jpa这个jar存在

SpringJpa优点

  1. 提供统一的接口,可避免我们再次重复的编写基础的DAO类;
  2. 遵循JPA规范,同时也提供了灵活的数据访问方式;
  3. 通过方法名即可自动生成HQL语句;
  4. 通过接口自动注入实现类,实现非常简单。

Spring Data JPA与MyBatis对比

Spring Data JPA与MyBatis对比,实际上就是Hibernate与MyBatis的对比,具体如下:

从基本概念和框架目标上看,两个框架差别还是很大的。 hibernate是一个自动化更强、更高级的框架,毕竟在java代码层面上,省去了绝大部分sql编写,取而代之的是 用面向对象的方式操作关系型数据库的数据。 MyBatis则是一个能够灵活编写sql语句,并将sql的入参和查询结果映射成POJOs的一个持久层框架。所以,从表 面上看,hibernate能方便、自动化更强,而MyBatis 在Sql语句编写方面则更灵活自由。

注:至于这两个框架用哪一个,可以根据自己的掌握情况或者使用场景进行选择。我个人推荐使用Spring
Data JPA,因为的确很简单,符合敏捷开发要求。


SpringBoot引入SpringDataJpa依赖


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

在yml文件配置如下,按需索取

spring:
  datasource:
    url:  jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
    username: root
    password: root
  jpa:
    database: mysql
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    show-sql: true
    hibernate:
      ddl-auto: update # 一般使用update
        # create: 每次运行程序时,都会重新创建表,故而数据会丢失
        # create-drop: 每次运行程序时会先创建表结构,然后待程序结束时清空表
        # upadte: 每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)
        # validate: 运行程序会校验数据与数据库的字段类型是否相同,字段不同会报错
        # none: 禁用DDL处理

这里贴出来博主的一些配置:



    4.0.0
    com.jmccms
    Jmccms
    0.0.1-SNAPSHOT
    Jmccms
    https://repo.spring.io/milestone
    CYJ:ChenYongJia 服务提供者Jmccms

    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.5.RELEASE
         
    

    
    
        UTF-8
        UTF-8
        1.8
        
        Greenwich.RELEASE
        5.1.39
        4.12
        1.0.18
        
    

    

        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-actuator
        

        
        
            org.springframework.boot
            spring-boot-starter-aop
        

        

        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        

        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix
        

        
        
        
            org.springframework.cloud
            spring-cloud-starter-oauth2
        

        
        
            org.springframework.cloud
            spring-cloud-starter-openfeign
        

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

        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
        
            junit
            junit
        

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

        
        
            org.springframework.boot
            spring-boot-starter-jdbc
        

        
        
            org.springframework.boot
            spring-boot-starter-security
        

        
        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        

        
        
            mysql
            mysql-connector-java
            ${mysql-connector}
        

        
        
            org.projectlombok
            lombok
            true
        

        
        

        
        
            com.alibaba
            fastjson
            1.2.56
        

        
        
            com.google.code.gson
            gson
            2.8.5
        

        
        
            com.alibaba
            easyexcel
            1.1.2-beta5
        

        

        
        
            org.apache.commons
            commons-lang3
            
            3.6
            provided
        

        
        
            org.apache.httpcomponents
            httpclient
            4.5.8
        

        
        

        

        

        
        
            io.springfox
            springfox-swagger2
            2.9.2
        

        
        
            io.springfox
            springfox-swagger-ui
            2.9.2
        

        
        
            eu.bitwalker
            UserAgentUtils
            1.21
        

    

    
    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                
                ${spring-cloud.version}
                
                pom
                import
            
        
    

    
        
            
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
        
        jmccms
    

    
    
        
            spring-milestones
            Spring Milestones
            https://repo.spring.io/milestone
            
                false
            
        
    



使用Spring Data Jpa增删改查(当然一般都和lombok结合使用)

第一步先创建你的数据库和配置文件保持一致,Jpa将自动帮你建表

package com.jmccms.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

/**
 * @Description: 用户类
 * @BelongsProject: Jmccms
 * @BelongsPackage: com.jmccms.entity
 * @Author: ChenYongJia
 * @CreateTime: 2019-05-02 15:32
 * @Email [email protected]
 */
@Getter
@Setter
@AllArgsConstructor // 自动所有参数的构造方法方法
@NoArgsConstructor // 自动无参的构造方法方法
@Builder
@Entity
@Table(name = "jmccms_user")
public class User implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @OrderBy
    @Column(columnDefinition = "bigint(19) unsigned  COMMENT '用户id'")
    private Long userId;
    @Column(columnDefinition = "varchar(64) NOT NULL COMMENT '用户名称'  ")
    private String userName;
    @Column(columnDefinition = "varchar(100) NOT NULL COMMENT '用户密码'  ")
    private String userPassWord;
    @Column(columnDefinition = "datetime COMMENT '用户创建时间' ")
    @JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")	//日期格式化为中国的时区 东8区
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")	//接受::字符串日期需要格式化为日期类型
    private Date userCreateTime;
    @Column(columnDefinition = "datetime COMMENT '用户最后一次登录时间' ")
    @JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")	//日期格式化为中国的时区 东8区
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")	//接受::字符串日期需要格式化为日期类型
    private Date userLastLoginTime;
    @Column(columnDefinition = "timestamp COMMENT '最后一次修改时间'", nullable = false, updatable = false, insertable = false)
    @JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")	//日期格式化为中国的时区 东8区
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")	//接受::字符串日期需要格式化为日期类型
    private Timestamp userLastUpdateTime;
    @Column(columnDefinition = "varchar(64) NOT NULL COMMENT '创建人'  ")
    private String userFounder;
    @Column(columnDefinition = "varchar(64) COMMENT '修改人'  ")
    private String userUpdateMan;

    @JsonIgnore
    @ManyToMany(fetch = FetchType.EAGER) // 指定多对多关系
    @Cascade(value = { CascadeType.ALL }) // 设置级联关系
    @JoinTable(name = "jmccms_user_role", // 指定第三张中间表名称
            joinColumns = { @JoinColumn(name = "user_id") }, // 本表主键userId与第三张中间表user_role_tb的外键user_role_tb_user_id对应
            inverseJoinColumns = { @JoinColumn(name = "role_id") }) // 多对多关系另一张表与第三张中间表表的外键的对应关系
    @NotFound(action = NotFoundAction.IGNORE) // NotFound : 意思是找不到引用的外键数据时忽略,NotFound默认是exception
    private Set rolesSet = new HashSet<>();// 用户所拥有的角色集合

}

  • 建立数据库访问层
    • 使用Spring Data JPA建立数据库十分简单,只需要定义一个继承了JpaRepository的接口,下面是博主项目的一个类,可以参照
package com.jmccms.dao;

import com.jmccms.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import javax.transaction.Transactional;
import java.util.List;

/**
 * @Description: 用户接口
 * @BelongsProject: Jmccms
 * @BelongsPackage: com.jmccms.dao
 * @Author: ChenYongJia
 * @CreateTime: 2019-05-02 18:05
 * @Email [email protected]
 */
public interface UserRepository extends JpaRepository, JpaSpecificationExecutor {

    /**
     * 根据用户名和密码查询用户
     * @return
     */
    User findByUserNameAndUserPassWord(String userName, String userPassWord);

    /**
     * 根据用户名查询用户
     * @return
     */
    User findByUserName(String userName);

    /**
     * 根据用户id查询用户信息
     * @param userId
     * @return
     */
    User findByUserId(Long userId);

    /**
     * 批量删除用户信息
     *
     * @param userList
     * @return
     */
    @Query(value = "DELETE FROM jmccms_user WHERE user_id IN (:userList)", nativeQuery = true)
    @Modifying
    @Transactional
    Integer deleteUser(@Param(value = "userList") List userList);

    /**
     * 根据ID查询用户角色
     *
     * @param userId
     * @return
     */
    @Query(value = "SELECT role_id FROM jmccms_user_role WHERE 1=1 AND user_id=:usersId ", nativeQuery = true)
    List getUserRole(@Param(value = "usersId") Long userId);

}
  • 继承了JpaRepository就相当于有了下面的数据访问操作方法,这些都是Spring Data Jpa封装好的。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.data.jpa.repository;

import java.util.List;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;

@NoRepositoryBean
public interface JpaRepository extends PagingAndSortingRepository, QueryByExampleExecutor {
    List findAll();

    List findAll(Sort var1);

    List findAllById(Iterable var1);

     List saveAll(Iterable var1);

    void flush();

     S saveAndFlush(S var1);

    void deleteInBatch(Iterable var1);

    void deleteAllInBatch();

    T getOne(ID var1);

     List findAll(Example var1);

     List findAll(Example var1, Sort var2);
}

支持的关键字、示例及JPQL片段如下表所示:

Keyword Sample JPQL Snippet
And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
Is,Equals indByFirstname,findByFirstnameIs,findByFirstnameEquals … where x.firstname = ?1
Between findByStartDateBetween … where x.startDate between ?1 and ?2
LessThan findByAgeLessThan … where x.age < ?1
LessThanEqual findByAgeLessThanEqual … where x.age <= ?1
GreaterThan findByAgeGreaterThan … where x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1
After findByStartDateAfter … where x.startDate > ?1
Before findByStartDateBefore … where x.startDate < ?1
IsNull findByAgeIsNull … where x.age is null
IsNotNull,NotNull findByAge(Is)NotNull … where x.age not null
Like findByFirstnameLike … where x.firstname like ?1
NotLike findByFirstnameNotLike … findByFirstnameNotLike
StartingWith findByFirstnameStartingWith … where x.firstname like ?1 (parameter bound with appended %)
EndingWith findByFirstnameEndingWith … where x.firstname like ?1 (parameter bound with prepended %)
Containing findByFirstnameContaining … where x.firstname like ?1 (parameter bound wrapped in %)
OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
Not findByLastnameNot … where x.lastname <> ?1
In findByAgeIn(Collection ages) … where x.age in ?1
NotIn findByAgeNotIn(Collection ages) … where x.age not in ?1
True findByActiveTrue() … where x.active = true
False findByActiveFalse() … where x.active = false
IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstame) = UPPER(?1)

更多详细内容请参照:官方文档4.4.3. Property Expressions


好了到这里也该结束了,不能全部给你们不是,各位要自己多动手才能学到真正的东西。加油各位


最后

  • 更多参考精彩博文请看这里:《陈永佳的博客》

  • 喜欢博主的小伙伴可以加个关注、点个赞哦,持续更新嘿嘿!


你可能感兴趣的:(SpringDataJpa系列,为霞而作)