Repository<T, ID>接口
Repository<T, ID>接口的作用:自定义JPQL语句
JPQL:通过 Hibernate 的HQL演变过来的。他和 HQL 语法及其相似。
HQL:Hibernate Query Language(Hibernate查询语言)
SQL:Structure Query Language(结构化查询语言)
区别:
SQL操作的是数据库中的表和字段
HQL:操作是实体对象和属性
我们编写的JPQL最终还是会转换成SQL语句进行执行的
编写新的接口继承Repository<T, ID>接口,T是操作的实体类,ID是实体对应数据库主键的java类型
/**
* 使用@Query注解,自定义JPQL语句
* JPQL语句中,使用的不是表名,而是实体类名,不是列名,而是属性名,
* 例如SQL语句:select * from user JPQL语句是:select User from User
* 如果是条件查询,之前语句中的占位符?可以使用(:xxx)进行表示
* 此时xxx会根据方法中同名的形参自动绑定值
*/
public interface UsersRepositoryByQuery extends Repository<User, Integer> {
//如果是查询所有列,可以省略select ....,从from开始写
@Query("from User where name=:name")
List<User> selectByName(String name); //select * from user where name=?
@Query("select u from User u where name=:name and age=:age")
List<User> selectByNameAndAge(String name, Integer age); //select * from user where name=? and age=?
@Query("from User where name=:name and age=:age")
List<User> selectByNameLike(String name);//select * from user where name like ?
//除了使用JPQL语句,也是可以使用sql原生语句,在注解中设置参数nativeQuery = true,不推荐!
@Query(value = "select * from user where name=:name",nativeQuery = true)
List<User> selectByNameSQl(String name);//select * from user where name=?
}
CrudRepository接口
编写新的接口继承CrudRepository接口<T, ID> T是操作的实体类,ID是实体对应数据库主键的java类型,
CrudRepository就继承了Repository接口,内置类增删改的方法
简单的使用演示:
新建接口继承CrudRepository接口:
/**
* 继承CrudRepository接口的使用
*/
public interface UsersRepositoryExCrud extends CrudRepository<User, Integer> {
}
测试代码:
@Autowired
private UsersRepositoryExCrud crud;
@Test
void testCrud(){
Optional<User> optional = crud.findById(3);
User user = optional.get();
System.out.println(user);
}
运行效果
PagingAndSortingRepository接口
PagingAndSortingRepository接口继承了CrudRepository接口
PagingAndSortingRepository接口主要增加了分页和排序方法
简单的使用演示:
新建接口,继承PagingAndSortingRepository:
public interface UserRepositoryPage extends PagingAndSortingRepository<User,Integer> {
}
测试代码:
@Autowired
private UserRepositoryPage userRepositoryPage;
/**
* 分页
*/
@Test
void testPage(){
//第一个参数是页码数,0表示第一页;第二参数是分页单位;
Pageable Pageable = PageRequest.of(0, 2);
Page<User> page = userRepositoryPage.findAll(Pageable);
System.out.println("总数据量"+page.getTotalElements());
System.out.println("总页数"+page.getTotalPages());
List<User> content = page.getContent();
for (User user : content) {
System.out.println(user);
}
}
/**
* 排序
*/
@Test
void testSort(){
//根据id排序
Sort sort = Sort.by(Sort.Order.desc("id"));
Iterable<User> all = userRepositoryPage.findAll(sort);
for (User user : all) {
System.out.println(user);
}
}
测试结果:
分页查询结果
Hibernate: select user0_.id as id1_7_, user0_.address as address2_7_, user0_.age as age3_7_, user0_.name as name4_7_, user0_.sex as sex5_7_ from user user0_ limit ?
Hibernate: select count(user0_.id) as col_0_0_ from user user0_
总数据量7
总页数4
User{id=3, name='赵六', sex='男', age=33}
User{id=4, name='李四', sex='男', age=22}
排序查询结果
Hibernate: select user0_.id as id1_7_, user0_.address as address2_7_, user0_.age as age3_7_, user0_.name as name4_7_, user0_.sex as sex5_7_ from user user0_ order by user0_.id desc
User{id=10, name='张无忌', sex='男', age=24}
User{id=9, name='张三丰', sex='男', age=108}
User{id=8, name='张三三', sex='女', age=21}
User{id=7, name='张三', sex='男', age=22}
User{id=5, name='王五', sex='男', age=33}
User{id=4, name='李四', sex='男', age=22}
User{id=3, name='赵六', sex='男', age=33}
JpaRepository接口
JpaRepository接口继承了PagingAndSortingRepository接口和 QueryByExampleExecutor接口
JpaRepository 接口是我们开发时使用的最多的接口。其特点是可以帮助我们将其他接口的方法的返回值做适配处理。可以使得我们在开发时更方便的使用这些方法。
简单的使用演示:
创建接口,继承JpaRepository接口
public interface UserRepositoryExJPA extends JpaRepository<User,Integer> {
}
测试代码:
@Autowired
private UserRepositoryExJPA userRepositoryExJPA;
@Test
public void testJpaRepositorySort() {
//Order 定义排序规则
Sort.Order order = Sort.Order.asc("age");
//Sort对象封装了排序规则
Sort sort = Sort.by(order);
List<User> list = userRepositoryExJPA.findAll(sort);
for (User user : list) {
System.out.println(user);
}
}
测试结果JpaSpecificationExecutor 接口
该接口主要提供了多条件查询的支持,并且可以在查询中添加分页与排序
注意:
JpaSpecificationExecutor接口与以上接口没有关系,完全独立。
不能单独使用,需要配合着JPA 中的其他接口一起使用。
简单使用演示:
创建接口,继承JpaSpecificationExecutor接口和其他JPA接口
public interface UserRepositoryExJPA extends JpaRepository<User,Integer>,JpaSpecificationExecutor<User> {
}
测试代码:
@Autowired
private UserRepositoryExJPA userRepositoryExJPA;
/**
* 自定义规则,可以多条件查询
*/
@Test
void testExJPA2() {
Specification<User> specification = new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//模糊查询
Predicate predicate = criteriaBuilder.like(root.get("name"), "张%");
//模糊查询+性别筛选+年龄筛选
Predicate predicate2 = criteriaBuilder.and(criteriaBuilder.like(root.get("name"), "张%"),
criteriaBuilder.equal(root.get("sex"), "男"), criteriaBuilder.gt(root.get("age"), 24));
return predicate2;
}
};
//进行排序年龄进行倒序排列
Sort sort = Sort.by(Sort.Order.desc("age"));
//分页+追加排序
Pageable pageable = PageRequest.of(0, 2, sort);
Page<User> page = userRepositoryExJPA.findAll(specification, pageable);
System.out.println("根据条件查询到" + page.getTotalElements() + "条数据");
System.out.println("根据条件查询到" + page.getTotalPages() + "页数据");
System.out.println("当页数据");
for (User user : page) {
System.out.println(user);
}
}
测试结果