博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring Data JPA 自定义Repository接口与子接口
阅读量:3927 次
发布时间:2019-05-23

本文共 7783 字,大约阅读时间需要 25 分钟。

上篇文章介绍了 Repository接口的使用(),接下来重点掌握 Repository的CrudRepository子接口下的子接口。

在dao层的接口中定义方法,查询的方法:find或get或read开头,遵守一些规定:

Keyword Sample JPQL snippet

And

findByLastnameAndFirstname

… where x.lastname = ?1 and x.firstname = ?2

Or

findByLastnameOrFirstname

… where x.lastname = ?1 or x.firstname = ?2

IsEquals

findByFirstname,findByFirstnameIs,findByFirstnameEquals

… where x.firstname = ?1

Between

findByStartDateBetween

… where x.startDate between ?1 and ?2

LessThan

findByAgeLessThan

… where x.age < ?1

LessThanEqual

findByAgeLessThanEqual

… where x.age <= ?1

GreaterThan

findByAgeGreaterThan

… where x.age > ?1

GreaterThanEqual

findByAgeGreaterThanEqual

… where x.age >= ?1

After

findByStartDateAfter

… where x.startDate > ?1

Before

findByStartDateBefore

… where x.startDate < ?1

IsNullNull

findByAge(Is)Null

… where x.age is null

IsNotNullNotNull

findByAge(Is)NotNull

… where x.age not null

Like

findByFirstnameLike

… where x.firstname like ?1

NotLike

findByFirstnameNotLike

… where x.firstname not like ?1

StartingWith

findByFirstnameStartingWith

… where x.firstname like ?1 (parameter bound with appended %)

EndingWith

findByFirstnameEndingWith

… where x.firstname like ?1 (parameter bound with prepended %)

Containing

findByFirstnameContaining

… where x.firstname like ?1 (parameter bound wrapped in %)

OrderBy

findByAgeOrderByLastnameDesc

… where x.age = ?1 order by x.lastname desc

Not

findByLastnameNot

… where x.lastname <> ?1

In

findByAgeIn(Collection<Age> ages)

… where x.age in ?1

NotIn

findByAgeNotIn(Collection<Age> ages)

… where x.age not in ?1

True

findByActiveTrue()

… where x.active = true

False

findByActiveFalse()

… where x.active = false

IgnoreCase

findByFirstnameIgnoreCase

… where UPPER(x.firstame) = UPPER(?1)

 

Repository的子接口的使用时只需要 dao层继承该接口即可。

一、CrudRepository接口

CrudRepository接口还有一个PagingAndSortingRepository子接口:

CrudRepository 主要提供CRUD功能。

PagingAndSortingRepository 提供进行分页和排序记录的方法。

1、CrudRepository 主要提供CRUD功能。

    CrudRepository接口的方法:很好理解就不解释了,下面使用几个即可快速掌握。

    

public interface UserDao extends CrudRepository
{}

测试:

@Test    public void test() {        User user = new User();        user.setUsername("赵云");        user.setPassword("123456");        user.setAge(18);        user.setCreatetime(LocalDateTime.now());        User save = userDao.save(user);        System.out.println(save.getId()); // 4    }    @Test    public void testList() {        List
list = new ArrayList<>(); for (int i = 0; i < 20; i++) { User user = new User(); user.setUsername("赵云" + i); user.setPassword("123456"); user.setAge(18 + i); user.setCreatetime(LocalDateTime.now()); list.add(user); } List
saveAll = (List
) userDao.saveAll(list); // id 不存在,会报错:org.springframework.dao.EmptyResultDataAccessException: // No class cn.jq.springdatajpademo.model.User entity with id 2 exists! userDao.deleteById(2L); }

2、PagingAndSortingRepository 提供进行分页和排序记录的方法。

        

   Pageable是一个接口,这里使用 PageRequest类

        

测试:

@Test    public void test() {        Sort.Order order1 = new Sort.Order(Sort.Direction.ASC, "age");        Sort.Order order2 = new Sort.Order(Sort.Direction.DESC, "id");        Sort sort = Sort.by(order1, order2);        // 查询第3页        Pageable pageRequest = PageRequest.of(2, 10, sort);        Page
page = userDao.findAll(pageRequest); List
userList = page.getContent(); // 数据 int number = page.getNumber(); // 当前页码,注意默认从0开始 int totalPages = page.getTotalPages(); // 总页码数 int numberOfElements = page.getNumberOfElements(); // 当前页码记录数 long totalElements = page.getTotalElements(); // 总的数量 int size = page.getSize(); // 每页的记录数 System.out.println("userList = " + userList); System.out.println("number = " + number + 1); System.out.println("totalPages = " + totalPages); System.out.println("numberOfElements = " + numberOfElements); System.out.println("totalElements = " + totalElements); System.out.println("size = " + size); }

3、JpaRepository接口是项目开发时使用最多的接口。

JpaRepository继承自PagingAndSortingRepository接口,JpaRepository基于JPA的Repository接口,极大减少了JPA作为数据访问的代码,JpaRepository是实现Spring Data JPA技术访问数据库的关键接口。

public interface UserDao extends JpaRepository
{}

   

测试:

@Test    public void test() {        User user = new User();        user.setUsername("赵云胜多负少");        user.setPassword("123456");        user.setAge(18);        user.setCreatetime(LocalDateTime.now());//        主键存在update,不存在就insert操作//        user.setId(4L);        User saveAndFlush = userDao.saveAndFlush(user);        System.out.println(saveAndFlush.getId());    }

二、JpaSpecificationExecutor接口

JpaSpecificationExecutor 是 JPA 2.0 提供的 Criteria API 的使用封装,可以用于动态生成 Query 来满足我们业务中的各种复杂场景。

Spring Data JPA 为我们提供了 JpaSpecificationExecutor 接口。该接口通过Specification来定义查询条件,使用Specification的要点就是CriteriaBuilder,通过这个对象来创建条件,之后返回一个Predicate对象。这个对象中就有了相应的查询需求,我们同样可以定义多个Specification,之后通过Specifications对象将其连接起来。

       

通过源码看出:SimpleJpaRepository类是JpaSpecificationExecutor接口的默认实现。

    

 

测试:

public interface UserDao extends JpaRepository
, JpaSpecificationExecutor {}
@Test    public void test() {        Specification
s1 = new Specification
() { /** * @param *root: 代表查询的实体类. * @param criteriaQuery: 可以从中可到 Root 对象, 即告知 JPA Criteria 查询要查询哪一个实体类. 还可以 * 来添加查询条件, 还可以结合 EntityManager 对象得到最终查询的 TypedQuery 对象.使用不多 * @param *criteriaBuilder: CriteriaBuilder 对象. 用于创建 Criteria 相关对象的工厂. 当然可以从中获取到 Predicate 对象 * @return: *Predicate 类型, 代表一个查询条件. */ @Override public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { Path
age = root.get("age"); Predicate p1 = criteriaBuilder.greaterThan(age, 18); Path username = root.get("username"); Predicate p2 = criteriaBuilder.like(username, "%李四%"); // where user0_.age>18 and ( user0_.username like ? ) return criteriaBuilder.and(p1, p2); } }; List list1 = userDao.findAll(s1); System.out.println(list1); }

三、自定义Repository接口

如果SpringData提供的JPA接口没有我们需要的查询方式,也是可以自定义Repository接口的。

spring data除了已经给我们提供了大量的 Repository接口,它支持我们自己定义Repository接口来扩展功能,实现一些个性化的需求。

1、自定义Repository接口的具体步骤:

1)新建一个自定义接口

// 自定义 Repository接口public interface MyUserRepository {    List
findByAge(Integer age);}

2)新建该自定义接口的实现类,并对方法进行实现,需要注入 EntityManager对象完成对数据库的操作

public class MyUserRepositoryImpl implements MyUserRepository {    // 这里使用JPA技术实现    @PersistenceContext    private EntityManager entityManager;    @Override    public List
findByAge(Integer age) { String jpql = "select u from User u where u.age <= ?1"; Query query = entityManager.createQuery(jpql, User.class); query.setParameter(1, age); List
resultList = query.getResultList(); return resultList; }}

注意:实现类的名称必须是该自定义接口的名称+Impl,名称会由SpringData解析。

        EntityManager是JPA中用于增删改查的接口,它的作用相当于一座桥梁,连接内存中的 Java对象和数据库的数据存储。也可以根据它进行sql的原生查找。

3)在目标接口(dao层接口)中继承该自定义接口。

public interface UserDao extends JpaRepository
, MyUserRepository { // spring data jpa 方法 List
findUsersByUsernameLikeAndAgeLessThanEqual(String username, Integer age);}

4)测试类,目标接口(dao层接口)就可以使用自定义接口方法

@Test    public void testList() {        List
userList = userDao.findByAge(18); System.out.println(userList); List
userList2 = userDao.findUsersByUsernameLikeAndAgeLessThanEqual("%赵云%", 18); System.out.println(userList2); }

   

 

 

参考文章:

 

—— Stay Hungry. Stay Foolish. 求知若饥,虚心若愚。

转载地址:http://lgdgn.baihongyu.com/

你可能感兴趣的文章
gdb命令手册
查看>>
gdb中设置共享库断点问题
查看>>
GBD调试程序(转)作者:Janlex
查看>>
第16章可移植性
查看>>
java读取和修改ini配置文件实例代码
查看>>
setsockopt 设置socket 详细用法
查看>>
在局域网中实现多播功能
查看>>
什么叫组播地址(Multicast Address )?
查看>>
掌握IP地址知识 子网掩码与子网划分
查看>>
组播地址,IP组播地址
查看>>
什么是组播
查看>>
组播通信
查看>>
Linux网络编程一步一步学-UDP组播
查看>>
Linux C编程---网络编程
查看>>
在Linux创建库函数(1)
查看>>
在Linux创建库函数(2)
查看>>
在Linux创建库函数(3)
查看>>
多VLAN环境下DHCP服务的实现
查看>>
Java实现文件拷贝的4种方法
查看>>
在pb11中将C/S程序转换到B/S的步骤
查看>>