Spring Data JPA

本文深入探讨SpringDataJPA的使用,涵盖JPA规范、动态查询、一对多及多对多关系映射,以及对象导航查询等核心概念。通过实例讲解如何利用SpringDataJPA简化数据库操作,提高开发效率。

JPA规范

JPA

Spring Data JPA入门案例

Spring Data JPA入门

Spring Data JPA 的实现过程

  1. 注入的customerDao对象,本质上是通过JdkDynamicAopProxy生成的一个代理对象

  2. SimpleJpaRepository当中封装了JPA的操作(借助JPAAPI完成数据库的CRUD

  3. 通过hibernate完成数据库操作(封装了jdbc
    在这里插入图片描述

Spring Data JPA查询

Spring Data JPA查询

JPQL 的方式查询

  1. @Query 注解的使用:只需在方法上面标注该注解,同时提供一个JPQL查询语句即可
  2. 使用@Query 来执行一个更新操作,需要用 @Modifying 来将该操作标识为修改查询

SQL 的方式查询

  1. @Query 注解的使用:只需在方法上面标注该注解,同时提供一个SQL查询语句即可
  2. 要将 @Query 中的nativeQuery 改为true

方法命名规则查询

  1. 查询方法以findBy开头
  2. 涉及条件查询时,条件的属性用条件关键字连接
  3. 条件属性首字母需大写
  4. 框架在进行方法名解析时,会先把方法名多余的前缀截取掉,然后对剩下部分进行解析
KeywordSimpleJPQL
AndfindByLastnameAndFirstname… where x.lastname = ?1 and x.firstname = ?2
OrfindByLastnameOrFirstname… where x.lastname = ?1 or x.firstname = ?2
Is,EqualsfindByFirstnameIs, findByFirstnameEquals… where x.firstname = ?1
BetweenfindByStartDateBetween… where x.startDate between ?1 and ?2
LessThanfindByAgeLessThan… where x.age < ?1
LessThanEqualfindByAgeLessThanEqual… where x.age <= ?1
GreaterThanfindByAgeGreaterThan… where x.age > ?1
GreaterThanEqualfindByAgeGreaterThanEqual… where x.age >= ?1
AfterfindByStartDateAfter… where x.startDate > ?1
BeforefindByStartDateBefore… where x.startDate < ?1
IsNullfindByAgeIsNull … where x.age is null
IsNotNull,NotNullfindByAge(Is)NotNull… where x.age not null
LikefindByFirstnameLike… where x.firstname like ?1
NotLikefindByFirstnameNotLike… where x.firstname not like ?1
StartingWithfindByFirstnameStartingWith… where x.firstname like ?1 (parameter bound with appended %)
EndingWithfindByFirstnameEndingWith… where x.firstname like ?1 (parameter bound with prepended %)
ContainingfindByFirstnameContaining… where x.firstname like ?1 (parameter bound wrapped in %)
OrderByfindByAgeOrderByLastnameDesc… where x.age = ?1 order by x.lastname desc
NotfindByLastnameNot… where x.lastname <> ?1
InfindByAgeIn(Collection ages)… where x.age in ?1
NotInfindByAgeNotIn(Collection age)… where x.age not in ?1
TruefindByActiveTrue()… where x.active = true
FalsefindByActiveFalse()… where x.active = false
IgnoreCasefindByFirstnameIgnoreCase… where UPPER(x.firstame) = UPPER(?1)

Specifications 动态查询

Specifications 动态查询

自定义查询条件

  1. 实现Specification接口(提供泛型,查询的对象类型)
  2. 实现 toPredicate方法(构造查询条件)
  3. 需要借助方法参数中的两个参数(root:获取需要查询的对象属性 CriteriaBuilder:构造查询条件的,内部封装了很多的查询条件)
方法名称Sql对应关系
equalfiled = value
gt(greaterThan )filed > value
lt(lessThan )filed < value
ge(greaterThanOrEqualTo )filed >= value
e( lessThanOrEqualTo)filed <= value
notEqulefiled != value
likefiled like value
notLikefiled not like value

JPA 中的一对多

一对多配置

映射注解说明:

@OneToMany:建立一对多的关系映射
属性:
targetEntityClass:指定多的多方的类的字节码
mappedBy:指定从表实体类中引用主表对象的名称(放弃维护主键)
cascade:指定要使用的级联操作
fetch指定是否采用延迟加载
orphanRemoval:是否使用孤儿删除

@ManyToOne:建立多对一的关系
属性:
targetEntityClass:指定一的一方实体类字节码
cascade:指定要使用的级联操作
值:
CascadeType.MERGE级联更新
CascadeType.PERSIST 级联保存:
CascadeType.REFRESH 级联刷新:
CascadeType.REMOVE 级联删除:
CascadeType.ALL 包含所有
fetch:指定是否采用延迟加载
optional:关联是否可选。如果设置为false,则必须始终存在非空关系。

@JoinColumn用于定义主键字段和外键字段的对应关系。
属性:
name:指定外键字段的名称
referencedColumnName:指定引用主表的主键字段名称
unique:是否唯一,默认值不唯一
nullable:是否允许为空。默认值允许。
insertable:是否允许插入。默认值允许。
updatable:是否允许更新。默认值允许。
columnDefinition:列的定义信息。

JPA 中的多对多

JPA 中的多对多

映射注解说明:

@ManyToMany:用于映射多对多关系
属性:
cascade:配置级联操作。
值:
CascadeType.MERGE级联更新
CascadeType.PERSIST 级联保存:
CascadeType.REFRESH 级联刷新:
CascadeType.REMOVE 级联删除:
CascadeType.ALL 包含所有
mappedBy:放弃对中间表的维护
fetch:配置是否采用延迟加载。
targetEntity:配置目标的实体类。映射多对多的时候不用写。

@JoinTable:针对中间表的配置
属性:
name:配置中间表的名称
joinColumns:中间表的外键字段关联当前实体类所对应表的主键字段
inverseJoinColumn:中间表的外键字段关联对方表的主键字段

@JoinColumn用于定义主键字段和外键字段的对应关系。
属性:
name:指定外键字段的名称
referencedColumnName:指定引用主表的主键字段名称
unique:是否唯一,默认值不唯一
nullable:是否允许为空。默认值允许。
insertable:是否允许插入。默认值允许。
updatable:是否允许更新。默认值允许。
columnDefinition:列的定义信息。

对象导航查询

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class ObjectQueryTest {
    @Autowired
    private CustomerDao customerDao;
    @Autowired
    private LinkManDao linkManDao;

    //测试对象导航查询(查询一个对象的时候,通过此对象查询所有的关联对象)
    //对象导航查询(一的一方查询多的一方),默认使用的是延迟加载的形式查询的
    //修改配置(fetch):将延迟加载该为立即加载
    @Test
    @Transactional  //解决在Java代码中的no session问题
    @Rollback(value = false)
    public void testQuery1(){
        //查询id为1的客户
        Customer customer = customerDao.findOne(1L);
        //对象导航查询,客户下的所有联系人
        Set<LinkMan> linkMans = customer.getLinkMen();
        for(LinkMan linkMan : linkMans){
            System.out.println(linkMan);
        }

    }

    //对象导航查询(多的一方查询一的一方),默认使用的是立即加载的形式查询的
    @Test
    @Transactional  //解决在Java代码中的no session问题
    @Rollback(value = false)
    public void testQuery2(){
        //查询id为1的联系人
        LinkMan linkMan = linkManDao.getOne(1L);
        //对象导航查询,联系人的kehu
        Customer customer = linkMan.getCustomer();
        System.out.println(customer);
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值