【SpringBoot系列】动态代理为接口增加实现,一文搞定Spring data 原理,你也可以这样玩!

🤵‍♂️ 个人主页:@香菜的个人主页,加 ischongxin ,备注csdn

✍🏻作者简介:csdn 认证博客专家,游戏开发领域优质创作者,华为云享专家,2021年度华为云年度十佳博主

🐋 希望大家多多支持,我们一起进步!😄

如果文章对你有帮助的话,

欢迎评论 💬点赞👍🏻 收藏 📂加关注+

系列文章:Spring Boot学习大纲,可以留言自己想了解的技术点

目录

1、jpa的使用

[2、spring data 的特点](#2、spring data 的特点)

3、jpa的简单使用

[3.1 jpa简单使用](#3.1 jpa简单使用)

4、简单实现-原理

[4.1 自己实现一个repo](#4.1 自己实现一个repo)

[4.2 实现代理接口](#4.2 实现代理接口)

[4.3 测试](#4.3 测试)

[4.4 看下结果](#4.4 看下结果)

总结


好久不写,也是真写不下去,不知道为啥,总是开始想写,一会就失去了动力。

今天无论如何整一篇吧,总结下JPA的原理,也为以后做同样的设计做个初稿。

1、jpa的使用

CSDN之前写了两篇Spring data JPA 的使用,可以参考下怎么用的,好用且简单,传送门

https://blog.csdn.net/perfect2011/article/details/130803614

https://blog.csdn.net/perfect2011/article/details/131049080

2、spring data 的特点

强大的存储库和自定义对象映射抽象

从存储库方法名称派生动态查询

实现域基类提供基本属性

无论是哪种持久化存储, 数据访问对象通常都会提供对单一域对象的CRUD (创建、读取、更新、删除)操作、查询方法、排序和分页方法等。Spring Data则提供了基于这些层面的统一接口(CrudRepository,PagingAndSortingRepository)以及对持久化存储的实现。

3、jpa的简单使用

为了能够简单实现JPA,也为了能说明技术特点,还是写一个简单的JPA使用,具体的实现代码可以看上面两个链接

3.1 jpa简单使用

entity定义

import jakarta.persistence.*;
import lombok.Data;

import java.io.Serializable;

@Entity
@Data
@Table(name = "t_user")
public class UserEntity implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Column(name = "username")
    private String userName;
    @Column(name = "password")
    private String password;
}

repo的定义

import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.anno.Cached;
import com.xin.jetcachetest.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface UserRepo extends JpaRepository<UserEntity, Integer>, JpaSpecificationExecutor<UserEntity> {

    UserEntity findAllByUserName(String userName);
}

项目中使用

import com.xin.jetcachetest.cache.UserRepo;
import com.xin.jetcachetest.entity.UserEntity;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @Resource
    UserRepo userRepo;
    @GetMapping("/user")
    public UserEntity getUser(){
        UserEntity allByUserName = userRepo.findAllByUserName("admin");
        return allByUserName;
    }
}

简单总结要点:

  • 1、有entity定义
  • 2、创建访问repo 实现相关的接口
  • 3、在其他地方使用

4、简单实现-原理

整个JPA的使用还是很简单的,这里的技术实现是怎么样的,主要

实现方式,在以后的工作中可以使用类似的开发技术方案,我关注的两个点

1.接口是怎么有实现的?

2.动态sql 是怎么做到的?

这两者的基础都是Java的动态代理,下面来个简单实现,万变不离其宗,我们来接管这个接口的实现。

4.1 自己实现一个repo

这里直接选择了一个CrudRepository 进行实现,同时也只实现了一个findById接口,在内容里加了一个打印

很简单,这里只是作为demo,没有真正的实现接口

4.2 实现代理接口

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class RepoProxy implements InvocationHandler {

    private Object target;
    private XinRepository xinRepository;

    public RepoProxy() {
        xinRepository = new XinRepository();
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Method method1 = xinRepository.getClass().getMethod(method.getName(), method.getParameterTypes());
        return method1.invoke(xinRepository,args);
    }
}

这里的重点是将代理方法的调用直接转接到XinRepository中调用,相当于狸猫换太子

4.3 测试

直接通过动态代理创建代理类。

import com.xin.jetcachetest.cache.UserRepo;

import java.lang.reflect.Proxy;

public class Aain {
    public static void main(String[] args) {

        UserRepo userRepo = (UserRepo) Proxy.newProxyInstance(UserRepo.class.getClassLoader(), new Class[]{UserRepo.class}, new RepoProxy());
        userRepo.findById(1);
    }
}

4.4 看下结果

总结

原理很简单,将接口生成动态代理,然后在代理中将方法转换到对应的实现中。

UserRepo 继承相关的接口

XinRepository 也要实现UserRepo 继承的接口,也就是保持接口中方法一致

RepoProxy 代理所有的接口方法,转入实现类XinRepository中

使用JDK动态代理创建代理类。

相关推荐
brrdg_sefg5 分钟前
gitlab代码推送
java
做梦敲代码9 分钟前
达梦数据库-读写分离集群部署
数据库·达梦数据库
hanbarger28 分钟前
mybatis框架——缓存,分页
java·spring·mybatis
cdut_suye35 分钟前
Linux工具使用指南:从apt管理、gcc编译到makefile构建与gdb调试
java·linux·运维·服务器·c++·人工智能·python
苹果醋31 小时前
2020重新出发,MySql基础,MySql表数据操作
java·运维·spring boot·mysql·nginx
小蜗牛慢慢爬行1 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
azhou的代码园1 小时前
基于JAVA+SpringBoot+Vue的制造装备物联及生产管理ERP系统
java·spring boot·制造
hanbarger1 小时前
nosql,Redis,minio,elasticsearch
数据库·redis·nosql
微服务 spring cloud1 小时前
配置PostgreSQL用于集成测试的步骤
数据库·postgresql·集成测试