参考博客:
JPA:
https://www.jianshu.com/p/b6932740f3c0
https://shimo.im/docs/zOer2qMVEggbF33d/
Restful:
https://blog.csdn.net/chenxiaochan/article/details/73716617
https://www.cnblogs.com/wang-yaz/p/9237981.html
(二期)10、spring data jpa综合运用
javax.persistence.Entity
javax.persistence.EntityManager
javax.transaction.Transactional
javax.persistence.criteria.CriteriaQuery
#JPQL
select o from Order o 或 select o from Order as o
JPA是一套ORM规范,hibernate实现了JPA规范
hibernate中有自己的独立ORM操作数据库方式,也有JPA规范实现的操作数据库方式。
在数据库增删改查操作中,我们hibernate和JPA的操作都要会。
- 索引参数
@Modifying
@Query("update User u set u.firstname = ?1 where u.lastname = ?2")
int setFixedFirstnameFor(String firstname, String lastname);
- 命名参数
public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
User findByLastnameOrFirstname(@Param("lastname") String lastname,
@Param("firstname") String firstname);
}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
spring:
http:
encoding:
charset: UTF-8
force: true
enabled: true
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost/jpademo?useSSL=false&characterEncoding=utf8
username: root
password: admin
jpa:
database: mysql
show-sql: true
hibernate:
ddl-auto: update
静态代理
package common;
public class Test {
static interface Subject{
void sayHi();
void sayHello();
}
static class SubjectImpl implements Subject{
@Override
public void sayHi() {
System.out.println("hi");
}
@Override
public void sayHello() {
System.out.println("hello");
}
}
static class SubjectImplProxy implements Subject{
private Subject target;
public SubjectImplProxy(Subject target) {
this.target=target;
}
@Override
public void sayHi() {
System.out.print("say:");
target.sayHi();
}
@Override
public void sayHello() {
System.out.print("say:");
target.sayHello();
}
}
public static void main(String[] args) {
Subject subject=new SubjectImpl();
Subject subjectProxy=new SubjectImplProxy(subject);
subjectProxy.sayHi();
subjectProxy.sayHello();
}
}
package common;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Test {
static interface Subject{
void sayHi();
void sayHello();
}
static class SubjectImpl implements Subject{
@Override
public void sayHi() {
System.out.println("hi");
}
@Override
public void sayHello() {
System.out.println("hello");
}
}
static class ProxyInvocationHandler implements InvocationHandler{
private Subject target;
public ProxyInvocationHandler(Subject target) {
this.target=target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.print("say:");
return method.invoke(target, args);
}
}
public static void main(String[] args) {
Subject subject=new SubjectImpl();
Subject subjectProxy=(Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), new ProxyInvocationHandler(subject));
subjectProxy.sayHi();
subjectProxy.sayHello();
}
}
第一步、
到此,第一步完成,我们知道了Spring Data JPA如何通过包扫描获得哪些类需要被代理.
第二步:
第三步:
第四步
原来JpaRepository接口只是它的外壳,其真正实现类是simplejpaReository
JdkDynamicAopProxy
AnnotationRepositoryConfigurationSource
RepositoryConfigurationSourceSupport
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
//获得基于注解的配置信息,如注解信息,要扫描的包,要扫描的注解等
AnnotationRepositoryConfigurationSource configurationSource = new AnnotationRepositoryConfigurationSource(annotationMetadata, getAnnotation(), resourceLoader, environment);
//这个类用来做一些准备工作,不是本文的重点
RepositoryConfigurationExtension extension = getExtension();
//实例化一个委托对象,用来完成整体的注册逻辑.
RepositoryConfigurationDelegate delegate = new RepositoryConfigurationDelegate(configurationSource, resourceLoader,environment);
//重点,调用委托对象,完成实际的注册逻辑,也就是上边的第一步和第二步
delegate.registerRepositoriesIn(registry, extension);
}
//省略了一些代码
public List<BeanComponentDefinition> registerRepositoriesIn(BeanDefinitionRegistry registry,
RepositoryConfigurationExtension extension) {
//调用extension准备JPA的上下文
extension.registerBeansForRoot(registry, configurationSource);
//生成Repository的BeanDefinitionBuilder的工具类
RepositoryBeanDefinitionBuilder builder = new RepositoryBeanDefinitionBuilder(registry, extension, resourceLoader,
environment);
//extension.getRepositoryConfigurations方法完成刚刚说的第一步,包扫描,读取配置.找出有哪些类需要Spring Data JPA生成代理
for (RepositoryConfiguration<? extends RepositoryConfigurationSource> configuration : extension
.getRepositoryConfigurations(configurationSource, resourceLoader, inMultiStoreMode)) {
//接下来开始第二步,一个一个地生成RepositoryFactoryBean的Definition
//由配置信息,主要是接口名称,生成基础的DefinitionBuilder
BeanDefinitionBuilder definitionBuilder = builder.build(configuration);
//配置EntityManager
extension.postProcess(definitionBuilder, configurationSource);
//获得FactoryBean的Definition
AbstractBeanDefinition beanDefinition = definitionBuilder.getBeanDefinition();
String beanName = beanNameGenerator.generateBeanName(beanDefinition, registry);
//注册FactoryBean的Definition
registry.registerBeanDefinition(beanName, beanDefinition);
}
}