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

概述

  • 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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容