Spring Data JPA —— 快速入门
2018-06-18 02:40:25来源:未知 阅读 ()
一、概述
JPA : Java Persistence API, Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
Spring Data JPA 是Spring基于ORM框架、JPA规范封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用SpringDataJPA可以极大提高开发效率! 除了CRUD外,还包括如分页、排序等一些常用的功能。下面的示例代码即可完成数据保存的操作,而无需具体实现类.
public interface UserDao extends Repository<AccountInfo, Long> {
public AccountInfo save(AccountInfo accountInfo);
}
二、
-
-
CrudRepository :是Repository的子接口,提供CRUD的功能
-
PagingAndSortingRepository:是CrudRepository的子接口,添加分页和排序的功能
-
JpaRepository:是PagingAndSortingRepository的子接口,增加了一些实用的功能,比如:批量操作等。
-
JpaSpecificationExecutor:用来做负责查询的接口
-
Specification:是Spring Data JPA提供的一个查询规范,要做复杂的查询,只需围绕这个规范来设置查询条件即可
三、快速入门
1、构建demo环境
- 使用maven建立jar项目,下图为项目文件目录
-
导入依赖
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>com.cenobitor</groupId> 5 <artifactId>JPADemo</artifactId> 6 <version>0.0.1-SNAPSHOT</version> 7 <packaging>pom</packaging> 8 <description>统一管理依赖</description> 9 10 <properties> 11 <spring.version>4.2.4.RELEASE</spring.version> 12 <hibernate.version>5.0.7.Final</hibernate.version> 13 <slf4j.version>1.6.6</slf4j.version> 14 <springdatajpa.version>1.10.4.RELEASE</springdatajpa.version> 15 <c3p0.version>0.9.1.2</c3p0.version> 16 <junit.version>4.11</junit.version> 17 </properties> 18 19 <dependencies> 20 <!-- spring 框架 --> 21 <dependency> 22 <groupId>org.springframework</groupId> 23 <artifactId>spring-context</artifactId> 24 <version>${spring.version}</version> 25 </dependency> 26 27 <dependency> 28 <groupId>org.springframework</groupId> 29 <artifactId>spring-test</artifactId> 30 <version>${spring.version}</version> 31 </dependency> 32 33 34 <!-- spring data jpa 数据库持久层 --> 35 <dependency> 36 <groupId>org.springframework.data</groupId> 37 <artifactId>spring-data-jpa</artifactId> 38 <version>${springdatajpa.version}</version> 39 </dependency> 40 41 <!-- hibernate 框架 --> 42 <dependency> 43 <groupId>org.hibernate</groupId> 44 <artifactId>hibernate-core</artifactId> 45 <version>${hibernate.version}</version> 46 </dependency> 47 <dependency> 48 <groupId>org.hibernate</groupId> 49 <artifactId>hibernate-entitymanager</artifactId> 50 <version>${hibernate.version}</version> 51 </dependency> 52 53 <!-- 数据库连接池 --> 54 <dependency> 55 <groupId>c3p0</groupId> 56 <artifactId>c3p0</artifactId> 57 <version>${c3p0.version}</version> 58 </dependency> 59 60 <!-- 日志框架 --> 61 <dependency> 62 <groupId>org.slf4j</groupId> 63 <artifactId>slf4j-log4j12</artifactId> 64 <version>${slf4j.version}</version> 65 </dependency> 66 <!-- 数据库驱动 --> 67 <dependency> 68 <groupId>mysql</groupId> 69 <artifactId>mysql-connector-java</artifactId> 70 <version>5.1.6</version> 71 </dependency> 72 73 <!-- 单元测试 --> 74 <dependency> 75 <groupId>junit</groupId> 76 <artifactId>junit</artifactId> 77 <version>${junit.version}</version> 78 </dependency> 79 </dependencies> 80 81 </project>
-
在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" 4 xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" 5 xmlns:jpa="http://www.springframework.org/schema/data/jpa" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd 9 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd 10 http://www.springframework.org/schema/data/jpa 11 http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> 12 13 <!--指定连接池配置--> 14 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 15 <property name="driverClass" value="com.mysql.jdbc.Driver" /> 16 <property name="jdbcUrl" value="jdbc:mysql:///ssh01?useSSL=false" /> 17 <property name="user" value="root" /> 18 <property name="password" value="" /> 19 </bean> 20 <!-- spring整合JPA --> 21 <bean id="entityManagerFactory" 22 class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 23 <property name="dataSource" ref="dataSource" /> 24 <!--指定JPA扫描的实体类所在的包--> 25 <property name="packagesToScan" value="com.cenobitor.domain" /> 26 <!-- 指定持久层提供者为Hibernate --> 27 <property name="persistenceProvider"> 28 <bean class="org.hibernate.ejb.HibernatePersistence" /> 29 </property> 30 <property name="jpaVendorAdapter"> 31 <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 32 <!-- 自动建表 --> 33 <property name="generateDdl" value="true" /> 34 <property name="database" value="MYSQL" /> 35 <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" /> 36 <property name="showSql" value="true" /> 37 </bean> 38 </property> 39 <property name="jpaDialect"> 40 <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" /> 41 </property> 42 </bean> 43 44 <!-- 配置事务管理器 --> 45 <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 46 <property name="entityManagerFactory" ref="entityManagerFactory" /> 47 </bean> 48 49 <!-- 开启事务注解 --> 50 <tx:annotation-driven transaction-manager="transactionManager" /> 51 <!--指定Spring Data JPA要进行扫描的包,该包中的类框架会自动为其创建代理--> 52 <jpa:repositories base-package="com.cenobitor.dao" /> 53 54 </beans>
- 项目中新建com.cenobitor.domain包,创建实体类
1 @Entity 2 @Table 3 public class User { 4 @Id 5 @GeneratedValue 6 @Column 7 private Integer id; 8 @Column 9 private String name; 10 @Column 11 private String password; 12 13 public Integer getId() { 14 return id; 15 } 16 17 public void setId(Integer id) { 18 this.id = id; 19 } 20 21 public String getName() { 22 return name; 23 } 24 25 public void setName(String name) { 26 this.name = name; 27 } 28 29 public String getPassword() { 30 return password; 31 } 32 33 public void setPassword(String password) { 34 this.password = password; 35 } 36 37 @Override 38 public String toString() { 39 return "User{" + 40 "id=" + id + 41 ", name='" + name + '\'' + 42 ", password='" + password + '\'' + 43 '}'; 44 } 45 }
- 项目中新建com.cenobitor.dao包,创建dao
1 // 泛型参数1 : 实体类 2 // 泛型参数2 : 实体类中主键的类型 3 @Repository 4 public interface JpaRepository extends org.springframework.data.jpa.repository.JpaRepository<User,Integer>{ 5 6 }
-
在com.cenobitor.test创建测试类,进行测试用例,如果在控制台看到Hibernate输出sql语句,说明操作成功
1 @RunWith(SpringJUnit4ClassRunner.class) 2 @ContextConfiguration("classpath:applicationContext.xml") 3 public class SpringDataJPATest { 4 @Autowired 5 private JpaRepository jpaRepository; 6 7 @Test 8 public void testQuery() { 9 // 查询操作 10 List<User> list = jpaRepository.findAll(); 11 for (User user : list) { 12 System.out.println(user); 13 } 14 } 15 }
2、增删改查操作
1 @Test 2 public void testSave() { 3 // 保存数据 4 User user = new User(); 5 user.setName("赵六"); 6 user.setPassword("1234"); 7 8 jpaRepository.save(user); 9 } 10 11 @Test 12 public void testUpdate() { 13 // 更新操作,传入主键ID 14 User user = new User(); 15 user.setId(3); 16 user.setName("李四"); 17 // 调用该方法时,首先进行查询操作,如果数据不存在,执行插入 18 // 如果数据存在,执行修改 19 jpaRepository.save(user); 20 } 21 22 @Test 23 public void testDelete() { 24 //删除操作 25 jpaRepository.delete(3); 26 } 27 28 @Test 29 public void testFindOne() { 30 //根据主键进行查询 31 User user = jpaRepository.findOne(4); 32 System.out.println(user); 33 }
3、自定义查询操作
JpaRepository支持接口规范方法名查询。意思是如果在接口中定义的查询方法符合它的命名规则,就可以不用写实现。
例如:findByName这个方法表示从数据库中查询Name这个属性等于XXX的所有记 录,类似于SQL语句:select*from xTablewherename=x这种形式 这段话有两个重点:
①方法名需要在接口中设定
②必须符合一定的命名规范
- 方法名构造方法 :
find+全局修饰+By+实体的属性名称+限定词+连接词+.(其它实体属性)+OrderBy+ 排序属性+排序方向
例如:
findDistinctByFirstNameIgnoreCaseAndLastNameOrderByAgeDesc(String firstName,StringlastName){.}
其中:Distinct是全局修饰(非必须),FirstName和LastName是实体的属性名, And是连接词,IgnoreCase是限定词,Age是排序属性,Desc是排序方向,限定词 和连接词统称为“关键词”
- 常用词如下:
-
- 全局修饰:Distinct,Top,First
- 关键词:IsNull,IsNotNull,Like,NotLike,Containing,In,NotIn, IgnoreCase,Between,Equals,LesThan,GreaterThan,After,Before
- 排序方向:Asc,Desc
- 连接词:And,Or
- 示例
1 // 泛型参数1 : 实体类 2 // 泛型参数2 : 实体类中主键的类型 3 @Repository 4 public interface JpaRepository extends org.springframework.data.jpa.repository.JpaRepository<User,Integer>{ 5 // =============标准命名方式=============== 6 // 根据名字进行精准查询,Standard类中有name字段 7 User findByName(String name); 8 // 根据名字进行模糊查询 9 User findByNameLike(String name); 10 // 查询名字为空的数据 11 List<User> findByNameIsNull(); 12 // 多条件查询 13 User findByNameAndPassword(String name,String password); 14 // ==============非标准命名方式============= 15 // 使用JPQL进行非标准命名查询 16 @Query("from User u where u.name like ?") 17 User findByNamexxxxxLikeJPQL(String name); 18 // 使用JPQL进行非标准多条件查询 19 // 默认情况下,问号的顺序和传入的参数顺序是一致的 20 // 可以在问号后面追加数字,改变和参数的匹配顺序 21 // 下面的示例中,传入的第一个参数匹配到第二个问号,传入的第二个参数匹配到第一个问号 22 @Query("from User u where u.name like ?2 and password = ?1") 23 User findByNameAndOperatorJPQL(String password,String name); 24 // 使用标准SQL进行非标准命名查询 25 @Query(value = "select * from user u where u.name like ?", nativeQuery = true) 26 User findByNamexxxxxLikeSQL(String name); 27 }
1 @Test 2 public void testFindByName(){ 3 User user = jpaRepository.findByName("赵六"); 4 System.out.println(user); 5 } 6 7 @Test 8 public void testFindByNameLike(){ 9 User user = jpaRepository.findByNameLike("%六"); 10 System.out.println(user); 11 } 12 13 @Test 14 public void testFindByNameIsNull(){ 15 List<User> users = jpaRepository.findByNameIsNull(); 16 System.out.println(users); 17 } 18 19 @Test 20 public void testFindByNameAndPassword(){ 21 User user = jpaRepository.findByNameAndPassword("赵六","1234"); 22 System.out.println(user); 23 } 24 25 @Test 26 public void testFindByNamexxxxxLikeJPQL(){ 27 User user = jpaRepository.findByNamexxxxxLikeJPQL("赵六"); 28 System.out.println(user); 29 } 30 31 @Test 32 public void testFindByNameAndOperatorJPQL(){ 33 User user = jpaRepository.findByNameAndOperatorJPQL("1234","赵六"); 34 System.out.println(user); 35 } 36 37 @Test 38 public void testFindByNamexxxxxLikeSQL(){ 39 User user = jpaRepository.findByNamexxxxxLikeSQL("赵六"); 40 System.out.println(user); 41 }
4、自定义更新删除操作
1 // ================自定义增删改操作========== 2 @Transactional // 使用事务 3 @Modifying // 执行修改操作 4 @Query("delete from User u where u.name = ?") 5 void deleteByName(String name); 6 7 @Transactional 8 @Modifying // 执行修改操作 9 @Query("update User u set u.password = ?2 where u.name = ?1") 10 void updatePasswordByName(String name, String password);
1 @Test 2 public void testDeleteByName() { 3 // 使用JPQL进行自定义删除操作 4 jpaRepository.deleteByName("赵六"); 5 } 6 7 @Test 8 public void testUpdatePasswordByName() { 9 // 使用JPQL进行自定义更新操作 10 jpaRepository.updatePasswordByName("赵六","333"); 11 }
- 分页查询
1 //分页查询 2 @Test 3 public void TestPageQuery() throws IOException { 4 int page = 1 ; //当前页面 5 int rows = 10 ; //每页数据条数 6 //创建分页条件 7 Pageable pageable = new PageRequest(page - 1, rows); 8 Page<User> page1 = jpaRepository.findAll(pageable); 9 //获取总数据条数 10 long totalElements = page1.getTotalElements(); 11 //获取结果集 12 List<User> list = page1.getContent(); 13 System.out.println(list); 14 15 }
- 条件分页查询
@Repository public interface JpaRepository extends JpaRepository<User,Integer>, JpaSpecificationExecutor<User> { }
1 @RunWith(SpringJUnit4ClassRunner.class) 2 @ContextConfiguration("classpath:applicationContext.xml") 3 public class SpringDataJPATest { 4 @Autowired 5 private JpaRepository jpaRepository; 6 7 @Test 8 public void testConditionPageQuery() throws IOException { 9 10 User user = new User(); 11 user.setName("李%"); 12 user.setPassword("1234"); 13 14 int page = 1 ; //当前页面 15 int rows = 10 ; //每页数据条数 16 17 //构造查询条件 18 Specification<User> specification = new Specification<User>() { 19 @Override 20 public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 21 /** 22 * 创建一个查询的where语句 23 * @param root : 根对象.可以简单的认为就是泛型对象 24 * @param cb : 构建查询条件 25 * @return a {@link Predicate}, must not be {@literal null}. 26 */ 27 String name = user.getName(); 28 String password = user.getPassword(); 29 // 存储条件的集合 30 ArrayList<Predicate> list = new ArrayList<>(); 31 if (! name.isEmpty()){ 32 //构建模糊查询条件,参数2为具体的比较的值 33 Predicate p1 = cb.like(root.get("name").as(String.class),name); 34 list.add(p1); 35 } 36 if (! password.isEmpty()){ 37 Predicate p2 = cb.equal(root.get("password").as(String.class), password); 38 list.add(p2); 39 } 40 if (list.size() == 0 ){ 41 return null; 42 } 43 Predicate[] arr = new Predicate[list.size()]; 44 list.toArray(arr); 45 return cb.and(arr); 46 } 47 48 }; 49 Pageable pageable = new PageRequest(page-1,rows); 50 Page<User> page1 = jpaRepository.findAll(specification,pageable); 51 List<User> content = page1.getContent(); 52 System.out.println(content); 53 } 54 }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Spring系列.ApplicationContext接口 2020-06-11
- springboot2配置JavaMelody与springMVC配置JavaMelody 2020-06-11
- 给你一份超详细 Spring Boot 知识清单 2020-06-11
- SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 2020-06-11
- 掌握SpringBoot-2.3的容器探针:实战篇 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash