Spring Data Jpa:基础、关联外键查询

作者: 聪明的奇瑞 | 来源:发表于2017-12-27 10:32 被阅读1408次

    概述

    • spring-data-jpa 是 spring 提供的一个轻量级ORM持久化框架,它 提供了 CRUD(增删改查)的功能,非常方便,可以不写一条Sql语句就能完成数据库操作,并支持 map-reduce 云计算数据服务
    • 它并没实现JPA,是一个管理工具,JPA的底层通常使用Hibernate

    基础使用

    引入依赖库

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    

    声明持久层接口,该接口继承Repository或其子接口,Spring 会生成实现代码

    public interface UserDao extends JpaRepository<User, Serializable>{
        List<User> findByNameLikeAndAgeGreaterThan(String firstName,Integer age);
    }
    

    配置

    #开启包的自动扫描
    entitymanager.packagesToScan= org.konghao.model
    # 数据库连接
    spring.datasource.url=jdbc:mysql://localhost:3306/springboot
    # 用户名
    spring.datasource.username=root
    # 密码
    spring.datasource.password=123456
    # 数据库驱动
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    # 自动更新表
    spring.jpa.properties.hibernate.hbm2ddl.auto=update
    # 使用MYSQL5作为数据库访问方言
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
    #显示sql语句
    spring.jpa.properties.hibernate.show_sql=true
    

    相关接口

    • Repository:仅仅只是一个标识,没有任何方法,方便Spring自动扫描识别
    • CrudRepository:继承Repository,实现一组CRUD相关方法
    • PagingAndStortingRepository:继承CrudRepository,实现一组分页排序相关方法
    • JpaRepository:继承PagingAndStortingRepository,实现一组JPA规范方法

    Spring JPA方法名解析步骤

    • 在进行方法名解析时会先去掉多余的前缀,比如find、findBy、read、readBy、get、getBy,然后对剩下部分进行解析,并且如果方法最后一个参数时 Sort 或 Pageable 类型,也会提取相关信息
    • 比如:findByNameLikeAndAgeGreaterThan
      • 剔除findBy
      • 判断nameLikeAndAgeGreaterThan(根据POJO规范,首字母变小写)是否为返回对象 User 的一个属性,如果是,则根据该属性进行查询,如果没有该属性,则进行下一步
      • 从右往左截取第一个大写字母开头的字符串(此处为Than),然后检查剩下的字符串是否为 User 的一个属性,如果是,则根据该属性进行查询,否则重复第2步,直到找出 name 为 User 的属性
      • 从已截取的部分后面开始,重新第 1 步开始(剔除条件语句),循环,直到把方法名处理完毕
      • 通过获取的操作、条件和属性、带入参数值,生成查询
    关键字 例子 对应的JPQL语句
    And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
    Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
    Is,Equals 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
    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)

    关联外键查询

    • 假设有两张表 article 与 user
    • article 表中有一个 user_id 的外键列对应着 user 表的主键
    • 若查询条件为 id 为 1 的 article 且同时对应 id 为 2 的用户,如下列 SQL 语句:
    SELECT a.* FROM article a JOIN user u ON a.user_id = u.id WHERE a.id = 1 AND u.id = 2
    
    • 则使用 _ 来连接关联实体属性查询,上述 SQL 对应的 JPA 方法名为
    Article findTopByIdAndUser_Id(int articleId,int userId);
    

    限制查询结果数量

    public interface PersonRepository extends JpaRepository<Person,Longs>{
    //获得符合查询条件的前30条数据
    List<Person>findTop30ByName(String name);
    }
    

    通过@query编写创建查询

    • 可以通过@Query(若使用nativesql属性,则使用原生的sql语句)注解来创建查询(参数也可用 ?1 ?2 代替,则不需@Param),如:
    @Query("select * from User u where u.name like :first and u.age>:age")
    List<User> findByNameLikeAndAgeGreaterThan(@Param("first")String firstName,@Param("age")Integer age);
    
    @Modifying 
    @Query("update User u set u.name = ?1 where u.id = ?2") 
    public int increaseSalary(String name, int id);
    
    • @Query可与@Modifying共同使用,用来更新、插入、删除等操作

    JPA 命名查询

    • 通过@NamedQuerys 与 @NamedQuery 注解在实体类上,定义SQL语句
    @Entity
    @NamedQuery(name = "User.findByEmailAddress",query = "select u from User u where u.emailAddress = ?1")
    public class User {}
    
    • 接口只要定义dao层方法即可
    public interface UserDao extends JpaRepository<User, Long> {
        List<User> findByLastname(String lastname);
        User findByEmailAddress(String emailAddress);
    }
    

    查询策略

    • CREATE:从方法名中解析创建SQL语句
    • USE_DECLARED_QUERY:如果通过@Query指定查询语句则使用该语句实现查询,如果没有,判断是否符合命名查询,若都没有则抛出异常
    • CREATE_IF_NOT_FOUND(默认):如果方法通过@Query则使用,否则查找命名查询,若都没有则使用方法名

    事务

    • 默认情况下,Spring Data JPA 的方法都是使用事务的
    • 针对查询类型的方法,等价于@Transactional(readOnly=true)
    • 增删改的方法,等价于@Transactional

    查询关键字

    zWezh.png

    返回值类型

    zWExS.png

    相关文章

      网友评论

        本文标题:Spring Data Jpa:基础、关联外键查询

        本文链接:https://www.haomeiwen.com/subject/vfgygxtx.html