ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring Data JPA

2022-06-16 01:02:09  阅读:206  来源: 互联网

标签:语句 JPA Spring 使用 查询 sql Query Data id


一、什么是JPA?

JAP全称Java Persistence API,即Java持久化API:一套Sun公司Java官方制定的ORM 方案,是规范,sun公司自己并没有实现。

二、什么是Spring Data JPA?

spirng data jpa是spring提供的一套简化JPA开发的框架,按照约定好的【方法命名规则】写dao层接口,就可以在不写接口实现的情况下,实现对数据库的访问和操作。同时提供了很多除了CRUD之外的功能,如分页、排序、复杂查询等等。

Spring Data JPA 可以理解为 JPA 规范的再次封装抽象,底层还是使用了 Hibernate 的 JPA 技术实现。

三、Spring Boot 怎样集成JPA?

1、添加依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-jpa</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>mysql</groupId>
  7. <artifactId>mysql-connector-java</artifactId>
  8. <version>5.1.35</version>
  9. </dependency>

2、相关application.yml配置

  1. spring:
  2. #连接mysql数据库
  3. datasource:
  4. url: jdbc:mysql://localhost:3306/news
  5. username: root
  6. password: 123456
  7. driver-class-name: com.mysql.jdbc.Driver
  8. jpa:
  9. hibernate:
  10. ddl-auto: update
  11. show-sql: true

备注:

ddl-auto:

        create:每次运行程序时,都会重新创建表,故而数据会丢失
        create-drop:每次运行程序时会先创建表结构,然后待程序结束时清空表
        upadte:每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)
        validate:运行程序会校验数据与数据库的字段类型是否相同,字段不同会报错
        none:禁用DDL处理

3、生成实体类

        可以通过设置IDE软件自动生成实体类,也可以通过手动创建实体类文件,通过添加注解的方式手动生成(推荐)。

        实体类注解说明
@Entity:声明类为实体或表。
@Table:声明表名。
@Basic:指定非约束明确的各个字段。
@Embedded:指定类或它的值是一个可嵌入的类的实例的实体的属性。
@Id:指定的类的属性,用于识别(一个表中的主键)。
@GeneratedValue:指定如何标识属性可以被初始化,例如自动、手动、或从序列表中获得的值。
@Transient:指定的属性,它是不持久的,即:该值永远不会存储在数据库中。
@Column:用来标识实体类中属性与数据表中字段的对应关系,可以用在属性前或者getter前
@SequenceGenerator:指定在@GeneratedValue注解中指定的属性的值。它创建了一个序列。
@TableGenerator:指定在@GeneratedValue批注指定属性的值发生器。它创造了的值生成的表。
@AccessType:这种类型的注释用于设置访问类型。如果设置@AccessType(FIELD),则可以直接访问变量并且不需要getter和setter, 但必须为public。如果设置@AccessType(PROPERTY),通过getter和setter方法访问Entity的变量。
@JoinColumn:指定一个实体组织或实体的集合。这是用在多对一和一对多关联。
@UniqueConstraint: 指定的字段和用于主要或辅助表的唯一约束。
@ColumnResult:参考使用select子句的SQL查询中的列名。
@ManyToMany:定义了连接表之间的多对多一对多的关系。
@ManyToOne:定义了连接表之间的多对一的关系。
@OneToMany:定义了连接表之间存在一个一对多的关系。
@OneToOne:定义了连接表之间有一个一对一的关系。
@NamedQueries:指定多个命名查询。命名查询实际上就是给查询语句起个名字,执行查询的时候就是直接使用起的这个名字,避免重复写JPQL语句
@NamedQuery:指定一个命名查询

4、dao层

        (1)创建dao层

  1. 一个表对应一个dao层接口,该接口要继承 org.springframework.data.jpa.repository.JpaRepository<T, ID> 接口:
  2. 第一个泛型:实体类
  3. 第二个泛型:实体类中Id(数据库主键)的类型
  4. JpaRepository接口及父接口中已经实现了的常用方法:
  5. getOne(id):根据id查找
  6. findAll()/findOne():查找全部或者一个
  7. findAll(Pageable pageable):分页查询,返回Page
  8. deleteById(id):根据 id删除
  9. repository.save(T entity):保存一个实体
  10. repository.save(Iterable<T> entities):保存多个实体
  11. repository.saveAndFlush(T entity):保存并立即刷新一个实体
  12. count():获取数量
  1. public interface NewsDao extends JpaRepository<News, Integer> {
  2. }

JpaRepository接口及父接口中已经实现了的常用方法:

  • getOne(id):根据id查找
  • findAll()/findOne():查找全部或者一个
  • findAll(Pageable pageable):分页查询,返回Page
  • deleteById(id):根据 id删除
  • repository.save(T entity):保存一个实体
  • repository.save(Iterable<T> entities):保存多个实体
  • repository.saveAndFlush(T entity):保存并立即刷新一个实体
  • count():获取数量

(2)方法名查询

JpaRepository支持接口规范方法名查询。即在接口中定义的查询方法符合它的命名规则,就可以不用写sql语句。

dao层接口中方法定义规范:

方法返回值类型跟据情况写,可以是List,可以是void,也可以是对应的Entry等等
方法名的命名规范:find/read/query/count/get/delete + XXBy + 由字段和关键字构成的查询条件
方法中的形参要与方法名的需要的参数一一对应;例如:

//在dao接口中创建了一个方法,该方法的作用从方法名就可以很容易读出来:
//查找用户名(方法名中的UserName)为username(第一个形参)或者Email(方法名中的Email)为email(第二个形参)的用户
User findByUserNameOrEmail(String username, String email);

方法名的具体命名规则:

  • find/read/query/get均为查询,delete为删除,count为查询数量。注意:使用方法名的方式修改数据库时,要加事务注解@Transactional,否则会报错
  • XX的位置可以去重、取查询结果的前N个元素,主要用法有:
关键字说明方法名举例
First(N) / Top(N)选取查询结果的前N个,N不写默认为1findFirst3By … 或者findTop10By …
All / 不填选取所有的查询结果findAllBy … 或者 findBy …
Distinct选取所有去重后的查询结果findDistinctBy …

DistinctFirst(N) / DistinctTop(N)

选取去重后查询结果的前N个findDistinctFirstBy … 或者 findDistinctTop2By …

  • 方法名中,By后面常用的关键字及用法如下:

分页查询的使用:

在查询的方法中,需要传入参数Pageable ,当查询中有多个参数的时候Pageable建议做为最后一个参数传入。PageRequest是 Spring 封装的分页实现类,使用的时候需要传入页数每页条数排序规则

  1. public void findAndPage() {
  2. int page=1, size=10;
  3. //多字段排序
  4. Sort sort = Sort.by(Sort.Direction.DESC,"isTop").and(Sort.by(Sort.Direction.ASC,"isEssence"));
  5. //分页查询
  6. newsDao.findAll(PageRequest.of(page, size, sort));
  7. }

(3)自定义SQL/HQL查询
其实 Spring Data 绝大部分的 SQL 都可以根据方法名定义的方式来实现,但是由于某些原因我们想使用自定义的 SQL 来查询,Spring Data 也是完美支持的;在 SQL 的查询方法上面使用@Query注解,如涉及到删除和修改还需要加上@Modifying。也可以根据需要添加 @Transactional对事务的支持,查询超时的设置等。

@Query中value属性用来写自定义的Sql或者Hql,具体使用哪种根据nativeQuery属性来指定
@Query中nativeQuery属性用来指定是否使用原生的sql,默认为false,即value属性使用Hql;为true时,使用Sql
在sql/hql中,使用 ?1、?2……来占位
单独使用@Query注解时只能写查询语句,加上@Modifying和@Transactional注解后,就能写修改语句了,支持使用hql的update/delete语句和使用sql的insert语句
@Modifying(clearAutomatically = true) 自动清除实体里保存的数据。

  1. //插入语句, 使用原生的sql语句
  2. @Transactional
  3. @Modifying
  4. @Query(value = "insert into user(userName, age) values (?1, ?2)",
  5. nativeQuery = true)
  6. void saveUser(String userName, Integer age);
  7. //更新语句
  8. @Transactional
  9. @Modifying
  10. @Query("update User u set u.userName = ?1 where u.id = ?2")
  11. int modifyByIdAndUserId(String userName, Long id);
  12. //删除语句
  13. @Transactional
  14. @Modifying
  15. @Query("delete from User where id = ?1")
  16. void deleteByUserId(Long id);
  17. //hql模糊查询语句
  18. @Query("select u from User u where u.emailAddress like concat('%', ?1, '%')")
  19. User findByEmailAddress(String emailAddress);
  20. //nativeQuery 为true, 直接写sql语句, 原生sql模糊查询加分页
  21. @Query(value = "select * from user where id like %?1%",
  22. nativeQuery = true)
  23. Page<Users> getAllss(Integer nId, Pageable pageable);//Page底层为ArrayList

使用原生sql语句进行模糊查询时,使用 like %?1%,当使用hql进行模糊查询时,使用 like concat('%', ?1, '%'),concat为sql的字符串拼接函数
当使用Page<T>来接收分页查询时,会自动查询数据的个数,也可以通过@Query中的countQuery来指定sql语句,service层通过page.getTotalPages()来获取数据的个数

四、使用EasyCode插件生成代码

使用EasyCode插件可以自动生成jpa代码:Easy Code插件使用(附Spring Data JPA生成模板)



原文转载:https://blog.csdn.net/weixin_59668801/article/details/124790143

标签:语句,JPA,Spring,使用,查询,sql,Query,Data,id
来源: https://www.cnblogs.com/dusucyy/p/16380503.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有