mybatis学习笔记之使用javassist生成类

文章目录

  • 使用javassist动态生成类
  • 使用javassist动态生成类并实现接口
  • 实现接口中所有的方法
  • 工具类GenerateDaoProxy的编写

使用javassist动态生成类

    @Testpublic void testGennerateFirstClass() throws Exception{//获取类池,这个类池就是用来生成class的ClassPool pool = ClassPool.getDefault();//制造类(需要告诉javassist,类名是啥)CtClass ctClass = pool.makeClass("类名");//制造方法String methodCode = "publi coid insert(){System.out.println(123);}";CtMethod ctMethod = CtMethod.make(methodCode, ctClass);//将方法添加到类中ctClass.addMethod(ctMethod);//在内存中生成classctClass.toClass();//类加载到JVM当中,返回类的字节码Class<?> clazz = Class.forName("类名");//创建对象Object obj = clazz.newInstance();//获取类中的方法Method insertMethod = clazz.getDeclaredMethod("insert");//调用方法insertinsertMethod.invoke(obj);}

使用javassist动态生成类并实现接口

    @Testpublic void testGenerateImpl() throws Exception{//获取类池ClassPool pool = ClassPool.getDefault();//制造类CtClass ctClass = pool.makeClass("类地址")//制造接口CtClass ctInterface = pool.makeInterface("类接口地址");// 添加接口到类中ctClass.addInterface(ctInterface);//实现接口中的方法//制造方法CtMethod ctMethod = CtMethod.make("条件执行语句",ctClass);//将方法添加到类中ctClass.addMethod(ctMethod);//在内存中生成类,同时将生成的类加载到JVM当中。Class<?> clazz = ctClass.toClass();AccountDao accountDao = (AccountDao) clazz.newInstance();accountDao.delete();}

实现接口中所有的方法

public class javassistTest {@Testpublic void testGenerateAccountDaoImpl() throws Exception{//获取类池ClassPool pool = ClassPool.getDefault();//制造类CtClass ctClass = pool.makeClass("类名地址");//制造接口CtClass ctInterface = pool.makeInterface("接口地址");//实现接口ctClass.addInterface(ctInterface);//实现接口中所有的方法Method[] methods = AccountDao.class.getDeclaredMethods();Arrays.stream(methods).forEach(method -> {//method是接口中的抽象方法//把method抽象方法给实现了try{//public void delete(){}//public int update(String actno, Double balance){}StringBuilder methodCode = new StringBuilder();methodCode.append("public");//追加修饰符列表methodCode.append(method.getReturnType().getName());//追加返回值类型methodCode.append(" ");methodCode.append(method.getName());//追加方法名methodCode.append("(");//拼接参数 String actno, Double balanceClass<?>[] paramterTypes = method.getParameterTypes();for (int i = 0; i < paramterTypes.length; i++) {Class<?> parameterType = paramterTypes[i];methodCode.append(parameterType.getName());methodCode.append(" ");methodCode.append("arg" + i);if(i != paramterTypes.length - 1){methodCode.append(",");}}methodCode.append("){System.out.println(1111);return 1;}}");//动态的添加return语句String returnTypeSimpleName = method.getReturnType().getSimpleName();if ("void".equals(returnTypeSimpleName)){}else if ("int".equals(returnTypeSimpleName)){methodCode.append("return 1;");}else if("String".equals(returnTypeSimpleName)){methodCode.append("return \"hello\";");}methodCode.append("}");System.out.println(methodCode);CtMethod ctMethod = CtMethod.make(methodCode.toString(), ctClass);ctClass.addMethod(ctMethod);}catch (Exception e){e.printStackTrace();}});//在内存中生成class,并且加载到JVM当中Class<?> clazz = ctClass.toClass();//创建对象AccountDao accountDao = (AccountDao) clazz.newInstance();//调用方法//...}

工具类GenerateDaoProxy的编写

package com.example.bank.utils;import org.apache.ibatis.javassist.ClassPool;
import org.apache.ibatis.javassist.CtClass;
import org.apache.ibatis.javassist.CtMethod;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.session.SqlSession;import java.lang.reflect.Method;
import java.util.Arrays;public class GenerateDaoProxy{public static Object generate(SqlSession sqlSession, Class daoInterface){//获取类池ClassPool pool = ClassPool.getDefault();//制造类CtClass ctClass = pool.makeClass(daoInterface.getName() + "Proxy");//制造接口CtClass ctInterface = pool.makeInterface(daoInterface.getName());//实现接口ctClass.addInterface(ctInterface);//实现接口中所有的方法Method[] methods = daoInterface.getDeclaredMethods();Arrays.stream(methods).forEach(method -> {//method是抽象方法//将method这个抽象方法进行实现try{// Account selectBtActno(String actno);//public Account selectByActno(String arg0, int arg1, int arg2){代码; }StringBuilder methodCode = new StringBuilder();methodCode.append("public ");methodCode.append(method.getReturnType().getName());methodCode.append(" ");methodCode.append(method.getName());methodCode.append("(");//需要方法的形式参数列表Class<?>[] paramterTypes = method.getParameterTypes();for(int i = 0; i < paramterTypes.length; i++){Class<?> paramterType = paramterTypes[i];methodCode.append(paramterType.getName());methodCode.append(" ");methodCode.append("arg" + i);if(i != paramterTypes.length - 1){methodCode.append(",");}}methodCode.append(")");methodCode.append("{");//需要方法体当中的代码methodCode.append("org.apache.ibatis.session.SqlSession sqlSession = com.example.bank.utils.SqlSessionUtil.openSession();");//需要知道是什么类型的sql语句//sql语句的id是框架使用者提供的,具有多变性,等于我框架的开发人员来说,我不知道//既然我框架开发者不知道sqlId,怎么办呢?mybatis框架的开发者于是就出台了一个归档,凡是使用GenerateDaoProxy机制的。//sqlId都不能随便写,namespace必须是dao接口的全限定名称,id必须是dao接口中的方法名String sqlId = daoInterface.getName() + "." + method.getName();SqlCommandType sqlCommandType = sqlSession.getConfiguration().getMappedStatement(sqlId).getSqlCommandType();if(sqlCommandType == SqlCommandType.INSERT){}if(sqlCommandType == SqlCommandType.DELETE){}if(sqlCommandType == SqlCommandType.UPDATE){methodCode.append("return sqlSession.update(\""+sqlId+"\",arg0);");}if(sqlCommandType == SqlCommandType.SELECT){String returnType = method.getReturnType().getName();methodCode.append("return ("+returnType+") sqlSession.selectOne(\""+sqlId+"\",arg0);");}methodCode.append("}");CtMethod ctMethod = CtMethod.make(methodCode.toString(), ctClass);ctClass.addMethod(ctMethod);}catch(Exception e){e.printStackTrace();}});//创建对象Object obj = null;try{Class<?> clazz = ctClass.toClass();obj = clazz.newInstance();} catch (Exception e){e.printStackTrace();}return obj;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/6096.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Cloudreve搭建云盘系统,并实现随时访问

文章目录 1、前言2、本地网站搭建1.环境使用2.支持组件选择3.网页安装4.测试和使用5.问题解决 3、本地网页发布1.cpolar云端设置2.cpolar本地设置 4、公网访问测试5、结语 1、前言 自云存储概念兴起已经有段时间了&#xff0c;各互联网大厂也纷纷加入战局&#xff0c;一时间公…

C#之委托

目录 一、简介 &#xff08;一&#xff09;概述 &#xff08;二&#xff09;类与委托 二、声明委托 三、使用委托 &#xff08;一&#xff09;创建委托对象 &#xff08;二&#xff09;使用委托 四、简单的委托示例 五、Action[T]和Func[T]委托 六、多播委托 七、匿…

ONNX Runtime 加速深度学习(C++ 、python)详细介绍

ONNX Runtime 加速深度学习(C 、python)详细介绍 本文在 https://blog.csdn.net/u013250861/article/details/127829944 基础上进行了更改&#xff0c;感谢原作&#xff01; ONNXRuntime(Open Neural Network Exchange)是微软推出的一款针对ONNX模型格式的推理框架&#xff0c…

妙记多 Mojidoc PC端(Mac 端+windows端)Beta版本正式上线!

你们呼唤了无数次的妙记多 Mojidoc PC客户端 Beta版本正式上线啦&#xff01; 感谢300位妙友积极参与内测&#xff0c;给予了我们很多非常有效的意见和建议&#xff01;我们会根据用户反馈不断优化和修复相关功能&#xff0c;在此感谢妙友们一直以来的支持&#xff5e; PC端拥…

SkyWalking链路追踪中span全解

基本概念 在SkyWalking链路追踪中&#xff0c;Span&#xff08;跨度&#xff09;是Trace&#xff08;追踪&#xff09;的组成部分之一。Span代表一次调用或操作的单个组件&#xff0c;可以是一个方法调用、一个HTTP请求或者其他类型的操作。 每个Span都包含了一些关键的信息&am…

numpy 笔记 partition和

1 partition 对数组进行部分排序&#xff0c;返回的是数组本身的部分排序结果 1.1 使用方法 numpy.partition(a, kth, axis-1, kindintroselect, orderNone) 1.2 参数说明 a输入的数组kth分割点&#xff0c;前kth的元素会按照部分排序的顺序排列&#xff0c;而在kth之后的…

小程序 methods方法互相调用 this.onClickCancel is not a function

背景 做了一个自定义的弹出对话窗口&#xff0c;主要是自定义一些文本颜色。 问题 但是点击按钮事件&#xff1a;取消与确认&#xff0c;调用了同一个接口&#xff0c;然后想着走不同方法&#xff0c;需要调用methods其他方法。然后报错了&#xff1a; VM1081 WAService.js:…

行为型模式 - 状态模式

概述 【例】通过按钮来控制一个电梯的状态&#xff0c;一个电梯有开门状态&#xff0c;关门状态&#xff0c;停止状态&#xff0c;运行状态。每一种状态改变&#xff0c;都有可能要根据其他状态来更新处理。例如&#xff0c;如果电梯门现在处于运行时状态&#xff0c;就不能进…

C语言数据在内存中的存储

目录 前言 本期内容介绍 一、数据类型的介绍 1.1类型的意义&#xff1a; 1.2C语言中是否有字符串类型&#xff1f; 1.3类型的基本归类 整型家族&#xff1a; 浮点型&#xff08;实型&#xff09;家族&#xff1a; 构造&#xff08;自定义&#xff09;类型&#xff1a;…

STM32外设系列—TB6612FNG

本文涉及到定时器和串口的知识&#xff0c;详细内容可见博主STM32速成笔记专栏。 文章目录 一、TB6612简介二、TB6612使用方法2.1 TB6612引脚连接2.2 控制逻辑2.3 电机调速 三、实战项目3.1 项目简介3.2 初始化GPIO3.3 PWM初始化3.3 电机控制程序3.4 串口接收处理函数 一、TB66…

优化transformer

使用transformer而导致的时间长&#xff0c;可能会由于self-attention计算Query和key的值才导致的时间长&#xff0c;也可能会因为feed forward中的计算导致时间长。这里我们只针对第一种情况下进行优化。 第一种情况&#xff1a;有些问题&#xff0c;我们可能不需要看整个句子…

【hadoop】使用Java API 上传下载数据

使用Java API 上传下载数据 使用Java API上传数据到HDFSHDFS数据的下载 使用Java API上传数据到HDFS Test public void test1() throws Exception {//构造一个输入流&#xff0c;代表要上传的数据InputStream input new FileInputStream("d:\\temp\\hadoop-2.7.3.tar.gz…

HTML <output> 标签

实例 执行计算然后在 <output> 元素中显示结果: <form οninput="x.value=parseInt(a.value)+parseInt(b.value)">0<input type="range" id="a" value="50">100+<input type="number" id="b&q…

【问题总结】基于docker-compose实现nginx转发redis

目录&#xff1a; 文章目录 需求简介&#xff1a;Q1: nginx的http模块和http模块有什么不同Q2: 可以都使用stream模块进行配置吗 Docker环境下如何转发1 修改docker-compose2 修改nginx.conf3 测试连接 需求简介&#xff1a; 需要在192.168.3.11的ngnix上&#xff0c;转发192.…

前端 | ( 十)HTML5简介及相关新增属性 | 尚硅谷前端html+css零基础教程2023最新

学习来源&#xff1a;尚硅谷前端htmlcss零基础教程&#xff0c;2023最新前端开发html5css3视频 系列笔记&#xff1a; 【HTML4】&#xff08;一&#xff09;前端简介【HTML4】&#xff08;二&#xff09;各种各样的常用标签【HTML4】&#xff08;三&#xff09;表单及HTML4收尾…

MyBatis学习笔记——4

MyBatis学习笔记——4 一、MyBatis的高级映射及延迟加载1.1、多对一1.1.1、第一种方式&#xff1a;级联属性映射1.1.2、第二种方式&#xff1a;association1.1.3、第三种方式&#xff1a;分步查询 1.2、一对多1.2.1、第一种方式&#xff1a;collection1.2.1、第二种方式&#x…

Web后端开发总结

后端web开发大致流程 和对应的核心技术 对应技术的来源 springMVC可以理解为spring框架中的web开发框架 springMVCSpringMybatis就是我们熟知的ssm框架了

golang单元测试及mock总结

文章目录 一、前言1、单测的定位2、vscode中生成单测 二、构造测试case的注意事项1、项目初始化2、构造空interface{}3、构造结构体的time.Time类型4、构造json格式的test case 三、运行单测文件1、整体运行单测文件2、运行单个单测文件报错&#xff08;1&#xff09;command-l…

基于sklearn计算precision、recall等分类指标

文章目录 一、分类指标函数1.1 precision_score函数1.2 recall_score函数1.3 accuracy_score函数1.4 f1_score函数1.5 precision_recall_curve函数1.6 roc_curve函数1.7 roc_auc_score函数1.8 classification_report函数 二、二分类任务三、多分类任务3.1 Macro Average&#x…

怎样原生制作lis的CentOS容器镜像

本文介绍从一个空白的裸机CentOS自己构造检验允许的docker环境。来达到运行环境的高度定制&#xff0c;而不是只能依赖VS或者微软或者数据库厂商提供的镜像当做基础制作。更容易理解基础原理。最终输出产物为lisnew.tar&#xff0c;一个开箱即用的lis运行环境。 制作的整个过程…