JPA访问数据库的几种方式
JPA访问数据库的几种方式
本文为原创,转载请注明出处:https://www.cnblogs.com/supiaopiao/p/10901793.html
1. Repository
1.1. 通过方法名称直接生成查询
|
Keyword |
Sample |
JPQL snippet |
|
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<Age> ages) |
… where x.age in ?1 |
|
NotIn |
findByAgeNotIn(Collection<Age> ages) |
… 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) |
In和NotIn可以使用任何Collection的子类作为参数。
案例:
|
public interface UserRepository extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User> { List<User> findByNameAndPhone(String name, String phone); User findUserById(Integer id); void deleteByIdIn(List<Integer> idList); |
1.2. @Query注解
可以使用Spring Data JPA 的@Query注解将查询绑定到repository的函数上。
备注:注解到查询方法上的@Query执行顺序优先于下文中的@NamedQuery。
1.2.1. HQL
注意:使用“:属性名”的时候,最好在接口上加上@Param注解,否则会报类似如下异常:

|
public interface UserRepository extends JpaRepository<User, Integer>{ @Query(value = "SELECT u FROM User u WHERE u.name like %:name% and u.sex = :sex") |
1.2.2. 原生SQL
(1)@Query注解通过设置nativeQuery标识支持执行原生SQL查询语句
|
public interface UserRepository extends JpaRepository<User, Integer>{ } |
(2)Spring Data JPA通过原生SQL进行查询时,不能满足Page条件进行分页,所以可以通过countQuery标识执行count查询实现Page分页:
|
public interface UserRepository extends JpaRepository<User, Integer>{ |
1.3. @Modifying注解
- 在@Query注解中编写JPQL实现DELETE和UPDATE操作的时候必须加上@Modifying注解,以通知Spring Data这是一个DELETE或UPDATE操作。
- UPDATE或者DELETE操作需要使用事务,此时需要定义Service层,在Service层的方法上添加事务操作@Transactional。
- Modifying查询语句中能用于void/int/Integer 返回类型,不能用于其他类型
- 注意JPQL不支持INSERT操作。
代码示例:
|
public interface UserRepository extends JpaRepository<User, Integer>{ @Modifying @Modifying } |
2. 实体类中定义,在Repository中使用
2.1. 命名查询@NamedQuery
使用@NamedQuery为实体创建查询适用于定义少量查询。@NamedQuery需要声明在实体类上,@NamedQuery可以实现命名HQL查询(或JPQL)。
备注:注解到查询方法上的@Query(上文中)执行顺序优先于@NamedQuery。
|
@Entity @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="name",nullable=false) @Column(name="sex",nullable=false) Set、get方法省略 |
Repository层代码展示:
|
public interface TwoRepository extends JpaRepository<Two, Integer>{ |
Spring Data处理这些方法对命名查询的调用,以实体类名称开始,后接方法名,以点作连接符。所以NameQuery定义在实体上,而不是定义在方法上。
2.2. 一个实体类中有多个命名查询@NamedQueries
上面我们演示了命名查询@NamedQuery的写法,当然JPA也支持多个@NamedQuery,那就是@NamedQueries
|
@Entity public class Two { @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="name",nullable=false) @Column(name="sex",nullable=false) Set、get方法省略 |
Repository层代码展示:
|
public interface TwoRepository extends JpaRepository<Two, Integer>{ |
Spring Data处理这些方法对命名查询的调用,以实体类名称开始,后接方法名,以点作连接符。所以NameQuery定义在实体上,而不是定义在方法上。
2.3. 命名原生sql查询@NamedNativeQuery
@NamedNativeQuery可以实现命名原生sql查询
|
@Entity @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="name",nullable=false) @Column(name="sex",nullable=false) Set、get方法省略 |
Repository层代码展示:
|
public interface ThreeRepository extends JpaRepository<Three, Integer>{ |
2.4. 一个实体类中有多个命名查询@NamedNativeQueries
上面我们演示了命名查询@NamedNativeQuery的写法,当然JPA也支持多个@NamedNativeQuery,那就是@NamedNativeQueries
|
@Entity @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="name",nullable=false) @Column(name="sex",nullable=false) Set、get方法省略 |
Repository层代码展示:
|
public interface ThreeRepository extends JpaRepository<Three, Integer>{ |
3. 外部ORM文件中定义,在Repository中使用
3.1. 命名查询named-query
使用XML配置,向位于resources/META-INF文件夹下的orm.xml配置文件添加必要的<name-query/>元素。
resources/META-INF下orm.xml配置:
|
<?xml version="1.0" encoding="UTF-8" ?> <!-- JPA Named Queries --> <named-query name="One.findUserByPrimaryKey"> |
Repository层代码展示:
|
public interface OneRepository extends JpaRepository<One, Integer>{ |
3.2. 原生SQL查询named-native-query
使用XML配置,向位于resources/META-INF文件夹下的orm.xml配置文件添加必要的<named-native-query/>元素。
resources/META-INF下orm.xml配置:
|
<?xml version="1.0" encoding="UTF-8" ?> <!-- JPA Named Native Queries --> <!--result-class用来指定实体类,result-set-mapping用来指定映射的名称--> |
Repository层代码展示:
|
package cn.com.bmsoft.stormplan.basic.dao; import cn.com.bmsoft.stormplan.basic.entity.One; import java.util.List; public interface OneRepository extends JpaRepository<One, Integer>{ |
4. SpEL表达式
从Spring Data JPA 1.4版本开始,支持在@Query定义的查询中使用SpEL模板表达式。在执行查询的时候,这些表达式通过一个事先定义好的变量集合求值。Spring Data JPA支持一个名为entityName的变量。它的用法是select x from #{#entityName} x。它会将域类型的entityName与给定repository关联起来。entityName按照如下方式处理:如果域类型在@Entity注解上设置了name属性,则使用该属性。否则直接使用域类型的类名。
下例演示了在定义带有查询方法和手工定义查询的repository接口时使用#{#entityName}表达式。
|
public interface UserRepository extends JpaRepository<User, Integer>{ |
SpEL表达式的好处:
参考网址:https://www.cnblogs.com/tilv37/p/6944182.html
5. Specifications动态构建查询
5.1. 参数介绍
- Predicate:单独每一条查询条件的详细描述
Predicate[]:多个查询条件的详细描述
- Root:查询哪个表
- CriteriaQuery:查询哪些字段,排序是什么
- CriteriaBuilder:字段之间是什么关系,如何生成一个查询条件,每个查询条件都是什么方式
(1)CriteriaQuery<T>:主要是构建查询条件
distinct、select、where、groupby、having、orderby等
(2)CriteriaBuilder:主要是用来进行一些函数操作
① and
② or
③ between
④ lt(小于)、le(小于等于)、gt(大于)、ge(大于等于)
⑤ not(非)等...
5.2. 代码案例
//where empname like ? group by wages
|
@Override |
//where empname like ? or deptid=?
|
@Override |
//where wages < ?
|
@Override |
//where wages between ? and ?
|
@Override |
6. JPA Join联表查询
构建表关系如下:

实体类代码展示:
|
@Entity @Column(name="aname",nullable=false) 省略set、get方法 |
@Entity @Column(name="bname",nullable=false) @OneToOne(cascade=CascadeType.ALL) //B是关系的维护端,当删除 b,会级联删除 a 省略set、get方法 |
|
@Entity @Column(name="cname",nullable=false) } |
@Entity @Column(name="dname",nullable=false) //可选属性optional=false,表示B不能为空。删除d,不影响b @ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},optional=false) |
Service层代码展示:
|
@Override //A:B:D 1:1:n 根据D的实体类查询aname |
JPA访问数据库的几种方式的更多相关文章
- Spring框架访问数据库的两种方式的小案例
1.1 以Xml的方式访问数据库的案例 要以xml的方式访问数据库需要用到JdbcTemplate ,因为 JdbcTemplate(jdbc的模板对象)在Spring 中提供了一个可以操作数据库的对 ...
- .NET访问数据库的两种方式(C#语言)
一.直接使用C#操作数据库的类库ADO.NETADO.NET使用Connection对象来连接数据库,使用Command或DataAdapter 对象来执行SQL语句,并将执行的结果返回给DataRe ...
- Asp.net 访问数据库的几种方式
ASP.NET中连接数据库的各种方法 连接SQL数据库的方法:(一).在Web.Config中创建连接字符串:1.<add name="ConnectionString" c ...
- .Net 中读写Oracle数据库常用两种方式
.net中连接Oracle 的两种方式:OracleClient,OleDb转载 2015年04月24日 00:00:24 10820.Net 中读写Oracle数据库常用两种方式:OracleCli ...
- plsql 连接oracle数据库的2种方式
plsql 连接oracle数据库的2种方式 CreationTime--2018年8月10日09点50分 Author:Marydon 方式一:配置tnsnames.ora 该文件在instan ...
- Code First03---CodeFirst根据配置同步到数据库的三种方式
上一节我们说到使用Fluent API对实体的配置,但是有一个问题了,在业务中我们可以用到的实体很多,那是不是每个都需要这样去配置,这样就造成我们重写的OnModelCreating方法很庞大了.所以 ...
- springboot学习-jdbc操作数据库--yml注意事项--controller接受参数以及参数校验--异常统一管理以及aop的使用---整合mybatis---swagger2构建api文档---jpa访问数据库及page进行分页---整合redis---定时任务
springboot学习-jdbc操作数据库--yml注意事项--controller接受参数以及参数校验-- 异常统一管理以及aop的使用---整合mybatis---swagger2构建api文档 ...
- Android开发之使用sqlite3工具操作数据库的两种方式
使用 sqlite3 工具操作数据库的两种方式 请尊重他人的劳动成果,转载请注明出处:Android开发之使用sqlite3工具操作数据库的两种方式 http://blog.csdn.net/feng ...
- Servlet访问路径的两种方式、Servlet生命周期特点、计算服务启动后的访问次数、Get请求、Post请求
Servlet访问路径的两种方式: 1:注解 即在Servlet里写一个@WebServlet @WebServlet("/myServlet") 2:配置web.xml < ...
随机推荐
- Golang中的匿名函数(闭包)
GO语言的匿名函数就是闭包,以下是<GO语言编程>中对闭包的解释 基本概念闭包是可以包含自由(未绑定到特定对象)变量的代码块,这些变量不在这个代码块内或者任何全局上下文中定义,而是在定义代 ...
- Balancing Act POJ - 1655 (树的重心)
Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the t ...
- 【未知来源】K-th String
题意 求有多少种 前 \(n\) 个小写字母的排列 \(t\),满足其所有子串按字典序从小到大排列,第 \(k\) 个子串是一个给定字符串 \(s\).答案模 \(10^9+7\). \(1\le n ...
- 牛客国庆集训派对Day5 A.璀璨光滑
首先我们可以确认 1的值一定是0 题目要求的是 有边的两个点所代表的值二进制有一位不同(即有边相连的两个值二进制所包含的1的个数相差为1) 所以我们通过他给你的图进行BFS 把原图分为一圈一圈的 并且 ...
- JAVA GUI设
1.两种设置大小的方式: //Border border1=BorderFactory.createEmptyBorder(20,20,20,20); //设置大小 panel.setB ...
- C# 扩展方法——mysql-dapper(MySqlMapperExtensions)
其他扩展方法详见:https://www.cnblogs.com/zhuanjiao/p/12060937.html 反射比较耗费性能,反射得到属性进行缓存 根据反射得到的属性,进行动态拼接sql语句 ...
- C#抽象类怎么调试
本文出自:https://www.cnblogs.com/2186009311CFF/p/11919030.html C#抽象类怎么调试 按F11调试 参考链接: 快捷键:https://www.cn ...
- Linux不同机器文件挂载
由于此前发布项目应用时,需要对两台文件服务器进行文件挂载,所以才实际第一次接触到这个名词,但由于一直以来自己没有真正的去操作过,只是停留在一些理论层次,所以今天记录一下这个实现过程,以备后用. 使用设 ...
- JAVA记录 Spring 两大特性
1.IOC控制反转 Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象 ...
- cursor(鼠标手型)属性
㈠简单介绍 在浏览网页时,通常看到的鼠标光标形状有箭头.手形.沙漏等,而在 windows 中实际看到的鼠标指针种类比这个还要多. 一般情况下,鼠标光标的形状由浏览器负责控制,大多数情况的光标形状为箭 ...