jpa简单的命名规则如下,这个不多做介绍,放在这里也是给自己以后查找起来方便,这篇文章主要介绍之前一直忽略了的几个点,像@NoRepositoryBean
这个注解,以及怎么自定义Repository的实现。
关键字 | 方法命名 | sql where字句 |
---|---|---|
And | findByNameAndPwd | where name= ? and pwd =? |
Or | findByNameOrSex | where name= ? or sex=? |
Is,Equals | findById,findByIdEquals | where id= ? |
Between | findByIdBetween | where id between ? and ? |
LessThan | findByIdLessThan | where id < ? |
LessThanEquals | findByIdLessThanEquals | where id <= ? |
GreaterThan | findByIdGreaterThan | where id > ? |
GreaterThanEquals | findByIdGreaterThanEquals | where id > = ? |
After | findByIdAfter | where id > ? |
Before | findByIdBefore | where id < ? |
IsNull | findByNameIsNull | where name is null |
isNotNull,NotNull | findByNameNotNull | where name is not null |
Like | findByNameLike | where name like ? |
NotLike | findByNameNotLike | where name not like ? |
StartingWith | findByNameStartingWith | where name like ‘?%’ |
EndingWith | findByNameEndingWith | where name like ‘%?’ |
Containing | findByNameContaining | where name like ‘%?%’ |
OrderBy | findByIdOrderByXDesc | where id=? order by x desc |
Not | findByNameNot | where name <> ? |
In | findByIdIn(Collection<?> c) | where id in (?) |
NotIn | findByIdNotIn(Collection<?> c) | where id not in (?) |
True | findByAaaTrue | where aaa = true |
False | findByAaaFalse | where aaa = false |
IgnoreCase | findByNameIgnoreCase | where UPPER(name)=UPPER(?) |
@NoRepositoryBean
我们查看JpaRepository
这个类的继承关系可以看到下面这张图
而在JpaRepository
,PagingAndSortingRepository
,QueryByExampleExecutor
,这三个接口上我们都能发现这个注解@NoRepositoryBean
,这个注解到底有上面用呢?
我们来看下官网的解释:
上面这段话大致的意思是:只要在相应的Repository接口上添加了这个注解,Spring就不会在运行时为这个接口创建对应的实例。
看到这里估计有的同学更加迷惑了,这又是什么意思呢?我们来看下面这段代码:
我定义了一个Repository接口
public interface UserRepository extends JpaRepository<User, Integer> {
/**
* 根据id查询
*
* @param part
* @return
*/
List<User> findFirstByUseEmailLike(String part);
}
启动类如下:
package com.study.spring.springdatajpa;
import com.study.spring.springdatajpa.config.CustomRepositoryFactoryBean;
import com.study.spring.springdatajpa.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@SpringBootApplication
@EnableJpaRepositories(basePackages = {"com.study.spring.springdatajpa.repository"})
public class SpringDataJpaApplication implements ApplicationRunner {
@Autowired
UserRepository userRepository;
public static void main(String[] args) {
SpringApplication.run(SpringDataJpaApplication.class, args);
}
@Override
public void run(ApplicationArguments args) throws Exception {
userRepository.findFirstByUseEmailLike("*.com")
}
}
断点调试如下:
可以看到,虽然我们定义了一个userRepository接口,但是Spring为我们生成了一个代理对象,并且这个代理对象代理是org.springframework.data.jpa.repository.support.SimpleJpaRepository
这个类。
我们看下SimpleJpaRepository
这个类的继承关系:
可以发现,SimpleJpaRepository实现了JpaRepository这个接口。
其实在程序初始化的时候,SpringBoot会通过这个注解@EnableJpaRepositories(basePackages = {"com.study.spring.springdatajpa.repository"})
将我们配置的包下的所有继承0了JpaRepository这个接口的接口,注册到spring容器中,然后以SimpleJpaRepository为目标对象创建代理对象。
我们知道对应的接口有3个,为什么它们没被创建代理对象呢?这样就要说到我们提到的注解@NoRepositoryBean
了,JpaRepository
,PagingAndSortingRepository
,QueryByExampleExecutor
这个3个接口都被这个注解标注了,所以不会被创建代理对象,这也是这个注解的作用
利用@NoRepositoryBean
来自定义一个Repository的实现
我们要达到的目的就是,定义一个Repository接口(仿JpaRepository),只要有别的接口继承了这个类,就自动拥有这个接口对应的实现类(仿SimpleJpaRepository)中的方法。
代码如下:
-
定义接口:
package com.wisely.support;
import java.io.Serializable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean; @NoRepositoryBean //指明当前这个接口不是领域类的接口
//我们自定义的CustomRepository继承了JpaRepository接口,具备JPA的能力
public interface CustomRepository<T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {
//要定义的数据操作方法在接口中定义
void doWithId(ID id);
} -
定义接口实现类
//要实现 CustomRepository接口,继承SimpleJpaRepository类让我们可以使用其提供的方法(如findAll)
public class CustomRepositoryImpl<T, ID extends Serializable>
extends SimpleJpaRepository<T, ID> implements CustomRepository<T, ID> { //数据操作方法会用到entityManager,我们这里没有用到
private final EntityManager entityManager; //CustomRepositoryImpl的构造函数,
// 需当前处理的领域类和entityManager作为构造参数,在这里也给entityManager赋值了
public CustomRepositoryImpl(Class<T> domainClass, EntityManager entityManager) {
super(domainClass, entityManager);
this.entityManager = entityManager;
} @Override
public void doWithId(ID id) {
//定义数据访问操作,如调用findAll方法并构造一些查询条件
System.out.println("拿到id干点事儿");
} } -
自定义一个RepositoryFactoryBean
//自定义CustomRepositoryFactoryBean,继承JpaRepositoryFactoryBean
public class CustomRepositoryFactoryBean<T extends JpaRepository<S, ID>, S, ID extends Serializable>
extends JpaRepositoryFactoryBean<T, S, ID> { public CustomRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
super(repositoryInterface);
} @Override
//重写createRepositoryFactory方法,用当前的CustomRepositoryFactory创建实例
protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
return new CustomRepositoryFactory(entityManager); //该类见下面的定义
} //定义一个私有的静态类,并继承JpaRepositoryFactory
//复写其中两个核心方法
private static class CustomRepositoryFactory extends JpaRepositoryFactory { //构造函数
public CustomRepositoryFactory(EntityManager entityManager) {
super(entityManager);
} @Override
protected JpaRepositoryImplementation<?, ?> getTargetRepository(RepositoryInformation information, EntityManager entityManager) {
return new CustomRepositoryImpl<>(information.getDomainType(), entityManager);
} @Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {// 获得当前自定义类的类型
return CustomRepositoryImpl.class;
}
}
} -
启动类代码,注意上面的注解
@SpringBootApplication
//@EnableJpaRepositories(basePackages = //{"com.study.spring.springdatajpa.repository"})
@EnableJpaRepositories(repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class)
public class SpringDataJpaApplication implements ApplicationRunner { @Autowired
UserRepository userRepository; public static void main(String[] args) {
SpringApplication.run(SpringDataJpaApplication.class, args);
} @Override
public void run(ApplicationArguments args) throws Exception {
userRepository.doWithId(11);
}
}
运行程序打印结果如下:
拿到id干点事儿
Spring学习笔记(八)Spring Data JPA学习的更多相关文章
-
Spring实战第五章学习笔记————构建Spring Web应用程序
Spring实战第五章学习笔记----构建Spring Web应用程序 Spring MVC基于模型-视图-控制器(Model-View-Controller)模式实现,它能够构建像Spring框架那 ...
-
Spring实战第八章学习笔记————使用Spring Web Flow
Spring实战第八章学习笔记----使用Spring Web Flow Spring Web Flow是一个Web框架,它适用于元素按规定流程运行的程序. 其实我们可以使用任何WEB框架写流程化的应 ...
-
Java架构师之路 Spring学习笔记(一) Spring介绍
前言 这是一篇原创的Spring学习笔记.主要记录我学习Spring4.0的过程.本人有四年的Java Web开发经验,最近在面试中遇到面试官总会问一些简单但我不会的Java问题,让我觉得有必要重新审 ...
-
go微服务框架kratos学习笔记八 (kratos的依赖注入)
目录 go微服务框架kratos学习笔记八(kratos的依赖注入) 什么是依赖注入 google wire kratos中的wire Providers injector(注入器) Binding ...
-
【opencv学习笔记八】创建TrackBar轨迹条
createTrackbar这个函数我们以后会经常用到,它创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上,使用起来很方便.首先大家要记住,它往往会和一个回调函数配合起来使用.先看下他的函数 ...
-
Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...
-
python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑
python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件?当我们点开下载页时, 一般 ...
-
Go语言学习笔记八: 数组
Go语言学习笔记八: 数组 数组地球人都知道.所以只说说Go语言的特殊(奇葩)写法. 我一直在想一个人参与了两种语言的设计,但是最后两种语言的语法差异这么大.这是自己否定自己么,为什么不与之前统一一下 ...
-
Redis学习笔记八:集群模式
作者:Grey 原文地址:Redis学习笔记八:集群模式 前面提到的Redis学习笔记七:主从复制和哨兵只能解决Redis的单点压力大和单点故障问题,接下来要讲的Redis Cluster模式,主要是 ...
-
Java IO学习笔记八:Netty入门
作者:Grey 原文地址:Java IO学习笔记八:Netty入门 多路复用多线程方式还是有点麻烦,Netty帮我们做了封装,大大简化了编码的复杂度,接下来熟悉一下netty的基本使用. Netty+ ...
随机推荐
-
艺萌TCP文件传输及自动更新系统介绍(TCP文件传输)(四)
艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输) 该系统基于开源的networkComms通讯框架,此通讯框架以前是收费的,目前已经免费并开源,作者是英国的,开发时间5年多,框架很稳定. 项 ...
-
Nodejs简单介绍以及在windows环境下安装与配置流程
简介 一. Nodejs是什么? Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效. ...
-
新手容易混乱的String+和StringBuffer,以及Java的方法参数传递方式。
之前在交流群里和猿友们讨论string+和stringbuffer哪个速度快以及Java的方法参数传递的问题,引起了群里猿友的小讨论.最终LZ得出的结果是string+没有stringbuffer快, ...
-
使用PHP绘制统计图
使用PHP画统计图的方法 第一种方法 <?php //最后一次修改:2004-6-21 //一个生成矩形图,曲线图的图形分析类 //作者:tonera //说明: //任何人可在任何场合*使用 ...
-
部署 外网 ASP.NET程序时, IIS安全性 配置 -摘自网络
最近,和朋友们在聊及ASP.NET程序的安全性没有JAVA高,IIS(Internet Infomartion Server)的存在很多漏洞(以及新型蠕虫,例如Code Red 和Nimda),安全得 ...
-
【JAVA - SSM】之MyBatis动态SQL
动态SQL就是在SQL语句中添加一些标签,以完成某些逻辑.通常用到的动态SQL标签有<if>.<choose>.<where>.<trim>.<s ...
-
floyd+动态规划 hdu-4571-Travel in time
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4571 题目大意: 有n个景点,每个点都有个游玩时间ci,游玩后得到的满意度si.给一个起点s和终点e ...
-
Oracle EBS-SQL (BOM-17):检查8层BOM.sql
define item1="1234567890" select a1.产品编码, a1.产品描述, '1层' 层数, a1.物料编码, a1.物料描述, a1.单 ...
-
JVM的内存区域划分以及垃圾回收机制详解
在我们写Java代码时,大部分情况下是不用关心你New的对象是否被释放掉,或者什么时候被释放掉.因为JVM中有垃圾自动回收机制.在之前的博客中我们聊过Objective-C中的MRC(手动引用计数)以 ...
-
debug和release下PostThreadMessage的异同
MFC中创建线程分为工作线程和UI线程.其中UI线程可以通过继承CWinThread进行创建. 创建函数如下: CWinThread *m_pRecogThread;//语音识别线程 m_pRecog ...