




已阅读5页,还剩8页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
一.SpringData概述1二.JPA Spring Data 概述2三.使用 Spring Data JPA 进行持久层开发需要的四个步骤21.配置 Spring 整合 JPA22.在 Spring 配置文件中配置 Spring Data23.声明持久层的接口,该接口继承Repository24.在接口中声明需要的方法25.测试3四.Repository接口31.Repository 的子接口3五.SpringData 方法定义规范41.简单条件查询42.支持的关键字43.查询方法解析流程5六.使用 Query 注解61.使用Query自定义查询62.索引参数与命名参数63.用Query来指定本地查询7七.Modifying 注解和事务81.Query与Modifying 执行更新操作82.事务8八.CrudRepository 接口999九.PagingAndSortingRepository接口10十.JpaRepository接口10十一.JpaSpecificationExecutor接口11十二.自定义 Repository 方法121.为某一个 Repository 上添加自定义方法122.为所有的 Repository 都添加自实现的方法13一.SpringData概述 Spring Data : Spring 的一个子项目。用于简化数据库访问,支持NoSQL 和 关系数据存储。其主要目标是使数据库的访问变得方便快捷。 SpringData 项目所支持 NoSQL 存储: l MongoDB (文档数据库) l Neo4j(图形数据库) l Redis(键/值存储) l Hbase(列族数据库) SpringData 项目所支持的关系数据存储技术: l JDBCl JPA二.JPA Spring Data 概述 JPA Spring Data : 致力于减少数据访问层 (DAO) 的开发量. 开发者唯一要做的,就只是声明持久层的接口,其他都交给 Spring Data JPA 来帮你完成! 框架怎么可能代替开发者实现业务逻辑呢?比如:当有一个 UserDao.findUserById() 这样一个方法声明,大致应该能判断出这是根据给定条件的 ID 查询出满足条件的 User 对象。Spring Data JPA 做的便是规范方法的名字,根据符合规范的名字来确定方法需要实现什么样的逻辑。 三.使用 Spring Data JPA 进行持久层开发需要的四个步骤1.配置 Spring 整合 JPA2.在 Spring 配置文件中配置 Spring Data3.声明持久层的接口,该接口继承 Repository4.在接口中声明需要的方法1.配置 Spring 整合 JPA2.在 Spring 配置文件中配置 Spring Data在 Spring 配置文件中配置 Spring Data,让 Spring 为声明的接口创建代理对象。配置了 后,Spring 初始化容器时将会扫描 base-package 指定的包目录及其子目录,为继承 Repository 或其子接口的接口创建代理对象,并将代理对象注册为 Spring Bean,业务层便可以通过 Spring 自动封装的特性来直接使用该对象。 加入jar包:spring-data-commons-1.6.2.RELEASE.jarspring-data-jpa-1.4.2.RELEASE.jar3.声明持久层的接口,该接口继承Repository声明持久层的接口,该接口继承 Repository,Repository 是一个标记型接口,它不包含任何方法,如必要,Spring Data 可实现 Repository 其他子接口,其中定义了一些常用的增删改查,以及分页相关的方法。4.在接口中声明需要的方法在接口中声明需要的方法。Spring Data 将根据给定的策略(具体策略稍后讲解)来为其生成实现代码。public interface PersonRepsotory extends Repository/根据 lastName 来获取对应的 PersonPerson getByLastName(String lastName);5.测试public class SpringDataTest private ApplicationContext ctx = null;private PersonRepsotory personRepsotory = null;ctx = new ClassPathXmlApplicationContext(applicationContext.xml);personRepsotory = ctx.getBean(PersonRepsotory.class);Testpublic void testHelloWorldSpringData()Person person = personRepsotory.getByLastName(AA);System.out.println(person);四.Repository接口1. Repository 是一个空接口. 即是一个标记接口。2. 若我们定义的接口继承了 Repository, 则该接口会被 IOC 容器识别为一个 Repository Bean纳入到 IOC 容器中. 进而可以在该接口中定义满足一定规范的方法。public interface PersonRepsotory extends Repository/根据 lastName 来获取对应的 PersonPerson getByLastName(String lastName);3. 实际上, 也可以通过 RepositoryDefinition 注解来替代继承 Repository 接口。RepositoryDefinition(domainClass=Person.class,idClass=Integer.class)public interface PersonRepsotory/根据 lastName 来获取对应的 PersonPerson getByLastName(String lastName);1.Repository 的子接口 基础的 Repository 提供了最基本的数据访问功能,其几个子接口则扩展了一些功能。它们的继承关系如下: l Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类 l CrudRepository: 继承 Repository,实现了一组 CRUD 相关的方法 l PagingAndSortingRepository: 继承 CrudRepository,实现了一组分页排序相关的方法 l JpaRepository: 继承 PagingAndSortingRepository,实现一组 JPA 规范相关的方法 l 自定义的 XxxxRepository 需要继承 JpaRepository,这样的 XxxxRepository 接口就具备了通用的数据访问控制层的能力。 l JpaSpecificationExecutor: 不属于Repository体系,实现一组 JPA Criteria 查询相关的方法 五.SpringData 方法定义规范在 Repository 子接口中声明方法 1. 不是随便声明的. 而需要符合一定的规范 2. 查询方法以 find | read | get 开头3. 涉及条件查询时,条件的属性用条件关键字连接4. 要注意的是:条件属性以首字母大写。5. 支持属性的级联查询. 若当前类有符合条件的属性, 则优先使用, 而不使用级联属性. 若需要使用级联属性, 则属性之间使用 _ 进行连接. 1.简单条件查询 简单条件查询: 查询某一个实体类或者集合 按照 Spring Data 的规范,查询方法以 find | read | get 开头,涉及条件查询时,条件的属性用条件关键字连接,要注意的是:条件属性以首字母大写。 例如:定义一个 Entity 实体类class Userprivate String firstName;private String lastName;使用And条件连接时,应这样写: findByLastNameAndFirstName(String lastName,String firstName);条件的属性名称与个数要与参数的位置与个数一一对应2.支持的关键字 直接在接口中定义查询方法,如果是符合规范的,可以不用写实现,目前支持的关键字写法如下:/WHERE lastName LIKE ?% AND id ?List getByLastNameStartingWithAndIdLessThan(String lastName, Integer id);/WHERE email IN (?, ?) OR birth ?List getByEmailInAndBirthLessThan(List emails, Date birth);Testpublic void testKeyWords()List persons = personRepsotory.getByLastNameStartingWithAndIdLessThan(X, 10);System.out.println(persons);persons = personRepsotory.getByEmailInAndBirthLessThan(Arrays.asList(AA, FF), new Date();System.out.println(persons.size();3.查询方法解析流程 假如创建如下的查询:findByUserDepUuid(),框架在解析该方法时,首先剔除 findBy,然后对剩下的属性进行解析,假设查询实体为Doc 先判断 userDepUuid (根据 POJO 规范,首字母变为小写)是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,继续第二步; 从右往左截取第一个大写字母开头的字符串(此处为Uuid),然后检查剩下的字符串是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设 user 为查询实体的一个属性; 接着处理剩下部分(DepUuid),先判断 user 所对应的类型是否有depUuid属性,如果有,则表示该方法最终是根据 “ Doc.user.depUuid” 的取值进行查询;否则继续按照步骤 2 的规则从右往左截取,最终表示根据 “Doc.user.dep.uuid” 的值进行查询。 可能会存在一种特殊情况,比如 Doc包含一个 user 的属性,也有一个 userDep 属性,此时会存在混淆。可以明确在属性之间加上 _ 以显式表达意图,比如 findByUser_DepUuid() 或者 findByUserDep_uuid() 特殊的参数: 还可以直接在方法的参数上加入分页或排序的参数,比如: Page findByName(String name, Pageable pageable); List findByName(String name, Sort sort);/WHERE a.id ?List getByAddress_IdGreaterThan(Integer id);Testpublic void testKeyWords2()List persons = personRepsotory.getByAddress_IdGreaterThan(1);System.out.println(persons);六.使用 Query 注解1.使用Query自定义查询 这种查询可以声明在 Repository 方法中,摆脱像命名查询那样的约束,将查询直接在相应的接口方法中声明,结构更为清晰,这是 Spring data 的特有实现。/查询 id 值最大的那个 Person/使用 Query 注解可以自定义 JPQL 语句以实现更灵活的查询Query(SELECT p FROM Person p WHERE p.id = (SELECT max(p2.id) FROM Person p2)Person getMaxIdPerson();Testpublic void testQueryAnnotation()Person person = personRepsotory.getMaxIdPerson();System.out.println(person);2.索引参数与命名参数 索引参数如下所示,索引值从1开始,查询中 ”?X” 个数需要与方法定义的参数个数相一致,并且顺序也要一致 /为 Query 注解传递参数的方式1: 使用占位符. Query(SELECT p FROM Person p WHERE p.lastName = ?1 AND p.email = ?2)List testQueryAnnotationParams1(String lastName, String email);Testpublic void testQueryAnnotationParams1()List persons = personRepsotory.testQueryAnnotationParams1(AA,);System.out.println(persons); 命名参数(推荐使用这种方式):可以定义好参数名,赋值时采用Param(参数名),而不用管顺序。/为 Query 注解传递参数的方式1: 命名参数的方式. Query(SELECT p FROM Person p WHERE p.lastName = :lastName AND p.email = :email)List testQueryAnnotationParams2(Param(email) String email, Param(lastName) String lastName);Testpublic void testQueryAnnotationParams2()List persons = personRepsotory.testQueryAnnotationParams2(,AA);System.out.println(persons); 如果是 Query 中有 LIKE 关键字,后面的参数需要前面或者后面加 %,这样在传递参数值的时候就可以不加 %: /SpringData 允许在占位符上添加 %. Query(SELECT p FROM Person p WHERE p.lastName LIKE %?1% OR p.email LIKE %?2%)List testQueryAnnotationLikeParam(String lastName, String email);Testpublic void testQueryAnnotationLikeParam()List persons = personRepsotory.testQueryAnnotationLikeParam2(bb, A);System.out.println(persons.size();3.用Query来指定本地查询/设置 nativeQuery=true 即可以使用原生的 SQL 查询Query(value=SELECT count(id) FROM jpa_persons, nativeQuery=true)long getTotalCount();Testpublic void testNativeQuery()long count = personRepsotory.getTotalCount();System.out.println(count);七.Modifying 注解和事务1.Query与Modifying 执行更新操作 Query 与 Modifying 这两个 annotation一起声明,可定义个性化更新操作,例如只涉及某些字段更新时最为常用,示例如下: 注意: 方法的返回值应该是 int,表示更新语句所影响的行数 在调用的地方必须加事务,没有事务不能正常执行2.事务 Spring Data 提供了默认的事务处理方式,即所有的查询均声明为只读事务。 对于自定义的方法,如需改变 Spring Data 提供的事务默认方式,可以在方法上注解 Transactional 声明 进行多个 Repository 操作时,也应该使它们在同一个事务中处理,按照分层架构的思想,这部分属于业务逻辑层,因此,需要在 Service 层实现对多个 Repository 的调用,并在相应的方法上声明事务。 1.可以通过自定义的JPQL 完成UPDATE 和 DELETE 操作.注意:JPQL不支持使用 INSERT2.在 Query 注解中编写 JPQL 语句, 但必须使用 Modifying 进行修饰. 以通知 SpringData, 这是一个 UPDATE 或 DELETE 操作3.UPDATE 或 DELETE 操作需要使用事务, 此时需要定义 Service 层. 在 Service 层 的方法上添加事务操作. 4.默认情况下, SpringData 的每个方法上有事务, 但都是一个只读事务. 他们不能完 成修改操作!Servicepublic class PersonService Autowiredprivate PersonRepsotory personRepsotory;Transactionalpublic void updatePersonEmail(String email, Integer id)personRepsotory.updatePersonEmail(id, email);ModifyingQuery(UPDATE Person p SET p.email = :email WHERE id = :id)void updatePersonEmail(Param(id) Integer id, Param(email) String email);Testpublic void testModifying()personService.updatePersonEmail(, 1);八.CrudRepository 接口CrudRepository 接口提供了最基本的对实体类的添删改查操作 T save(T entity);/保存单个实体 Iterable save(Iterable entities);/保存集合 T findOne(ID id);/根据id查找实体 boolean exists(ID id);/根据id判断实体是否存在 Iterable findAll();/查询所有实体,不用或慎用! long count();/查询实体数量 void delete(ID id);/根据Id删除实体 void delete(T entity);/删除一个实体 void delete(Iterableentities);/删除一个实体的集合void deleteAll();/删除所有实体,不用或慎用! public interface PersonRepsotory extends CrudRepository public class PersonService Autowiredprivate PersonRepsotory personRepsotory;Transactionalpublic void savePersons(List persons)personRepsotory.save(persons);Testpublic void testCrudReposiory()List persons = new ArrayList();for(int i = a; i = z; i+)Person person = new Person();person.setAddressId(i + 1);person.setBirth(new Date();person.setEmail(char)i + + (char)i + );person.setLastName(char)i + + (char)i);persons.add(person);personService.savePersons(persons);九.PagingAndSortingRepository接口该接口提供了分页与排序功能 Iterable findAll(Sort sort); /排序 Page findAll(Pageable pageable); /分页查询(含排序功能) public interface PersonRepsotory extends PagingAndSortingRepository Testpublic void testPagingAndSortingRespository()/pageNo 从 0 开始. int pageNo = 6 - 1;int pageSize = 5;/Pageable 接口通常使用的其 PageRequest 实现类. 其中封装了需要分页的信息/排序相关的. Sort 封装了排序的信息/Order 是具体针对于某一个属性进行升序还是降序. Order order1 = new Order(Direction.DESC, id);Order order2 = new Order(Direction.ASC, email);Sort sort = new Sort(order1, order2);PageRequest pageable = new PageRequest(pageNo, pageSize, sort);Page page = personRepsotory.findAll(pageable);System.out.println(总记录数: + page.getTotalElements();System.out.println(当前第几页: + (page.getNumber() + 1);System.out.println(总页数: + page.getTotalPages();System.out.println(当前页面的 List: + page.getContent();System.out.println(当前页面的记录数: + page.getNumberOfElements();十.JpaRepository接口 该接口提供了JPA的相关功能 List findAll(); /查找所有实体 List findAll(Sort sort); /排序、查找所有实体 List save(Iterable entities);/保存集合 void flush();/执行缓存与数据库同步 T saveAndFlush(T entity);/强制执行持久化 void deleteInBatch(Iterable entities);/删除一个实体集合 public interface PersonRepsotory extends JpaRepository Testpublic void testJpaRepository()Person person = new Person();person.setBirth(new Date();person.setEmail();person.setLastName(xyz);person.setId(28);Person person2 = personRepsotory.saveAndFlush(person);System.out.println(person = person2);/false,先查询后更新十一.JpaSpecificationExecutor接口 不属于Repository体系,实现一组 JPA Criteria 查询相关的方法 Specification:封装 JPA Criteria 查询条件。通常使用匿名内部类的方式来创建该接口的对象 public interface PersonRepsotory extends JpaRepository ,JpaSpecificationExecutor /* * 目标: 实现带查询条件的分页. id 5 的条件 * 调用 JpaSpecificationExecutor 的 Page findAll(Specification spec, Pageable pageable); * Specification: 封装了 JPA Criteria 查询的查询条件 * Pageable: 封装了请求分页的信息: 例如 pageNo, pageSize, Sort */Testpublic void testJpaSpecificationExecutor()int pageNo = 3 - 1;int pageSize = 5;PageRequest pageable = new PageRequest(pageNo, pageSize);/通常使用 Specification 的匿名内部类Specification specification = new Specification() /* * param *root: 代表查询的实体类. * param query: 可以从中可到 Root 对象, 即告知 JPA Criteria 查询要查询哪一个实体类. 还可以来添加查询条件, 还可以结合 EntityManager 对象得到最终查询的 TypedQuery 对象. * param *cb: CriteriaBuilder对象.用于创建 Criteria 相关对象的工厂.当然可以从中获取到 Predicate 对象 * return: *Predicate 类型, 代表一个查询条件. */Overridepublic Predicate toPredicate(Root root,CriteriaQuery query, CriteriaBuilder cb) Path path = root.get(id);Predicate predicate = cb.gt(path, 5);return predicate;Page page = personRepsotory.findAll(specification, pageable);System.out.println(总记录数:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025版隔层施工与室内装修一体化合同范本
- 二零二五版高端食品储藏室租赁及冷链服务协议
- 2025版影视版权转让居间代理合同
- 2025版新能源储能技术研发与合作协议执行步骤
- 二零二五年度二手房买卖定金合同含房屋交易税费减免承诺
- 二零二五年度城市夜景亮化项目厂家直销供货合同模板
- 2025版婚庆现场礼仪服务与执行合同
- 二零二五年度智慧家居安装承包合同模板
- 二零二五年度仓库节能减排改造合同
- 2025版高性能计算机系统集成与维护服务合同
- 2025年西藏自治区事业单位招聘考试教师招聘体育学科专业知识试卷(模拟试题)
- 先天性甲状腺功能减退症诊治指南解读课件
- 2025至2030中国裸眼3D行业产业运行态势及投资规划深度研究报告
- 检修安全监护管理制度
- 产科工作管理制度
- 初中历史教师业务考试试题及答案
- 导尿管相关尿路感染预防与控制试题(附答案)
- 中医烧伤课件
- 2025-2030中国水下混凝土行业市场发展趋势与前景展望战略研究报告
- GB/T 30134-2025冷库管理规范
- 2025年心理咨询师基础理论知识测试卷:心理咨询心理学理论体系试题
评论
0/150
提交评论