SpringBoot + Jpa Detailed Usage Tutorial (Enterprise Development and Usage Summary)

Introduction to JPA

JPA (Java Persistence API), Object Relational Mapping (ORM) framework specification, is a Java persistence specification. jpa can generate database tables through entity classes. At the same time, it comes with many methods for adding, deleting, modifying and checking. Most of the sql statements do not need to be written by ourselves. After the configuration is completed, you can directly call the method, which is very convenient.

Simple JPA usage example

1. pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data JPA 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
 <!-- mysql驱动 依赖 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

2. application.properties configuration

# 数据库连接配置
spring.datasource.url = jdbc:mysql://localhost:3306/manageserver?serverTimezone=Asia/Shanghai
spring.datasource.username = root
spring.datasource.password = 123456
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
# jpa配置
# 自动更新数据库表
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
# 是否在控制台显示Hibernate的sql
spring.jpa.show-sql = false

3. Create an entity class object for mapping database tables

@Table(name="db_dictionary")
@Data
@Entity
public class DbDictionary implements Serializable {

    @Id
    @GenericGenerator(name = "faceset_generator", strategy = "uuid")
    @GeneratedValue(generator = "faceset_generator")
    @Column
    private String id;

    /**
     * 类型名称
     */
    @Size(max = 50)
    @Column
    @NotNull
    private String type;

    /**
     * 中文
     */
    @Column
    @NotNull
    private String name;

    /**
     * 代码
     */
    @Column
    @NotNull
    private String code;


    /**
     * 顺序
     */
    private Integer sort;

    /**
     * 描述信息
     */
    @Column
    private String remark;


    private static final long serialVersionUID = 1L;
}

4. Create a persistent interface DAO, 继承JpaRepositorywhich is used to operate on the database

@Repository
public interface DictionaryDao extends JpaRepository<DbDictionary, String> {
}

5. So far, the basic configuration of JPA has been completed. There are many built-in methods for adding, deleting, modifying and checking. We don’t need to write sql statements ourselves, just call them directly.

Relevant annotations in JPA entity classes

  • @Entity: Indicates that it is an entity class
  • @Table(name = "dict_info"): The corresponding data table name, used together with the @Entity annotation, but if the table name is the same as the entity class name, @Table can be omitted
  • @GenericGenerator(name = "jpa-uuid", strategy = "uuid"): Custom hibernate primary key generation strategy
  • @Id: Indicates that the current field is the primary key
  • @GeneratedValue(generator = "jpa-uuid"): Specify the primary key generation strategy as uuid
  • @Column(name = "DICTNAME"): When the attribute of the entity class has a different name from the column of the database table it maps to, you need to use the @Column annotation
  • @CreatedDate: creation time
  • @LastModifiedDate: update time
  • @Temporal(TemporalType.TIMESTAMP): The entity class will be encapsulated into the Date type of the complete time "yyyy-MM-dd hh:MM:ss"
  • @Transient: Indicates that this attribute is not a mapping to a field in a database table, and the ORM framework will ignore this attribute

JPA Persistence Layer Keyword Description

The usage mode of JPA Data has helped me integrate some daily keyword usage, which can be used directly through query!

keywords method naming sql where clause
And findByNameAndPwd where name= ? and pwd =?
Or findByNameOrSex where name= ? or sex=?
Is,Equals findById,findByIdEquals where id= ?
Between findByIdBetween where id between ? and ?
LessThan findByIdLessThan where id < ?
LessThanEquals findByIdLessThanEquals where id <= ?
GreaterThan findByIdGreaterThan where id > ?
GreaterThanEquals findByIdGreaterThanEquals where id > = ?
After findByIdAfter where id > ?
Before findByIdBefore where id < ?
IsNull findByNameIsNull where name is null
isNotNull,NotNull findByNameNotNull 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 findByIdOrderByXDesc where id=? order by x desc
Not findByNameNot where name <> ?
In findByIdIn(Collection<?> c) where id in (?)
swimming findByIdNotIn(Collection<?> c) where id not in (?)
True findByAaaTue where aaa = true
False findByAaaFalse where aaa = false
IgnoreCase findByNameIgnoreCase where UPPER(name)=UPPER(?)

Actual combat: JPA enterprise development example

1. Entities inherit basic common properties

/**
 * 实体继承映射类基础 ,保存实体的通用属性
 *
 * @date: 2022-05-29
 * @author: Buckletime
 */
@Data
@Accessors(chain = true)
@MappedSuperclass   //实体继承映射
public abstract class BaseEntity implements Serializable {
    
    

    /**
     * 创建者
     */
    @Basic
    @Column(length = 50)
    private String creator;

    /**
     * 修改者
     */
    @Basic
    @Column(length = 50)
    private String modifier;

    /**
     * 创建时间
     */
    @Basic
    @Column(name = "create_time")
    @CreatedDate
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;

    /**
     * 修改时间
     */
    @Basic
    @Column(name = "update_time")
    @LastModifiedDate
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;

}

2. Query

2.1 Condition query

There are two ways to query conditions, one is to directly use the keywords provided by the persistence layer, and the other is to write the query SQL yourself.

// 根据名称和性别查询用户
User findByNameAndSex(String name, String sex);
@Query(nativeQuery = true, value = "select * from user where name = :name and sex = :sex")
User findByNameAndSex(@Param("name") String name, @Param("sex") String sex);

2.2 Query sorting

List<T> findAll(Sort sort);
//按创建时间倒序排列
Sort.by("createTime").descending()

2.3 Pagination query

Page<T> findAll(Pageable pageable);
/*获取分页参数*/
public PageRequest getPageRequest() {
    
    
    return getPageRequest(Sort.unsorted());
}

/*获取分页和排序参数*/
public PageRequest getPageRequest(Sort sort) {
    
    
    ServletRequestAttributes attributes = getServletRequestAttributes();
    if (StringUtils.hasText(attributes.getRequest().getParameter("page")) && StringUtils.hasText(attributes.getRequest().getParameter("size"))) {
    
    
        int page = Integer.parseInt(attributes.getRequest().getParameter("page"));
        int size = Integer.parseInt(attributes.getRequest().getParameter("size"));
        return PageRequest.of(page, size, sort);
    }
    return PageRequest.of(Constants.zero, Constants.ten);
}

2.4 Dynamic condition query

For dynamic condition query Specification, DAO needs to inherit JpaSpecificationExecutothe r interface

List<T> findAll(@Nullable Specification<T> spec);

Specification<ProjectionInfo> spec = (Specification<ProjectionInfo>) (root, query, cb) -> {
    
    
    List<Predicate> predicateList = new ArrayList<>();
    // 时间
    if (null != startTime && null != endTime) {
    
    
        predicateList.add(cb.between(root.get("createTime"), startTime, endTime));
    }
    // 数字
    if (searchDto.getCloud() != null) {
    
    
        predicateList.add(cb.le(root.<Integer>get("cloudPercent"), searchDto.getCloud()));
    }
    // 字符串
    if (searchDto.getName() != null) {
    
    
        predicateList.add(cb.equal(root.get("name"), searchDto.getName()));
    }
    // 列表
    if (StrUtil.isNotEmpty(searchDto.getSatellite())) {
    
    
        String[] satellites = searchDto.getSatellite().split(",");
        Expression<String> exp = root.<String>get("satellite");
        predicateList.add(exp.in(Arrays.asList(satellites)));
    }
    Predicate[] pre = new Predicate[predicateList.size()];
    pre = predicateList.toArray(pre);
    return query.where(pre).getRestriction();
};

2.5 Multi-table joint query

@Query(nativeQuery = true, value = "SELECT satellite, count(id), COALESCE(sum(file_size), 0) FROM t_mas_orbit_info" +
            " WHERE create_time BETWEEN :startTime AND :endTime " +
            " GROUP BY satellite")
List<Object[]> satelliteDataIncreased(@Param("startTime") Date startTime,
                                      @Param("endTime") Date endTime);

2.6 Return custom Vo

@Query(value = "SELECT new cn.piesat.dispatch.model.vo.FileDataVO(p.id, p.fileName,p.stationCode,p.fileSize, p.fileDate, p.createTime, p.state, p.filePath,p.forwardTime) " +
            " FROM DbZxjProductInfoDTO p ")
List<FileDataVO> getFileList();

3. Modification and deletion

When modifying and deleting, you need to add @Modifyingand @Transactionalcomment.

@Query(nativeQuery = true, value = "UPDATE db_order_info SET download_count = (SELECT download_count + 1) WHERE id = :orderId ")
@Modifying
@Transactional
int updateDownloadTimes(String orderId);
@Modifying
@Transactional
void deleteByName(String name);

Step on the pit

1. The delete method must be annotated with @Transactional and @Modifying
2. When customizing the delete method, if the basic type or package type is passed, void deleteByxxx(String s) must be used instead of void deleteAllByxxx(String s).

Because deleteAllByxxx(String s) will be recognized as a query statement by jpa, only use deleteAllByxxx(List<String> s) when the incoming parameter is a list

It is recommended to use native SQL. The built-in delete or deleteAll will query first, and then perform deletions on the query results one by one. It is not a single SQL that deletes the operation, so it is recommended to write delete by yourself

Guess you like

Origin blog.csdn.net/weixin_45698637/article/details/124327479