JpaRepository 实现简单条件查询

网友投稿 882 2022-11-19

JpaRepository 实现简单条件查询

JpaRepository 实现简单条件查询

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

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) http://{

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 findByUserName(String userName);

List findByUserNameAndAge(String userName,Integer age);

List 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 users) {

userRepository.saveAll(users);

}

public User getUserByUserName(String userName) {

return userRepository.findByUserName(userName);

}

public List getUserByUserNameAndAge(String userName,Integer age){

return userRepository.findByUserNameAndAge(userName, age);

}

public List 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 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 getByUserNameAndAge(String userName,Integer age){

return userService.getUserByUserNameAndAge(userName, age);

}

@RequestMapping("/userNameLike")

public List 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

http://

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.特殊的参数

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

PagefindByName(String name, Pageable pageable);

ListfindByName(String name, Sort sort);

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

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

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

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

publicList findByAge(int age);

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

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

只要设置nativeQuery为true,比如:

@Query(value="select* from tbl_user where name like %?1" ,nativeQuery=true)

publicList findByUuidOrAge(String name);

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

f.使用命名化参数

使用@Param即可,比如:

@Query(value="selecto from UserModel o where o.name like %:nn")

publicList 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:在调用的地方必须加事务,没有事务不能正常执行

h.创建查询的顺序

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

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

它有如下三个取值:

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

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

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:同步直播(4):空间统计中的注意事项
下一篇:未能找到元数据文件**.dll解决办法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~