zoukankan      html  css  js  c++  java
  • SpringDataJPA对数据库的操作的几种方式

    1:SpringDataJPA是JPA规范的再次封装抽象,底层还是使用了HibernateJPA技术实现,是属于Spring的生成体系中的一部分

    2:SpringData的结构(七个接口)

    操作数据库的方式一:继承JpaRepository口后操作数据库

      1:在Repository层新建一个基础接口

     
    1 @NoRepositoryBean //告诉JPA不要创建对应接口的bean对象
    2 public interface BaseReposittory <T,ID extends Serializable> extends JpaRepository<T,ID>{
    3 }

      2:再建一个你所要操作的类型的接口去继承 这里以实体类Employee举例  这里Long是数据库中主键的类型   完成后就已经具备了基础的CRUD 和分页排序的功能

     1 public interface EmployeeRepository extends BaseReposittory<Employee,Long>{ 

      注意:在操作数据库时 添加和修改所使用的都是save()方法 ;可以自行测试   这里测试一个分页排序

    1 @Test//分页排序
    2     public void pageAndSort() throws Exception{
    3         Sort sort = new Sort(Sort.Direction.DESC,"age");
    4          Pageable page = new PageRequest(0,10,sort);
    5         Page<Employee> employees = employeeRepository.findAll(page);
    6         employees.forEach(e->{
    7             System.out.println(e);
    8         });
    9     }

      基础查询和分页排序底层已经定义好可以直接使用 现在我们来自定义查询; 查询方法写在EmployeeRepository

    自定义查询

    方式一:按照规范创建查询方法,一般按照java驼峰式书写规范加一些特定关键字

      例:  

    1  //根据名称模糊查询
    2     List<Employee> findByUsernameLike(String username);
    3     //根据名称进行查询
    4     List<Employee> findByUsername(String username);

    查询规则如下:

    表达式

    例子

    hql查询语句

    And

    findByLastnameAndFirstname

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

    Or

    findByLastnameOrFirstname

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

    Is,Equals

    findByFirstname,findByFirstnameIs,findByFirstnameEqual

    … where x.firstname = 1?

    Between

    findByStartDateBetween

    … where x.startDate between 1? and ?2

    LessThan(lt)

    findByAgeLessThan

    … where x.age < ?1

    LessThanEqual(le)

    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

    IsNull

    findByAgeIsNull

    … where x.age is null

    IsNotNull,NotNull

    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 ages)

    … where x.age in ?1

    NotIn

    findByAgeNotIn(Collection age)

    … 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)

    方式二:@Query注解查询

    EmployeeRepository 按照查询方法的命名规则,其实是比较麻烦的如果我们想不遵循 查询方法的命名规则,还可以使用@Query的方法进行查询。只需要将@Query定义在Respository的方法之上即可

     

      1:使用jpql语句操作数据库

      例:

     

    1    //根据用户名查询(这里写必需在问号后加顺序)
    2     @Query("select e from Employee e where e.username = ?1")
    3     Employee query01(String name);
    4     //根据用户名模糊查询(这里写必需在问号后加顺序)
    5     @Query("select e from Employee e where e.username like ?1")
    6     List<Employee> query02(String name);
    7     //根据用户名与邮件进行模糊查询(这里写必需在问号后加顺序)
    8     @Query("select e from Employee e where e.username like ?1 and e.email like ?2")
    9     List<Employee> query03(String name, String email);

     

      2:如果想用原生sql操作数据库只需在注解@Query中加nativeQuery =true 

      例:

    1   //查询所有
    2     @Query(nativeQuery =true,value = "select * from employee where username=?;")
    3     Employee query04(String name);

     

     方式三:继承接口JpaSpecificationExecutor

        JpaSpecificationExecutor的认识  

        JpaSpecificationExecutor(JPA规则执行者)JPA2.0提供的Criteria API的使用封装,可以用于动态生成Query来满足我们业务中的各种复杂场景。

        Spring Data JPA为我们提供了JpaSpecificationExecutor接口,只要简单实现toPredicate方法就可以实现复杂的查询。所有查询都要求传入一个Specification对象

      1:BaseReposittory的操作

    @NoRepositoryBean //告诉JPA不要创建对应接口的bean对象
    public interface BaseReposittory <T,ID extends Serializable> extends JpaRepository<T,ID>,JpaSpecificationExecutor<T> {
    }

     

      2:测试:直接来个多条件查询

      

     1 /**
     2      * 根据相应的规则(Specification) 查询对应数据
     3      *  Predicate: where username=? and email =?
     4      *      root : 根 -> 可以获取到类中的属性(username,email)
     5      *      criteriaQuery: 如select,from,where,group by ,order by 等
     6      *      criteriaBuilder:解决 username=? / username like ? / age > ?
     7      *                      多个条件结合 username=?  and/or  age > ?
     8      */
     9     @Test//多条件查询+分页+排序
    10     public void testJpaSpecificationExecutor() throws Exception{
    11         //先定义规范
    12         Specification spec= new Specification<Employee>() {
    13             @Override
    14             public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> cq, CriteriaBuilder cd) {
    15                 Path usernamePath = root.get("username");
    16                 Predicate p1 = cd.like(usernamePath, "%1%");
    17                 Path emailPath = root.get("email");
    18                 Predicate p2 = cd.like(emailPath, "%2%");
    19                 Path agePath = root.get("age");
    20                 Predicate p3 = cd.ge(agePath, 18);//le 表示小于 ge表示大于
    21                 //多个条件连接起来
    22                 Predicate p = cd.and(p1, p2, p3);
    23                 return p;
    24             }
    25         };
    26         //进行排序
    27         Sort sort = new Sort(Sort.Direction.ASC,"username");
    28         //进行分页
    29         Pageable page=new PageRequest(0,10,sort);
    30         //查询数据库
    31         Page p = employeeRepository.findAll(spec, page);
    32         p.forEach(e->{
    33             System.out.println(e);
    34         });
    35     }

    Root:查询哪个表(定位到表和字段-> 用于拿到表中的字段)
     *            可以查询和操作的实体的根
     *              Root接口:代表Criteria查询的根对象,Criteria查询的查询根定义了实体类型,能为将来导航获得想要的结果,它与SQL查询中的FROM子句类似
     *             Root<Employee> 相当于 from Employee
     *             Root<Product> 相当于  from Product
     *        CriteriaQuery:查询哪些字段,排序是什么(主要是把多个查询的条件连系起来)
     *        CriteriaBuilder:字段之间是什么关系,如何生成一个查询条件,每一个查询条件都是什么方式
     *                      主要判断关系(和这个字段是相等,大于,小于like等)
     *        PredicateExpression):单独每一条查询条件的详细描述 整个 where xxx=xx and yyy=yy ...

     

     

    方式四:使用jpa-spec插件的前提是要实现JpaSpecificationExecutor接口(我这里是接口继承了接口)

      1:在Maven项目中pom.xml引入包

     

    <!--  jpa的SpecificationSpecification功能封装 -->
    <dependency>
      <groupId>com.github.wenhao</groupId>
      <artifactId>jpa-spec</artifactId>
      <version>3.1.1</version>
      <!-- 把所有依赖都过滤 -->
      <exclusions>
        <exclusion>
          <groupId>*</groupId>
          <artifactId>*</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

      2:功能测试:

     

     1 @Test// 多个条件查询 +分页+排序
     2     public void testSpec() throws Exception{
     3         Specification<Employee> spec = Specifications.<Employee>and()
     4                 .like("username","%1%")
     5                 .like("email","%2%")
     6                 .ge("age", 20)
     7                 .build();
     8         Sort sort = new Sort(Sort.Direction.DESC,"age");//根据年龄排序
     9         Pageable page = new PageRequest(0,10,sort);
    10         Page<Employee> list = employeeRepository.findAll(spec, page);
    11         list.forEach(e->{
    12             System.out.println(e);
    13         });
    14     }

     

     

     

  • 相关阅读:
    日志组件一:Log4j
    HTTPS加密那点事--轻松秒懂HTTPS非对称加密
    图解Git
    Python 迭代器 & __iter__方法
    Fiddler 抓包工具总结
    Python使用struct处理二进制(pack和unpack用法)
    Python binascii
    常见证书格式及相互转换
    MyBatis Generator 详解
    MyBatis学习总结(八)——Mybatis3.x与Spring4.x整合
  • 原文地址:https://www.cnblogs.com/logoman/p/11679800.html
Copyright © 2011-2022 走看看