JpaRepository 实现简单条件查询

目录
  • JpaRepository 简单条件查询
    • 创建持久化类
    • 定义数据访问层接口
    • 定义业务层类
    • 定义控制器类
    • 测试应用
  • JpaRepository 查询规范
    • 1.JpaRepository支持接口规范方法名查询
    • 2.JpaRepository相关查询功能
      • a.Spring DataJPA框架在进行方法名解析时
      • b.假如创建如下的查询
      • c.特殊的参数
      • d.也可以使用JPA的NamedQueries,方法如下
      • e.还可以使用@Query来指定本地查询
      • f.创建查询的顺序

JpaRepository 简单条件查询

JpaRepository继承自PagingAndSortingRepository接口,JpaRepository基于JPA的Repository接口,极大减少了JPA作为数据访问的代码,JpaRepository是实现Spring Data JPA技术访问数据库的关键接口。

示例:简单条件查询

创建持久化类

程序清单:/jpa/src/main/java/com/dwx/bean/User.java

package com.dwx.bean;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="t_user")
public class User {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer userId;
	private String userName;
	private String sex;
	private Integer age;
	public User() {}
	public User(String userName,String sex,Integer age) {
		this.userName=userName;
		this.sex=sex;
		this.age=age;
	}
	public Integer getUserId() {
		return userId;
	}
	public void setUserId(Integer userId) {
		this.userId = userId;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
}

定义数据访问层接口

程序清单:/jpa/src/main/java/com/dwx/repository/UserRepository.java

package com.dwx.repository;
import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import com.dwx.bean.User;
public interface UserRepository extends JpaRepository<User, Integer> {
	User findByUserName(String userName);
	List<User> findByUserNameAndAge(String userName,Integer age);
	List<User> findByUserNameLike(String userName);
}

定义业务层类

程序清单:/jpa/src/main/java/com/dwx/service/UserService.java

package com.dwx.service;
import java.util.List;
import javax.annotation.Resource;
import javax.transaction.Transactional;
import org.springframework.stereotype.Service;
import com.dwx.bean.User;
import com.dwx.repository.UserRepository;
@Service
public class UserService {
	@Resource
	private UserRepository userRepository;

	@Transactional
	public void saveAll(List<User> users) {
		userRepository.saveAll(users);
	}

	public User getUserByUserName(String userName) {
		return userRepository.findByUserName(userName);
	}

	public List<User> getUserByUserNameAndAge(String userName,Integer age){
		return userRepository.findByUserNameAndAge(userName, age);
	}

	public List<User> getUserByUserNameLike(String userName){
		return userRepository.findByUserNameLike(userName);
	}
}

定义控制器类

程序清单:/jpa/src/main/java/com/dwx/controller/UserController.java

package com.dwx.controller;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.dwx.bean.User;
import com.dwx.service.UserService;
@RestController
@RequestMapping("/user")
public class UserController {
	@Resource
	private UserService userService;

	@RequestMapping("/save")
	public String save() {
		User user1=new User("john","男",25);
		User user2=new User("lucy","女",18);
		User user3=new User("Tom","男",16);
		List<User> users=new ArrayList<>();
		users.add(user1);
		users.add(user2);
		users.add(user3);
		userService.saveAll(users);
		return "保存成功";
	}

	@RequestMapping("/userName")
	public User getByUserName(String userName){
		return userService.getUserByUserName(userName);
	}

	@RequestMapping("/userNameAndAge")
	public List<User> getByUserNameAndAge(String userName,Integer age){
		return userService.getUserByUserNameAndAge(userName, age);
	}

	@RequestMapping("/userNameLike")
	public List<User> getByUserNameLike(String userName){
		return userService.getUserByUserNameLike(userName);
	}
}

测试应用

添加用户信息,在浏览器中输入以下地址:http://localhost:8080/user/save

根据姓名和年龄查询,在浏览器中输入以下地址:http://localhost:8080/user/userNameAndAge?userName=john&age=25

根据姓名模糊查询,在浏览器中输入以下地址:http://localhost:8080/user/userNameLike?userName=jack

JpaRepository 查询规范

1.JpaRepository支持接口规范方法名查询

意思是如果在接口中定义的查询方法符合它的命名规则,就可以不用写实现,目前支持的关键字如下。


Keyword


Sample


JPQL snippet


IsNotNull


findByAgeNotNull


... where x.age not null


Like


findByNameLike


... where x.name like ?1


NotLike


findByNameNotLike


... where x.name not like ?1


StartingWith


findByNameStartingWith


... where x.name like ?1(parameter bound with appended %)


EndingWith


findByNameEndingWith


... where x.name like ?1(parameter bound with prepended %)


Containing


findByNameContaining


... where x.name like ?1(parameter bound wrapped in %)


OrderBy


findByAgeOrderByName


... where x.age = ?1 order by x.name desc


Not


findByNameNot


... where x.name <> ?1


In


findByAgeIn


... where x.age in ?1


NotIn


findByAgeNotIn


... where x.age not in ?1


True


findByActiveTrue


... where x.avtive = true


Flase


findByActiveFalse


... where x.active = false


And


findByNameAndAge


... where x.name = ?1 and x.age = ?2


Or


findByNameOrAge


... where x.name = ?1 or x.age = ?2


Between


findBtAgeBetween


... where x.age between ?1 and ?2


LessThan


findByAgeLessThan


... where x.age < ?1


GreaterThan


findByAgeGreaterThan


... where x.age > ?1


After/Before


...


...


IsNull


findByAgeIsNull


... where x.age is null

2.JpaRepository相关查询功能

a.Spring DataJPA框架在进行方法名解析时

会先把方法名多余的前缀截取掉,比如find、findBy、read、readBy、get、getBy,然后对剩下部分进行解析。

b.假如创建如下的查询

findByUserDepUuid(),框架在解析该方法时,首先剔除findBy,然后对剩下的属性进行解析,假设查询实体为Doc。

1:先判断userDepUuid (根据POJO规范,首字母变为小写)是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,继续第二步;

2:从右往左截取第一个大写字母开头的字符串此处为Uuid),然后检查剩下的字符串是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设user为查询实体的一个属性;

3:接着处理剩下部分(DepUuid),先判断user所对应的类型是否有depUuid属性,如果有,则表示该方法最终是根据“Doc.user.depUuid” 的取值进行查询;否则继续按照步骤2的规则从右往左截取,最终表示根据“Doc.user.dep.uuid” 的值进行查询。

4:可能会存在一种特殊情况,比如Doc包含一个user的属性,也有一个userDep 属性,此时会存在混淆。可以明确在属性之间加上"_"以显式表达意图,比如"findByUser_DepUuid()"或者"findByUserDep_uuid()"

c.特殊的参数

还可以直接在方法的参数上加入分页或排序的参数,比如:

Page<UserModel>findByName(String name, Pageable pageable);
List<UserModel>findByName(String name, Sort sort);

d.也可以使用JPA的NamedQueries,方法如下

1:在实体类上使用@NamedQuery,示例如下:

@NamedQuery(name ="UserModel.findByAge",query = "select o from UserModel o where o.age >=?1")

2:在自己实现的DAO的Repository接口里面定义一个同名的方法,示例如下:

publicList<UserModel> findByAge(int age);

3:然后就可以使用了,Spring会先找是否有同名的NamedQuery,如果有,那么就不会按照接口定义的方法来解析。

e.还可以使用@Query来指定本地查询

只要设置nativeQuery为true,比如:

@Query(value="select* from tbl_user where name like %?1" ,nativeQuery=true)
publicList<UserModel> findByUuidOrAge(String name);

注意:当前版本的本地查询不支持翻页和动态的排序

f.使用命名化参数,使用@Param即可,比如:

@Query(value="selecto from UserModel o where o.name like %:nn")
publicList<UserModel> findByUuidOrAge(@Param("nn") String name);

g.同样支持更新类的Query语句,添加@Modifying即可,比如:

@Modifying
@Query(value="updateUserModel o set o.name=:newName where o.name like %:nn")
public intfindByUuidOrAge(@Param("nn") String name,@Param("newName")String
newName);

注意:

1:方法的返回值应该是int,表示更新语句所影响的行数

2:在调用的地方必须加事务,没有事务不能正常执行

f.创建查询的顺序

Spring Data JPA在为接口创建代理对象时,如果发现同时存在多种上述情况可用,它该优先采用哪种策略呢?

<jpa:repositories>提供了query-lookup-strategy 属性,用以指定查找的顺序。

它有如下三个取值:

1:create-if-not-found:如果方法通过@Query指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则通过解析方法名字来创建查询。这是querylookup-strategy 属性的默认值

2:create:通过解析方法名字来创建查询。即使有符合的命名查询,或者方法通过@Query指定的查询语句,都将会被忽略

3:use-declared-query:如果方法通过@Query指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则抛出异常

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot JPA实现查询多值

    JPA是java Persistence API简称,中文名:java持久层API,JPA是JCP组织发布的J2EE标准之一 1.创建DataSource连接池对象 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- 数据库驱动 -

  • 详解Spring Data Jpa 模糊查询的正确用法

    模糊查询 Spring Data Jpa的使用可以减少开发者对sql语句的编写,甚至完全不需要编写sql语句.但是,开发过程中总会遇到各种复杂的场景以及大大小小的坑. 今天项目中某个功能模块需要用到模糊查询.原生sql中模糊查询关键字'Like',而Spring Data Jpa的Repository接口中恰恰也有实体字段对应的Like.但是,如果直接使用它,那么恭喜你,你幸运地掉坑了. Spring Data Jpa 模糊查询正确用法 首先,我们先创建一个实体用来存储我们的数据 /** * 实

  • Spring Boot JPA Repository之existsBy查询方法失效的解决

    引言: Spring Boot号称微服务的利器,在结合了Spring Data与JPA之后,更是如虎添翼,开发快速的不像话,本文将讲述一个关于JPA中一个诡异问题的诊断分析过程以及修复方法. 环境介绍 JDK 1.8 Spring 4.2 Spring Boot 1.5.9 问题描述 在Spring Data中的Repository接口中创建了一个检查数据是否存在的接口方法: @Repository public interface VideoEntityRepository extends J

  • JpaRepository 实现简单条件查询

    目录 JpaRepository 简单条件查询 创建持久化类 定义数据访问层接口 定义业务层类 定义控制器类 测试应用 JpaRepository 查询规范 1.JpaRepository支持接口规范方法名查询 2.JpaRepository相关查询功能 a.Spring DataJPA框架在进行方法名解析时 b.假如创建如下的查询 c.特殊的参数 d.也可以使用JPA的NamedQueries,方法如下 e.还可以使用@Query来指定本地查询 f.创建查询的顺序 JpaRepository

  • 一个简单实现多条件查询的例子

    在我们的网站设计过程中,经常会用到多条件查询,本文的源码是一个二手房屋查询的例子.在本例中,我们要实现能够通过地理位置,物业类型,房屋价格,房屋面积及信息发布日期等多个条件查询到客户所需的资料.以下是实现过程. 查询条件界面(略): 查询文件(search.php) 一.生成查询语句: <? $conn=mysql_connect("localhost","root",""); $db=mysql_select_db("lingy

  • sql条件查询语句的简单实例

    复制代码 代码如下: //创建成绩表 create table result(        stu_id varchar2(20) not null,        china number(9,2) null,        math number(9,2) null,        english number(9,2) null); //插入数据 insert into result values('0001',60,20,80); insert into result values('

  • 使用准则进行条件查询--1.4.从窗体中选择查询的条件

    4.从窗体中选择查询的条件 前面的方法虽然简单,但对用户来说操作不够方便,对设计者来说也难以控制,如果通过窗体来实现,这些问题就可以解决了. 如下面的窗体,运行时用户可以在组合框中选择要查询司机的姓名,按下查询按钮就可以看到查询的结果. 下面详细地列出设计的步骤: 创建一个窗体,按下控件向导按钮,在窗体上添加一个组合框.在第一个对话框中选择"我想让组合框在一个表或查询中查找这些值",下一步. 选择一个为组合框提供数据的表或查询.下一步. 选择组合框中要显示的数据,通常除了选择要显示在组

  • 用扩展方法优化多条件查询(不定条件查询)

    在我们开发过程中,特别是管理系统的开发,经常会遇到多条件查询(或者叫不定条件查询)的案例,就是提供给User输入的查询条件有多个不同的查询栏位,而且,在实际使用中并不能确定User会使用哪些条件来当做搜索条件. 下图就是我们实际项目中一个查询页面的截图,  User在实际操作中,有可能会只根据[扣帐编号]查询,那么,只要在[扣帐编号]栏位输入号码,其他栏位留空即可,那么查询语句就只卡[扣帐编号]这条条件也有可能直接根据日前范围查询,只要输入起始日期即可.当然,在实际开发的时候我们是不能预判Use

  • PHP组合查询多条件查询实例代码第1/2页

    先向大家说明需求:按照我们系统的要求,我们将通过部门名称.员工姓名.PC名称.IP地址等等字段来进行组合查询从而得到想要的数据结果.那么,为了简单起见,我们用两个条件(部门名称.员工姓名)的组合查询来向大家说明这一技术技巧.当我们只输入部门名而员工姓名为空值时,那么部门内所有员工信息将被呈现,只有当你同时限制部门与员工姓名时,才能查询出唯一信息. 那就让我们开始. 首先建立查询页面search.php,不同于上次单一条件查询,这次我们需要两个条件的组合进行查询. <html> <body

  • 解决Django中多条件查询的问题

    tags: django中对条件查询 一些cms项目都会使用到多条件查询,我们后端如何处理请求的条件呢? 满足一个条件 满足两个条件 满足多个条件 -------. 这样处理起来会非常的恼火. 其实有多方法比如(传参数,传字典,传Q对象,传F对象-)陷入深深的思考中-怎么用做简单的方法把这个需求解决了. 个人觉得.把我们的查询的所有条件来构建一个字典来查询起来比较高效.具体如何操作见下面的代码: 视图函数. def order_list(request): if request.method =

  • 利用MyBatis实现条件查询的方法汇总

    SQL映射文件 Mybatis真正强大的是在于它的SQL映射语句,也是它的流弊之处. 它的功能强大,SQL映射文件的配置却比较简单. 使用SQL映射文件可以减少50%以上的代码量. Mybatis专注于SQL,对于开发人员来说可极大限度地进行SQL调优,以保证性能,下面是SQL映射文件的几个顶级元素配置 1.mapper 它是映射文件的根节点,只有一个属性就是 namespace(命名空间)它的作用是区分不同的mapper,里面的参数是全局唯一的,绑定DAO层接口,即面向接口编程 namespa

  • SQL Server2019数据库之简单子查询的具有方法

    子查询可以完成 SQL 查询中比较复杂的情况,本章主要介绍一些子查询的简单用法. 一.简单子查询 1.简单子查询 子查询是 SELECT 语句内的另外一条 SELECT 语句.通常,语句内可以出现表达式的地方都可以使用子查询.另外,子查询可以从任何表中提取数据,只要对该表有适当的访问权限即可.因此,通过在一个查询内或者在另一个子查询内嵌套子查询,可以从两个或多个表中组合信息而不必编写复杂的整个组合表,然后再过滤掉多余的或不相关的联合行的JOIN语句. 子查询的语法与普通的 SELECT 查询的语

  • Mybatis Criteria使用and和or进行联合条件查询的操作方法

    之前用Mybatis框架反向的实体,还有实体里面的Example,之前只是知道Example里面放的是条件查询的方法,可以一直不知道怎么用,到今天才开始知道怎么简单的用.在我们前台查询的时候会有许多的条件传过来:先看个例子: public List<Contact> searchByExample(Contact contact) { System.out.println("searchByExampleContact"); ContactExample example =

随机推荐