SpringBoot Jpa企业开发示例详细讲解

 更新时间:2022年11月18日 17:27:45   作者:Buckletime  
这篇文章主要介绍了SpringBoot Jpa企业开发示例,Jpa可以通过实体类生成数据库的表,同时自带很多增删改查方法,大部分sql语句不需要我们自己写,配置完成后直接调用方法即可,很方便

JPA 介绍

JPA(Java Persistence API),对象关系映射(ORM)框架规范,是一种Java持久化规范。jpa可以通过实体类生成数据库的表,同时自带很多增删改查方法,大部分sql语句不需要我们自己写,配置完成后直接调用方法即可,很方便。

JPA 简单使用示例

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配置

# 数据库连接配置
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. 创建实体类对象,用于映射数据库表

@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. 创建持久化接口DAO,继承JpaRepository,用于对数据库进行操作

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

5. 至此,JPA基本配置已经完成,这里自带很多内置的增删改查方法,不用我们自己写sql语句,直接调用即可。

JPA 实体类中相关注解说明

  • @Entity:表明是一个实体类
  • @Table(name = "dict_info"):对应的数据表名,与@Entity注解一块使用,但是如果表名和实体类名相同的话,@Table可以省略
  • @GenericGenerator(name = "jpa-uuid", strategy = "uuid"):自定义hibernate主键生成策略
  • @Id:表示当前字段为主键
  • @GeneratedValue(generator = "jpa-uuid"):指定主键生成策略为uuid
  • @Column(name = "DICTNAME"):当实体类的属性与其映射的数据库表的列不同名时需要使用@Column 标注说明
  • @CreatedDate:创建时间
  • @LastModifiedDate:更新时间
  • @Temporal(TemporalType.TIMESTAMP):实体类会封装成完整的时间“yyyy-MM-dd hh:MM:ss”的 Date类型
  • @Transient:表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性

JPA 持久层关键字说明

JPA Data的使用模式已经帮我集成了日常一些关键字用法,通过查询可以直接使用!

关键字方法命名sql where字句
AndfindByNameAndPwdwhere name= ? and pwd =?
OrfindByNameOrSexwhere name= ? or sex=?
Is,EqualsfindById,findByIdEqualswhere id= ?
BetweenfindByIdBetweenwhere id between ? and ?
LessThanfindByIdLessThanwhere id < ?
LessThanEqualsfindByIdLessThanEqualswhere id <= ?
GreaterThanfindByIdGreaterThanwhere id > ?
GreaterThanEqualsfindByIdGreaterThanEqualswhere id > = ?
AfterfindByIdAfterwhere id > ?
BeforefindByIdBeforewhere id < ?
IsNullfindByNameIsNullwhere name is null
isNotNull,NotNullfindByNameNotNullwhere name is not null
LikefindByNameLikewhere name like ?
NotLikefindByNameNotLikewhere name not like ?
StartingWithfindByNameStartingWithwhere name like ‘?%’
EndingWithfindByNameEndingWithwhere name like ‘%?’
ContainingfindByNameContainingwhere name like ‘%?%’
OrderByfindByIdOrderByXDescwhere id=? order by x desc
NotfindByNameNotwhere name <> ?
InfindByIdIn(Collection<?> c)where id in (?)
NotInfindByIdNotIn(Collection<?> c)where id not in (?)
TruefindByAaaTuewhere aaa = true
FalsefindByAaaFalsewhere aaa = false
IgnoreCasefindByNameIgnoreCasewhere UPPER(name)=UPPER(?)

实战-JPA企业开发示例

1. 实体继承基础通用属性

/**
 * 实体继承映射类基础 ,保存实体的通用属性
 */
@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. 查询

2.1 条件查询

条件查询有两种方式,一是直接使用持久层提供的关键字,二是自己写查询SQL。

// 根据名称和性别查询用户
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 查询排序

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

2.3 分页查询

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 动态条件查询

动态条件查询Specification,DAO需要再继承JpaSpecificationExecutor接口

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 多表联查

@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 返回自定义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. 修改和删除

进行修改和删除时,需要添加@Modifying@Transactional注解。

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

踩坑

1.删除的方法上一定要加@Transactional和@Modifying注解

2.自定义删除方法的时候如果传的是基本类型或者包装类型一定要用 void deleteByxxx(String s) 而不是 void deleteAllByxxx(String s)。

因为deleteAllByxxx(String s)会被jpa识别为查询语句,只有传入参数是列表时才是用deleteAllByxxx(List<String> s)

推荐使用原生sql,自带的delete或者deleteAll会先进行查询,然后在查询结果上面挨个执行删除,并不是一条sql执行完删除操作,所以还是建议自己写delete

到此这篇关于SpringBoot Jpa企业开发示例详细讲解的文章就介绍到这了,更多相关SpringBoot Jpa内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java实现批量向mysql写入数据的方法

    Java实现批量向mysql写入数据的方法

    这篇文章主要介绍了Java实现批量向mysql写入数据的方法,涉及java基于JDBC连接mysql数据库及写入数据的相关操作技巧,非常简单实用,需要的朋友可以参考下
    2017-12-12
  • SpringBoot分页查询功能的实现方法

    SpringBoot分页查询功能的实现方法

    在实际的项目开发过程中,分页显示是很常见的页面布局,所以学习如何实现分页也是必要的,下面这篇文章主要给大家介绍了关于SpringBoot分页查询功能的实现方法,需要的朋友可以参考下
    2022-06-06
  • Java实现自定义重试工具类

    Java实现自定义重试工具类

    这篇文章主要为大家详细介绍了如何基于Java实现自定义重试工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-11-11
  • maven解决依赖冲突的三种解决方法

    maven解决依赖冲突的三种解决方法

    依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成了包版本冲突,本文主要介绍了maven解决依赖冲突的三种解决方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Java中notify和notifyAll的区别及何时使用

    Java中notify和notifyAll的区别及何时使用

    本文主要介绍了Java中notify和notifyAll的区别及何时使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • 解决使用@Component会导致spring.factories中的EnableAutoConfiguration无效问题

    解决使用@Component会导致spring.factories中的EnableAutoConfiguration无效

    这篇文章主要介绍了解决使用@Component会导致spring.factories中的EnableAutoConfiguration无效问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • SpringBoot操作spark处理hdfs文件的操作方法

    SpringBoot操作spark处理hdfs文件的操作方法

    本文介绍了如何使用Spring Boot操作Spark处理HDFS文件,包括导入依赖、配置Spark信息、编写Controller和Service处理地铁数据、运行项目以及观察Spark和HDFS的状态,感兴趣的朋友跟随小编一起看看吧
    2025-01-01
  • springboot项目配置多个kafka的示例代码

    springboot项目配置多个kafka的示例代码

    这篇文章主要介绍了springboot项目配置多个kafka,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04
  • RocketMQ消息重试机制原理分析讲解

    RocketMQ消息重试机制原理分析讲解

    这篇文章主要介绍了RocketMQ消息重试机制,消息的发送和消费并不是百分百成功的,在出现消息推送失败时,RocketMQ有何补偿方式来进行消息重试呢?这是我们今天要一起学习的点
    2023-02-02
  • Java高级之HashMap中的entrySet()方法使用

    Java高级之HashMap中的entrySet()方法使用

    这篇文章主要介绍了Java高级之HashMap中的entrySet()方法使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03

最新评论