学习主题:SpringDataJPA
学习目标:
1 掌握SpringDataJPA常用接口类,常用注解
1. Spring Data JPA接口继承结构
(1)阐述Spring Data JPA的继承结构。
2.SpringDataJPA底层原理
(1)阐述Spring Data JPA的底层运行原理。
通过jdk生成的动态代理对象SimpleJpaRepository
3.Repository接口-方法命名规则查询
(1)Repository接口的作用是什么?
Repository接口是Spring Data中为我们提供的所有接口中的顶层接口
(2)Repository接口支持几种查询方式?
两种
1、基于方法名称的命名规则查询
2、基于@Query注解查询
(3)什么是方法命名规则查询?
规则:
findBy(关键字)+属性名称(属性名称的首字母大写)+查询条件(首字母大写)
4.@Query查询JPQL语句
(1)@Query注解的作用是什么?
JPA注解就是利用注解来实现JPA相关的配置工作。 在没有使用注解直接,大量的配置通过XML文件来完成,导致维护起来非常困难。 使用注解时,所有的实体相关的配置,都是放到实体类里面,维护的时候打开实体类就能够直接修改
(2)使用JPQL查询方式t_users表,条件为用户名相等。
@Query(value = "from Users where username = ?")
List<Users> queryByUsernameUseJPQL(String username);
@Test
public void test4(){
List<Users> list = this.usersDao.queryByUsernameUseJPQL("lisi");
for (Users users:list){
System.out.println(users);
}
}
(3)使用JPQL查询方式t_users表,条件为用户名Like。
@Query("from Users where username like ?")
List<Users> queryByUsernameLikeUseJPQL(String username);
@Test
public void test5(){
List<Users> list = this.usersDao.queryByUsernameLikeUseJPQL("h%");
for (Users users:list){
System.out.println(users);
}
}
(4)使用JPQL查询方式t_users表,条件为用户名年龄大于。
@Query("from Users where username=? and userage =?")
List<Users> queryByUsernameAndUserageUseJPQL(String username,Integer userage);
@Test
public void test6(){
List<Users> list = this.usersDao.queryByUsernameAndUserageUseJPQL("zhangsan", 22);
for (Users users:list){
System.out.println(users); } }
5.@Query查询SQL语句
(1)使用SQL查询方式t_users表,条件为用户名相等。
//nativeQuery 默认是false ,就是不开启sql查询
@Query(value = "select * from t_users where username =?",nativeQuery = true)
List<Users> queryByUsernameUseSQL(String username);
@Test
public void test7(){
List<Users> list = this.usersDao.queryByUsernameUseSQL("zhangsan");
for (Users users:list){
System.out.println(users);
}
}
(2)使用SQL查询方式t_users表,条件为用户名Like。
@Query(value = "select * from t_users where username like ?",nativeQuery = true)
List<Users> queryByUsernameLikeUseSQL(String username);
@Test
public void test8(){
List<Users> list = this.usersDao.queryByUsernameLikeUseSQL("y%");
for (Users users:list){
System.out.println(users);
}
}
(3)使用SQL查询方式t_users表,条件为用户名年龄大于。
@Query(value = "select * from t_users where username =? and userage >=?",nativeQuery = true)
List<Users> queryByUsernameAndUserageUseSQL(String username,Integer userage);
@Test
public void test9(){
List<Users> list = this.usersDao.queryByUsernameAndUserageUseSQL("zhangsan", 22);
for (Users users:list){
System.out.println(users);
}
}
6.@Query更新操作
(1)@Modifying注解的作用是什么?
表示当前语句为更新语句
7.CrudRepository接口的使用
(1)CrudRepository接口的作用是什么?
该接口提供了最基本的对实体类的增删改查操作
8.分页处理
(1)PagingAndSortingRepository接口的作用是什么?
对在数据库中查找的数据实现分页与排序的操作
(2)通过PagingAndSortingRepository接口完成带分页的查询。
/**
* 分页查询
*/
@Test
public void selectByPage(){
int page=0;//page:当前页的索引,注意索引都是从0开始
int size=3;//size:每页显示的条数
Pageable pageable = new PageRequest(page, size);
Page<Users> pag = this.usersDao.findAll(pageable);
System.out.println("当前总条数:"+pag.getTotalElements());
System.out.println("总页数"+pag.getTotalPages());
List<Users> list = pag.getContent();
for (Users users:list) {
System.out.println(users);
}
}
9.排序处理
(1)Sort对象的作用是什么?
该对象封装了排序规则以及指定的排序字段(对象的属性来表示)
(2)Order对象的作用是什么?
静态内部类,做排序规则的指定
有多个排序规则时,该对象封装了排序规则以及指定的排序字段(对象的属性来表示),然后放进sort对象中。
(3)Direction参数的作用是什么?
排序规则
(4)Properties参数的作用是什么?
指定做排序的属性
10.JpaRepository接口的使用
(1)JpaRepository接口的作用是什么?
JpaRepository接口是我们开发时使用的最多的接口,其特点是可以帮助我们将其他接口的方法的返回值做适配处理,可以使得我们在开发时更方便的使用这些方法。
11.JpaSpecificationExecutor接口-单条件查询
(1)JpaSpecificationExecutor接口的作用是什么?
完成多条件查询,并且支持分页和排序。
12.多条件查询方式一
(1)通过JpaSpecificationExecutor接口对t_users表完成多条件的查询。
/**
* JpaSpecificationExecutor接口
* 注意:JpaSpecificationExecutor接口不能单独使用,必须和jpa中的其他接口一起配合使用
*/
public interface UsersDao extends JpaRepository<Users,Integer>, JpaSpecificationExecutor<Users> {
/**
* JpaSpecificationExecutor多条件查询
* 根据用户名和用户年龄查询
*/
@Test
public void test2(){
Specification<Users> spec = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> list=new ArrayList<>();
list.add(cb.equal(root.get("username"),"zhangsan"));
list.add(cb.equal(root.get("userage"),22));
Predicate[] arr=new Predicate[list.size()];
return cb.and(list.toArray(arr));
}
};
List<Users> list = this.usersDao.findAll(spec);
for (Users users:list){
System.out.println(users);
}
}
13.多条件查询方式二
(1)通过JpaSpecificationExecutor接口对t_users表完成多条件的查询。
/**
* JpaSpecificationExecutor多条件查询
* 根据用户名或者用户年龄查询(或者关系)
*/
@Test
public void test3(){
Specification<Users> spec = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.or(cb.equal(root.get("username"),"zhangsan"),cb.and(cb.equal(root.get("username"),"yy"),cb.equal(root.get("userage"),23)));
}
};
List<Users> list = this.usersDao.findAll(spec);
for (Users users:list){
System.out.println(users);
}
}
14.多条件查询-分页处理
(1)通过JpaSpecificationExecutor接口完成对查询结果集的分页处理。
/**
* 需求:查询王姓用户,并且做分页处理
*/
@Test
public void test4(){
Specification<Users> spec = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
return cb.like(root.get("username"),"张%");
}
};
//分页
Pageable pageable=new PageRequest(0,2);
Page<Users> page = this.usersDao.findAll(spec, pageable);
System.out.println("当前总条数:"+page.getTotalElements());
System.out.println("总页数:"+page.getTotalPages());
List<Users> list = page.getContent();
for (Users users:list){
System.out.println(list);
}
}
15.多条件查询-排序处理
(1)通过JpaSpecificationExecutor接口完成对查询结果集的排序处理。
/**
* 需求:查询数据库中王姓的用户,并且根据用户 id 做倒序排序
*/
@Test
public void test5(){
Specification<Users> spec = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
return cb.like(root.get("username"),"zhang%");
}
};
Sort sort=new Sort(Sort.Direction.DESC,"userid");
List<Users> list = this.usersDao.findAll(spec, sort);
for (Users users:list){
System.out.println(users);
}
}
16.多条件查询+分页+排序
(1)通过JpaSpecificationExecutor接口完成对查询结果集的分页与排序处理。
/**
* 需求:查询数据库中王姓的用户,做分页处理,并且根据用户 id 做倒序排序
*/
@Test
public void test6(){
//排序的定义
Sort sort=new Sort(Sort.Direction.DESC,"userid");
//分页的定义
Pageable pageable=new PageRequest(0,2,sort);
//查询条件
Specification<Users> spec = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
return cb.like(root.get("username"),"zhang%");
}
};
Page<Users> page = this.usersDao.findAll(spec, pageable);
System.out.println("当前总条数"+page.getTotalElements());
System.out.println("总页数"+page.getTotalPages());
List<Users> list = page.getContent();
for (Users users:list){
System.out.println(users);
}
}