spring-data-jpa简单使用(二)

1:使用spring-data-jpa很简单,只需要在dao层继承repository接口即可。那么repository接口是什么呢?

 可以看到repository接口下面什么都没有,这表明它是一个标记接口。标记接口的作用的什么?标记接口的作用是把当前类纳入到spring的容器中,继承了这个类你会发现

这个标记我想使用idea的同志们都不会陌生的,因为这个表明,当前的类已经被纳入到spring容器中,可以被spring扫描到。那么,除了继承Repository这个接口,还可以怎么做 -> 在接口上加上@RepositoryDefinition注解

RepositoryDefinition注解中有两个属性(domainClass,idClass)一个标识实体类的字节码类型和主键的字节码类型

但是我们一般不用这个注解,这里我们了解一下知道他是怎么搞的就行:无非就是用了spring的aop和反射来实现的。

下面我们来看看spring-data-jpa有哪些接口

那么查询方法的规则和使用又是怎么样的呢?

在接口下面定义的方法必须遵循这些规则

上代码:

     1:查询出名字以胡开头,并且年龄小于25

    @Test
    public void test1(){
        // 查询出名字以胡开头,并且年龄小于25
        List<User> users = userRepository.findByNameLikeAndAgeLessThan("胡%",25);
        users.forEach(p -> System.out.println(p.getName() + " ,年龄" + p.getAge()));
    }

    2:使用原生的sql进行查询

    @Query(value = "select * from user u where u.name like ?1% and age > ?2",nativeQuery = true)
    List<User> findUser(String name,int age);

      需要使用@Query注解和nativeQuery属性

   3: 不使用原生的sql进行查询

    @Query(value = "select u from User u where u.salary > ?1")
    List<User> findSalary(double salary);

     from后面就不能写表名了,只能写表对应的映射名称   ?1代表占位符,当前你也可以使用:如下

    @Query(value = "select u from User u where u.id = :id")
    User findUser(@Param("id")long id);

   这有一个误区:就是冒号后面对应的值应该和@Param里面的值一致,否则或报错

    @Query(value = "select u from User u where u.id = :idd")
    User findUser(@Param("idd")long id);

这是正确的,注解里面的值和冒号后面的值对应。下面是错误的:

    @Query(value = "select u from User u where u.id = :idd")
    User findUser(@Param("id")long idd);

4:修改查询

    @Modifying
    @Query(nativeQuery = true,value = "update user u set u.address = ?2 where u.id = ?1")
    void update(Long id,String address);

     需要@Modifying注解和@Query注解和@Transactional注解(放在service层) 缺一不可.

5:关联查询什么之类的就不用我多嘴了吧 直接@Query注解加上nativeQuery属性搞起来,原生sql别说你不会哈!!!

分页排序:

     这里需要两个对象:Sort和PageRequest

代码如下:

    public List<User> getUsers(){
        // 安装薪资降序
        Sort sort = new Sort(Sort.Direction.DESC,"salary");

        // 每页大小十页
        PageRequest pageRequest = PageRequest.of(0,10,sort);
        List<User> users = userRepsoitory.findAll(pageRequest).getContent();

        return users;
    }

 具体方法点进去看api需要什么参数

那么?更复杂点的动态sql分页排序查询,spring-data-jpa能解决吗?我们知道mybatis可以在xml文件中使用if,for之类的标签来判断,构造动态sql;那spring-data-jpa怎么构建:

这个时候就需要一个强大的对象出马:

   Specification 和JpaSpecificationExecutor<T>

代码如下:

   public List<User> conditionalQuery(User user){
        Specification<User> specification = new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
                // root:可用从root中拿到User的属性
                // cq:用来查询
                // cb:用来构造查询条件
                List<Predicate> predicates = new ArrayList<>();
                if (!StringUtils.isBlank(user.getName())) {
                    predicates.add(cb.like(root.get("name"),user.getName() + "%"));
                }

                if (user.getAge() > 0) {
                    predicates.add(cb.gt(root.get("age"),user.getAge()));
                }

                if (user.getSalary() > 0) {
                    predicates.add(cb.gt(root.get("salary"),user.getSalary()));
                }

                Predicate result = cb.and(predicates.toArray(new Predicate[predicates.size()]));

                return result;
            }
        };
        // 这个排序分页还记得怎么操作吗?
        PageRequest pageRequest = PageRequest.of(0,10,Sort.Direction.DESC,"salary");

        List<User> users = userRepsoitory.findAll(specification, pageRequest).getContent();
        return users;
    }
}

dao层需要继承JpaSpecificationExecutor<User>,然后用JpaSpecificationExecutor<User>的findAll方法;

结果如下:

     按薪水降序:

[
    {
        "id": 5,
        "name": "胡歌",
        "age": 30,
        "salary": 2100000,
        "address": "上海"
    },
    {
        "id": 17,
        "name": "胡歌",
        "age": 27,
        "salary": 2100000,
        "address": "上海"
    },
    {
        "id": 18,
        "name": "胡歌",
        "age": 30,
        "salary": 2100000,
        "address": "上海"
    },
    {
        "id": 21,
        "name": "胡歌",
        "age": 27,
        "salary": 2100000,
        "address": "上海"
    },
    {
        "id": 19,
        "name": "胡歌",
        "age": 26,
        "salary": 21000,
        "address": "上海"
    },
    {
        "id": 20,
        "name": "胡歌",
        "age": 19,
        "salary": 18000,
        "address": "上海"
    }
]

总结:

   1:简单的查询可以直接调用JpaRepository的方法和其命名规范查询

   2:关联查询可以使用@Query注解加nativeQuery属性

   3:动态sql分页排序查询可以使用Specification和JpaSpecificationExecutor接口

猜你喜欢

转载自blog.csdn.net/qq_36957587/article/details/84673201