当前位置:   article > 正文

SpringDataJpa使用详解_spring data jpa使用

spring data jpa使用

 

概述

这里就不引用冠冕堂皇的介绍了。用我概括的话说。他就是一个类似hibernate,mybatis数据访问层的框架。官网有详细的介绍,

戳这里

Jpa是什么?他是一套规范,类似restful风格一样,都是一套规范。使用Jpa必须按照它的规范来操作数据访问。

SpringDataJpa==Jpa规范+Hibernate底层

为什么要用jpa

笔者其实很喜欢用mybatis写sql来操作数据。但mybatis的局限性就是使用比较麻烦。在工作中,其实大多数业务都是简单的增删改查排序分页。使用mybatis时,每个表基本都要写一遍mapping配置。其实这些工作都是重复性的。写多了谁都会烦而且没必要,只是改了表名和实体类。针对这个问题也有解决方案,就是使用生成工具,直接生成。或者封装一个通用基类,但是mybatis封装很麻烦。所以笔者开始用jpa来做这件事。当然mybatis使用配置文件有一点好处,就是修改sql无需重新编译就可以生效。就是说当我们在服务器上部署了一个项目,通过修改配置文件不用重启服务器。

Jpa适合什么样的项目呢?我觉得适合非互联网项目,或者说中小型项目,或者说对sql优化不高的项目,或者说需求变更不是太频繁的项目。我们可以一个项目中mybatis+jpa混合使用,对于不需要sql优化的表,jpa使用更加方便。

综合来说,jpa在开发效率上讲绝对是比mybatis方便的。我们可以根据自己的需求,来界定是否使用jpa。

Jpa用起来有多简单呢?只需要写一个接口,然后继承JpaRepository,就可以使用了。

比如我要操作User表,新增一个接口IUserDao继承JpaRepository。

public interface IUserDao extends JpaRepository<User,Integer>,JpaSpecificationExecutor<User> {}

在调用的地方初始化IUserDao

  1. @Autowired
  2. private IUserDao userDao;

最后就是调用的地方写代码即可,增删改查如下,根本不用自己定义一边。

  1. userDao.save(user);增
  2. userDao.delete(1);删
  3. userDao.save(user);改
  4. userDao.findById(1);查

相比mybatis,每个方法都要声明一边,然后写对应的sql,是不是简单了许多?

可能有人会说上边这几个方法使用起来太单一,不能满足我的需求,比如根据用户名查找,根据用户名修改等操作。

别急,我上边只是介绍最基本的操作,你想的这些,Jpa作者都想到了。

比如说根据用户名查找,我们只需要在IUserDao接口中,声明如下方法即可:

public User findByUserName(String userName);

然后在调用的地方,加上如下代码即可。

userDao.findByUserName("zhangsan");

我们也可以这样写:

  1. @Query("from User where userName=?1")
  2. public User findBySql(String userName);

也可以通过条件修改:

  1. @Transactional
  2. @Modifying
  3. @Query("update User set userName=?1 where id=?2")
  4. public int updateBySql(String userName,Integer id);

还有很多简便用法,这里就不做展示了。写到这不知道你对Jpa是否有点心动。

使用详解

SpringBoot集成Jpa

使用SpringBoot继承Jpa是最简单的。

操作步骤如下:

  1. 打开Idea工具;
  2. 选择Spring Initializr,下一步;
  3. 定义好工程相关信息,下一步;
  4. 选择左侧菜单中的SQL,勾选右边的Spring Data JPA ,MySql Driver,JDBC API。下一步;
  5. finish;

初始化后pom.xml文件如下,也可以新建空的maven工程,倒入下边的依赖。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.1.7.RELEASE</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.ming</groupId>
  12. <artifactId>springbootjpatest</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>springbootjpatest</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <java.version>1.8</java.version>
  18. </properties>
  19. <dependencies>
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter-data-jpa</artifactId>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-starter-jdbc</artifactId>
  27. </dependency>
  28. <dependency>
  29. <groupId>mysql</groupId>
  30. <artifactId>mysql-connector-java</artifactId>
  31. <scope>runtime</scope>
  32. </dependency>
  33. <dependency>
  34. <groupId>org.springframework.boot</groupId>
  35. <artifactId>spring-boot-starter-test</artifactId>
  36. <scope>test</scope>
  37. </dependency>
  38. </dependencies>
  39. <build>
  40. <plugins>
  41. <plugin>
  42. <groupId>org.springframework.boot</groupId>
  43. <artifactId>spring-boot-maven-plugin</artifactId>
  44. </plugin>
  45. </plugins>
  46. </build>
  47. </project>

工程初始化完毕后,首先新增实体类User。具体注意点,参见代码注释。一定要注意细节,哪个位置没注意,工程就会报错。代码如下:

  1. package com.ming.springbootjpatest.entity;
  2. import javax.annotation.Generated;
  3. import javax.persistence.*;
  4. @Entity
  5. @Table(name = "t_userinfo")//数据库表明
  6. public class User {
  7. @Id//声明id为主键
  8. @GeneratedValue(strategy = GenerationType.IDENTITY)//声明自动增长
  9. @Column(name = "id")//声明数据库对应的字段
  10. private Integer id;
  11. @Column(name = "user_name")//声明数据库对应的字段
  12. //定义字段也是有讲究的,比如首字母小写,后边的驼峰,对应的数据库字段,遇到驼峰用下划线断开
  13. //比如实体类定义的userName,则数据库字段为user_name,
  14. //比如实体类定义的username,则数据库字段也为username
  15. private String userName;
  16. @Column(name = "password")
  17. private String password;
  18. public Integer getId() {
  19. return id;
  20. }
  21. public void setId(Integer id) {
  22. this.id = id;
  23. }
  24. public String getUserName() {
  25. return userName;
  26. }
  27. public void setUserName(String userName) {
  28. this.userName = userName;
  29. }
  30. public String getPassword() {
  31. return password;
  32. }
  33. public void setPassword(String password) {
  34. this.password = password;
  35. }
  36. @Override
  37. public String toString() {
  38. return "User{" +
  39. "id=" + id +
  40. ", userName='" + userName + '\'' +
  41. ", password='" + password + '\'' +
  42. '}';
  43. }
  44. }

然后新增dao层接口IUserDao,代码如下:

public interface IUserDao extends JpaRepository<User,Integer>,JpaSpecificationExecutor<User> {}

然后定义配置文件,在resources目录下新增application.yml,将之前的application.properties文件删掉。配置如下:

  1. server:
  2. port: 8080
  3. servlet:
  4. context-path: /
  5. spring:
  6. datasource:
  7. url: jdbc:mysql://localhost:3306/jpatest?serverTimezone=UTC
  8. username: root
  9. password: 123456
  10. jpa:
  11. database: MySQL
  12. database-platform: org.hibernate.dialect.MySQL5InnoDBDialect #mysql数据库固定配置
  13. show-sql: true #控制台打印sql
  14. hibernate:
  15. ddl-auto: update #update代表数据库没有表的话,会先创建表,有表的话就不创建了。

以上就基本完成了,我们可以在测试类中做各种数据操作了。

有人说数据库表还没有呢啊!这里要告诉大家,程序运行后,Jpa会去数据库查看,如没有表的话,会先创建表,有表的话就不创建了。所以我们不用创建表,jpa帮我们做了。具体配置参见上边ddl-auto字段。

下边就可以在测试类中写一些测试了啦,代码如下:

  1. package com.ming.springbootjpatest;
  2. import com.ming.springbootjpatest.dao.IUserDao;
  3. import com.ming.springbootjpatest.entity.User;
  4. import org.junit.Test;
  5. import org.junit.runner.RunWith;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.boot.test.context.SpringBootTest;
  8. import org.springframework.data.domain.Page;
  9. import org.springframework.data.domain.PageRequest;
  10. import org.springframework.data.domain.Pageable;
  11. import org.springframework.data.domain.Sort;
  12. import org.springframework.data.jpa.domain.Specification;
  13. import org.springframework.test.context.junit4.SpringRunner;
  14. import javax.persistence.criteria.*;
  15. import java.util.ArrayList;
  16. import java.util.Iterator;
  17. import java.util.List;
  18. import java.util.Optional;
  19. @RunWith(SpringRunner.class)
  20. @SpringBootTest
  21. public class SpringbootjpatestApplicationTests {
  22. @Autowired
  23. private IUserDao userDao;
  24. /**
  25. * 增加方法
  26. */
  27. @Test
  28. public void testAdd(){
  29. User user=new User();
  30. user.setUserName("zhangsan1");
  31. user.setPassword("12345");
  32. userDao.save(user);
  33. }
  34. /**
  35. * 批量增加
  36. */
  37. @Test
  38. public void testAddList(){
  39. List<User> userList=new ArrayList<>();
  40. for(int i=0;i<10;i++){
  41. User user=new User();
  42. user.setUserName("zhangsan_"+i);
  43. user.setPassword("12345_"+i);
  44. userList.add(user);
  45. }
  46. userDao.saveAll(userList);
  47. }
  48. /**
  49. * 通过主键查找
  50. */
  51. @Test
  52. public void testFindById(){
  53. Optional<User> optionalUser = userDao.findById(1);
  54. User user = optionalUser.get();
  55. System.out.println(user);
  56. }
  57. /**
  58. * 通用查找方法,基本上按照哪个字段查都可以,写起来稍微麻烦一点点。
  59. * 下边是按照userName="zhangsan"去查,如果不用=换作like,就将下边的criteriaBuilder.equal
  60. * 换成criteriaBuilder.like。
  61. */
  62. @Test
  63. public void testCommonFind(){
  64. Specification<User> specification=new Specification<User>() {
  65. @Override
  66. public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
  67. Path<Object> userName = root.get("userName");
  68. Predicate predicate = criteriaBuilder.equal(userName, "zhangsan");
  69. return predicate;
  70. }
  71. };
  72. Optional<User> optionalUser = userDao.findOne(specification);
  73. User user = optionalUser.get();
  74. System.out.println(user);
  75. }
  76. /**
  77. * 查询所有,如果想通过条件查询,可以根据上边的方式查询。
  78. */
  79. @Test
  80. public void testFindAll(){
  81. List<User> userList = userDao.findAll();
  82. for(User item:userList){
  83. System.out.println(item);
  84. }
  85. }
  86. @Test
  87. public void testPage(){
  88. //排序
  89. Sort sort=new Sort(Sort.Direction.DESC,"id");
  90. //分页
  91. Pageable pageable=PageRequest.of(0,2,sort);
  92. Page<User> page = userDao.findAll(pageable);
  93. //当前页结果,(0)页
  94. List<User> userList = page.getContent();
  95. //按照每页2条数据,一共有的页数
  96. int totalPages = page.getTotalPages();
  97. //总共有多少条数据
  98. long totalElements = page.getTotalElements();
  99. }
  100. /**
  101. * 通用修改方法,先根据主键查找,然后在修改提交
  102. * 也可以通过sql直接修改.需要在IUserDao接口中定义,这里不再演示。
  103. */
  104. @Test
  105. public void testUpdate(){
  106. Optional<User> userOptional = userDao.findById(1);
  107. User user = userOptional.get();
  108. user.setUserName("张三");
  109. //主键存在为修改,不存在为新增
  110. userDao.save(user);
  111. }
  112. /**
  113. * 通过主键删除
  114. * 也可以通过sql直接删除.需要在IUserDao接口中定义,这里不再演示
  115. */
  116. @Test
  117. public void testDelete(){
  118. userDao.deleteById(1);
  119. }
  120. }

以上基本覆盖了常用的方法。还有很多的复杂方法这里不再介绍。仅当入门演示。

Spring继承Jpa

spring配置起来比SpringBoot麻烦,主要是需要导入很多依赖,版本号控制繁琐,配置也比Springboot麻烦。但难于很多项目都是Spring,在这里增加Jpa在spring中的配置。

可以去maven仓库查询常见依赖版本,maven仓库地址:https://mvnrepository.com/

新建一个空的maven工程,导入pom文件如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.ming</groupId>
  7. <artifactId>spring-jpa-test</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <properties>
  10. <java.version>1.8</java.version>
  11. <spring.version>5.1.5.RELEASE</spring.version>
  12. <hibernate.version>5.4.2.Final</hibernate.version>
  13. <slf4j.version>1.8.0-beta4</slf4j.version>
  14. <log4j.version>1.2.17</log4j.version>
  15. <c3p0.version>0.9.1.2</c3p0.version>
  16. <mysql.version>5.1.6</mysql.version>
  17. </properties>
  18. <dependencies>
  19. <!-- junit单元测试 -->
  20. <dependency>
  21. <groupId>junit</groupId>
  22. <artifactId>junit</artifactId>
  23. <version>4.13-beta-3</version>
  24. <scope>test</scope>
  25. </dependency>
  26. <!-- spring beg -->
  27. <dependency>
  28. <groupId>org.aspectj</groupId>
  29. <artifactId>aspectjweaver</artifactId>
  30. <version>1.9.4</version>
  31. </dependency>
  32. <dependency>
  33. <groupId>org.springframework</groupId>
  34. <artifactId>spring-aop</artifactId>
  35. <version>${spring.version}</version>
  36. </dependency>
  37. <dependency>
  38. <groupId>org.springframework</groupId>
  39. <artifactId>spring-context</artifactId>
  40. <version>${spring.version}</version>
  41. </dependency>
  42. <dependency>
  43. <groupId>org.springframework</groupId>
  44. <artifactId>spring-context-support</artifactId>
  45. <version>${spring.version}</version>
  46. </dependency>
  47. <dependency>
  48. <groupId>org.springframework</groupId>
  49. <artifactId>spring-orm</artifactId>
  50. <version>${spring.version}</version>
  51. </dependency>
  52. <dependency>
  53. <groupId>org.springframework</groupId>
  54. <artifactId>spring-beans</artifactId>
  55. <version>${spring.version}</version>
  56. </dependency>
  57. <dependency>
  58. <groupId>org.springframework</groupId>
  59. <artifactId>spring-core</artifactId>
  60. <version>${spring.version}</version>
  61. </dependency>
  62. <!-- spring end -->
  63. <!-- hibernate beg -->
  64. <dependency>
  65. <groupId>org.hibernate</groupId>
  66. <artifactId>hibernate-core</artifactId>
  67. <version>${hibernate.version}</version>
  68. </dependency>
  69. <dependency>
  70. <groupId>org.hibernate</groupId>
  71. <artifactId>hibernate-entitymanager</artifactId>
  72. <version>${hibernate.version}</version>
  73. </dependency>
  74. <dependency>
  75. <groupId>org.hibernate</groupId>
  76. <artifactId>hibernate-validator</artifactId>
  77. <version>6.0.16.Final</version>
  78. </dependency>
  79. <!-- hibernate end -->
  80. <!-- c3p0 beg -->
  81. <dependency>
  82. <groupId>c3p0</groupId>
  83. <artifactId>c3p0</artifactId>
  84. <version>${c3p0.version}</version>
  85. </dependency>
  86. <!-- c3p0 end -->
  87. <!-- log end -->
  88. <dependency>
  89. <groupId>log4j</groupId>
  90. <artifactId>log4j</artifactId>
  91. <version>${log4j.version}</version>
  92. </dependency>
  93. <dependency>
  94. <groupId>org.slf4j</groupId>
  95. <artifactId>slf4j-api</artifactId>
  96. <version>${slf4j.version}</version>
  97. </dependency>
  98. <dependency>
  99. <groupId>org.slf4j</groupId>
  100. <artifactId>slf4j-log4j12</artifactId>
  101. <version>${slf4j.version}</version>
  102. </dependency>
  103. <!-- log end -->
  104. <dependency>
  105. <groupId>mysql</groupId>
  106. <artifactId>mysql-connector-java</artifactId>
  107. <version>${mysql.version}</version>
  108. </dependency>
  109. <dependency>
  110. <groupId>org.springframework.data</groupId>
  111. <artifactId>spring-data-jpa</artifactId>
  112. <version>2.1.10.RELEASE</version>
  113. </dependency>
  114. <dependency>
  115. <groupId>org.springframework</groupId>
  116. <artifactId>spring-test</artifactId>
  117. <version>5.1.9.RELEASE</version>
  118. </dependency>
  119. <!-- el beg 使用spring data jpa 必须引入 -->
  120. <dependency>
  121. <groupId>javax.el</groupId>
  122. <artifactId>javax.el-api</artifactId>
  123. <version>3.0.0</version>
  124. </dependency>
  125. <dependency>
  126. <groupId>org.glassfish</groupId>
  127. <artifactId>javax.el</artifactId>
  128. <version>3.0.1-b10</version>
  129. </dependency>
  130. <!-- el end -->
  131. </dependencies>
  132. </project>

接下来就是resources中applicationContext.xml的配置。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
  6. xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
  7. xsi:schemaLocation="
  8. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  9. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
  10. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
  11. http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
  12. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
  13. http://www.springframework.org/schema/data/jpa
  14. http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
  15. <!-- 1.dataSource 配置数据库连接池-->
  16. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  17. <property name="driverClass" value="com.mysql.jdbc.Driver" />
  18. <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/jpatest" />
  19. <property name="user" value="root" />
  20. <property name="password" value="123456" />
  21. </bean>
  22. <!-- 2.配置entityManagerFactory -->
  23. <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  24. <property name="dataSource" ref="dataSource" />
  25. <property name="packagesToScan" value="com.ming.springjpatest.entity" />
  26. <property name="persistenceProvider">
  27. <bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
  28. </property>
  29. <!--JPA的供应商适配器-->
  30. <property name="jpaVendorAdapter">
  31. <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
  32. <property name="generateDdl" value="false" />
  33. <property name="database" value="MYSQL" />
  34. <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
  35. <property name="showSql" value="true" />
  36. </bean>
  37. </property>
  38. <property name="jpaDialect">
  39. <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
  40. </property>
  41. </bean>
  42. <!-- 3.事务管理器-->
  43. <!-- JPA事务管理器 -->
  44. <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  45. <property name="entityManagerFactory" ref="entityManagerFactory" />
  46. </bean>
  47. <!-- 整合spring data jpa-->
  48. <jpa:repositories base-package="com.ming.springjpatest.dao"
  49. transaction-manager-ref="transactionManager"
  50. entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
  51. <!-- 4.txAdvice-->
  52. <tx:advice id="txAdvice" transaction-manager="transactionManager">
  53. <tx:attributes>
  54. <tx:method name="save*" propagation="REQUIRED"/>
  55. <tx:method name="insert*" propagation="REQUIRED"/>
  56. <tx:method name="update*" propagation="REQUIRED"/>
  57. <tx:method name="delete*" propagation="REQUIRED"/>
  58. <tx:method name="get*" read-only="true"/>
  59. <tx:method name="find*" read-only="true"/>
  60. <tx:method name="*" propagation="REQUIRED"/>
  61. </tx:attributes>
  62. </tx:advice>
  63. <!-- 5.aop-->
  64. <aop:config>
  65. <aop:pointcut id="pointcut" expression="execution(* com.ming.springjpatest.service.*.*(..))" />
  66. <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
  67. </aop:config>
  68. <context:component-scan base-package="com.ming.springjpatest"></context:component-scan>
  69. <!--组装其它 配置文件-->
  70. </beans>

主要就是这两个配置文件,具体实现代码同SpringBoot中的代码。

注意pom文件中mysql-connection-java的版本跟你使用的mysql版本有关,如果用5点几的mysql,mysql-connection-java的版本也要用5点几的否则会报错噢,具体版本可以用maven仓库搜索,仓库地址上边有写

因为配置spring版本等问题,很容易出错,如遇到错误,可先去我的另外一篇文章中查找,戳这里

在多module工程中,如果把model放在单独的工程,记得在jpa工程启动类中,使用@EntityScan注解,扫描实体类噢。

总结

以上就是对SpringDataJpa的介绍,相信通过文章的介绍大家都能入门使用了,有些细节的使用,还需熟悉jpa规范。

我们也可以封装一个公用基类,便于更好的维护管理。

公用基类声明如下:

  1. @NoRepositoryBean
  2. public interface IBaseDao<T,ID extends Serializable> extends JpaRepository<T,ID>, JpaSpecificationExecutor<T> {
  3. }

像IUserDao等接口都直接继承IBaseDao即可。注意上边的注解,否则会报错。

Github

https://github.com/OptimusMX/springdatajpa

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/656261
推荐阅读
相关标签
  

闽ICP备14008679号