学习主题:SpringDataJPA
学习目标:
1 掌握SpringDataJPA常用接口类,常用注解
无
对应作业
- Spring Data JPA接口继承结构
- 阐述Spring Data JPA的继承结构。
- SpringDataJPA底层原理
- 阐述Spring Data JPA的底层运行原理。
@PersistenceContext(name="entityManagerFactory")
private EntityManager em;
@Test
public void test1(){
//org.springframework.data.jpa.repository.support.SimpleJpaRepository@fba8bf
//System.out.println(this.usersDao);
//class com.sun.proxy.$Proxy29 代理对象是基于JDK 的动态代理方式创建的
//System.out.println(this.usersDao.getClass());
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
//getRepository(UsersDao.class);可以帮助我们为接口生成实现类。而这个实现类是SimpleJpaRepository 的对象
//要求:该接口必须要是继承Repository 接口
UserDao ud = factory.getRepository(UserDao.class);
System.out.println(ud);//org.springframework.data.jpa.repository.support.SimpleJpaRepository@5fad41be
System.out.println(ud.getClass());//class com.sun.proxy.$Proxy30
}
- Repository接口-方法命名规则查询
- Repository接口的作用是什么?
Repository 接口是Spring Data JPA 中为我我们提供的所有接口中的顶层接口
Repository 提供了两种查询方式的支持
- Repository接口支持几种查询方式?
1)基于方法名称命名规则查询
2)基于@Query 注解查询
- 什么是方法命名规则查询?
规则 :findBy(关键字)+(属性名称的首字母大小写) +查询条件(首字母大写)
- @Query查询JPQL语句
- @Query注解的作用是什么?
@Query 注解查询 , 根据这个注解改写上面的查询方法,注解内使用的HQL语句
- 使用JPQL查询方式t_users表,条件为用户名相等。
/**
* 等值查询
* @param string
* @return
*/
List<Users> findByUsernameIs(String name);
- 使用JPQL查询方式t_users表,条件为用户名Like。
/**
* like关键字查询
* @param string
* @return
*/
List<Users> findByUsernameLike(String name);
- 使用JPQL查询方式t_users表,条件为用户名年龄大于。
/**
* 多条件查询 :名称等于并且年龄大于..
* @param name
* @param age
* @return
*/
List<Users> findByUsernameAndUserageGreaterThanEqual(String name,Integer age);
无
对应作业
- @Query查询SQL语句
- 使用SQL查询方式t_users表,条件为用户名相等。
@Query(value="from Users where username =?")
List<Users> queryByUsername(String name);
- 使用SQL查询方式t_users表,条件为用户名Like。
@Query("from Users where username like ?")
List<Users> queryByUsernameLike(String keywords);
- 使用SQL查询方式t_users表,条件为用户名年龄大于。
@Query("from Users where username =? and userage >=?")
List<Users> queryByUsernameAndUserageGreaterThanEqual(String username,Integer userage);
- @Query更新操作
- @Modifying注解的作用是什么?
标识当前语句是一个更新操作
- CrudRepository接口的使用
- CrudRepository接口的作用是什么?
继承了该接口 ,无需实现类即可完成如下操作
- 分页处理
- PagingAndSortingRepository接口的作用是什么?
用于处理分页和排序
- 通过PagingAndSortingRepository接口完成带分页的查询。
/**
* 分页 page: 当前页的索引。注意索引都是从0 开始的。 size: 每页显示3 条数据
* 导入data.domain.*;
* PagingAndSortingRepository接口不能自己写查询条件进行分页 不过可以自己在定义一个dao接口以及实现。可以对自己的需求做扩展
*/
@Test
public void test() {
int page = 0;
int size = 3;
Pageable pageable = new PageRequest(page, size);
Page<Users> p = this.userDao.findAll(pageable);
System.out.println("数据的总条数 : " + p.getTotalElements());
System.out.println("总页数 :" + p.getTotalPages());
List<Users> list = p.getContent();
for (Users users : list) {
System.out.println(users);
}
- 排序处理
- Sort对象的作用是什么?
该对象封装了排序规则以及指定的排序字段(对象的属性来表示)
- Order对象的作用是什么?
规定查询到的结果是升序还是降序
- Direction参数的作用是什么?
direction:排序规则
- Properties参数的作用是什么?
properties:指定做排序的属性
- JpaRepository接口的使用
- JpaRepository接口的作用是什么?
properties:指定做排序的属性
- JpaSpecificationExecutor接口-单条件查询
- JpaSpecificationExecutor接口的作用是什么?
可以帮助我们将其他接口的方法的返回值做适配处理。可以使得我们在开发时更方便的使用对数据库进行DML操作方法。
- 多条件查询方式一
- 通过JpaSpecificationExecutor接口对t_users表完成多条件的查询。
/**
* 查询所有数据
* 无需强转 ,对比CrudRepository ,故一般会使用这个接口进行增删改查操作
*/
@Test
public void test() {
List<Users> list = this.userDao.findAll();
for(Users users:list) {
System.out.println(users);
}
}
- 多条件查询方式二
- 通过JpaSpecificationExecutor接口对t_users表完成多条件的查询。
/**
* 多条件查询方式一
* 需求:使用用户姓名以及年龄查询数据
*/
@Test
public void test2() {
Specification<Users> spec = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//利用list封装查询条件
ArrayList<Predicate> list = new ArrayList<Predicate>();
list.add(cb.equal(root.get("username") , "卫宫士郎"));
list.add(cb.equal(root.get("userage") , 18));
//此时这两个条件没有关系 ,通过cd再为其加上关系
Predicate[] arr=new Predicate[list.size()];
return cb.and(list.toArray(arr));
}
};
List<Users> users = this.userDao.findAll(spec);
System.out.println(users);
}
- 多条件查询-分页处理
- 通过JpaSpecificationExecutor接口完成对查询结果集的分页处理。
/**
* 带条件的分页查询
* 需求:查询宿州姓用户,并且做分页处理
*/
@Test
public void test4() {
Specification<Users> spec = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.like(root.get("username").as(String.class ),"宿州%");
}
};
Pageable pageable=new PageRequest(0, 2);
Page<Users> page = this.userDao.findAll(spec, pageable);
System.out.println("总条数 : "+page.getTotalElements());
System.out.println("总页数 : "+page.getTotalPages());
for (Users users : page) {
System.out.println(users);
}
}
- 多条件查询-排序处理
- 通过JpaSpecificationExecutor接口完成对查询结果集的排序处理。
/**
* 带条件的排序查询
* 需求:查询数据库中存在宿州的用户,并且根据用户id 做倒序排序
*/
@Test
public void test5() {
Specification<Users> spec = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.like(root.get("username").as(String.class ),"宿州%");
}
};
Sort sort=new Sort(Direction.DESC,"userage");
List<Users> list = this.userDao.findAll(spec, sort);
for (Users users : list) {
System.out.println(users);
}
}
- 多条件查询+分页+排序
- 通过JpaSpecificationExecutor接口完成对查询结果集的分页与排序处理。
/**
* 带条件与排序的分页查询
* 使用的是分页查询的方法
* 需求:查询数据库中存在宿州的用户,做分页处理,并且根据用户id 做倒序排序
*/
@Test
public void Test6() {
//1. 定义排序
Sort sort=new Sort(Direction.DESC,"userid");
Pageable pageable=new PageRequest(0, 2, sort);
//2.定义分页
Specification<Users> spec = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.like(root.get("username").as(String.class), "宿州%");
}
};
Page<Users> page = this.userDao.findAll(spec, pageable);
System.out.println("总条数 : "+page.getTotalElements());
System.out.println("总页数 : "+page.getTotalPages());
for (Users users : page) {
System.out.println(users);
}
}