java通过反射拿到mybatis中的sql语句并操作
private static final int MaxBatchLength = 100;
public void updateBatch(List<T>list, BaseMapper<T> mapper){
if (!Proxy.isProxyClass(mapper.getClass())){
throw new RuntimeException("mapper必须是代理对象");
}
InvocationHandler invocationHandler = Proxy.getInvocationHandler(mapper);
if (null==invocationHandler){
throw new RuntimeException("mapper必须是有处理器的代理对象");
}
Field fieldSession;
try {
fieldSession = invocationHandler.getClass().getDeclaredField("sqlSession");
} catch (NoSuchFieldException e) {
throw new RuntimeException("从mapper代理对象中获取不到sqlSession", e);
}
Field fieldMapper;
try {
fieldMapper = invocationHandler.getClass().getDeclaredField("mapperInterface");
} catch (NoSuchFieldException | SecurityException e) {
throw new RuntimeException("从mapper代理对象中获取不到mapperInterface", e);
}
fieldSession.setAccessible(true);
SqlSession session;
try {
session = (SqlSession) fieldSession.get(invocationHandler);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException("从mapper代理对象中获取sqlSession失败,不应该出现此异常", e);
}
fieldMapper.setAccessible(true);
Class<?> mapperInterface;
try {
mapperInterface = (Class<?>) fieldMapper.get(invocationHandler);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException("从mapper代理对象中获取mapperInterface失败,不应该出现此异常", e);
}
// 方法名(mybatis的对应xml中的sql语句的id)
String methodName = mapperInterface.getName() + ".updateEntityBatch";
System.out.println("获取方法的SQL:"+methodName);
//传递参数保证,要更新的字段存在(若没有判空,则可以不用传递参数)
BoundSql boundSql = session.getConfiguration().getMappedStatement(methodName).getBoundSql(list.get(0));
//是否是独立的事务
boolean atmo = true, succ = false;
System.out.println("每次批量执行最大长度为:"+MaxBatchLength );
//获取批量执行的sql
String sql = boundSql.getSql();
//获取连接
Connection connection = null;
PreparedStatement ps = null;
List<Closeable> closeables = new LinkedList<>();
try {
connection = session.getConnection();
if (atmo = null == connection || connection.isClosed()) {
DataSource dataSource = session.getConfiguration().getEnvironment().getDataSource();
connection = dataSource.getConnection();
//事务不自动提交
connection.setAutoCommit(false);
System.out.println("session中的连接不可使用,使用独立的连接和事务");
} else {
System.out.println("使用session的连接,事务和session保持一致");
}
ps = connection.prepareStatement(sql);
int index = 0;
System.out.println("需要批量更新"+list.size()+"个对象");
for (int i = 0, j = list.size(); i < j; i++, index++) {
T t = list.get(i);
//将实体类转换为map
BeanMap map = BeanMap.create(t);
System.out.println("绑定对象:"+ map);
for (int ii = 1, jj = boundSql.getParameterMappings().size(); ii <= jj; ii++) {
ParameterMapping parameterMapping = boundSql.getParameterMappings().get(ii - 1);
String name = parameterMapping.getProperty();
Object value = map.get(name);
if (null == value) {
// 为空时候尝试取默认值
value = map.get(name + "Default");
}
if (null != value && value instanceof Date) {
Timestamp date = new Timestamp(((Date) value).getTime());
value = date;
}
// 单独处理clob类型
if (JdbcType.CLOB.equals(parameterMapping.getJdbcType())) {
StringReader sr = new StringReader(null == value ? "" : value.toString());
ps.setClob(ii, sr);
closeables.add(sr);
} else {
ps.setObject(ii, value, parameterMapping.getJdbcType().TYPE_CODE);
}
}
ps.addBatch();
if (index > MaxBatchLength) {
ps.executeBatch();
ps.clearBatch();
index = 0;
}
}
if (index > 0) {
//执行剩下的
ps.executeBatch();
}
succ = true;
}catch (Exception e){
throw new RuntimeException("批量更新失败",e);
}finally {
// 如果是独立的事务
if (atmo && null != connection) {
log.info("检测到独立事务,判断提交/回滚");
if (succ) {
try {
connection.commit();
log.info("独立事务提交成功");
} catch (SQLException e) {
log.info("独立事务提交失败");
throw new RuntimeException(e);
}
} else {
try {
connection.rollback();
log.info("独立事务回滚成功");
} catch (SQLException e) {
log.info("独立事务回滚失败");
throw new RuntimeException(e);
}
}
}
if (null != ps) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (atmo && null != connection) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
for (Closeable closeable : closeables) {
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
java通过反射拿到mybatis中的sql语句并操作的更多相关文章
- 控制台输出 mybatis 中的sql语句
控制台输出 mybatis 中的sql语句 在 log4j.xml 文件中 增加如下配置 <!-- mybatis 输出的sql,DEBUG级别 --> <logger name=& ...
- MyBatis中动态SQL语句完成多条件查询
一看这标题,我都感觉到是mybatis在动态SQL语句中的多条件查询是多么的强大,不仅让我们用SQL语句完成了对数据库的操作:还通过一些条件选择语句让我们SQL的多条件.动态查询更加容易.简洁.直观. ...
- Mybatis中动态SQL语句中的parameterType不同数据类型的用法
Mybatis中动态SQL语句中的parameterType不同数据类型的用法1. 简单数据类型, 此时#{id,jdbcType=INTEGER}中id可以取任意名字如#{a,jdbcType ...
- MyBatis 中实现SQL语句中in的操作 (11)
MyBatis 中实现SQL语句中in的操作 概括:应用myBatis实现SQL查询中IN的操作 1.数据库结构及其数据 2.mapper.xml文件 <?xml version="1 ...
- 在mybatis中写sql语句的一些体会
本文会使用一个案例,就mybatis的一些基础语法进行讲解.案例中使用到的数据库表和对象如下: article表:这个表存放的是文章的基础信息 -- ------------------------- ...
- mybatis中打印sql语句
在mybatis-config.xml中properties节点下,配置一个settings节点 <settings> <setting name="cacheEnable ...
- EF Core中执行Sql语句查询操作之FromSql,ExecuteSqlCommand,SqlQuery
一.目前EF Core的版本为V2.1 相比较EF Core v1.0 目前已经增加了不少功能. EF Core除了常用的增删改模型操作,Sql语句在不少项目中是不能避免的. 在EF Core中上下文 ...
- 阶段3 1.Mybatis_08.动态SQL_03.mybatis中动态sql语句-foreach和sql标签
foreach标签 in的查询 sql语句好写,但是传参在映射文件里面改怎么传呢 定义一个List<Integer>成员变量,然后生成get和set 定义一个新的查询方法 open:开始符 ...
- 阶段3 1.Mybatis_08.动态SQL_02.mybatis中动态sql语句-where标签的使用
这里的userSex是实体类里面的属性名,而不是数据库内的字段名称 一个老王改成性别女,为了区分一下 增加sex字段的查询 where标签 用上where和刚才的执行效果是一样的 where标签使我们 ...
随机推荐
- c#Main()方法,java 是小写main
main 方法,staitc 静态关键首字母大写,区分大小写,java 是main小写,返回值 ,vodi,int参数:可选static void Main(string[] args){ }
- HBuilder打包app(vue项目)
一.测试项目是否可以正确运行 指令:npm run dev 首先我们先建立一个vue的项目,本人用的是vue-cli随便建立的,然后运行项目 不必非得是像我这样的,这一步的目的只是测试一下咱们的 ...
- css浮动现象及清除浮动的方法
css浮动现象及清除浮动的方法 首先先明确浮动最初的定义及使用场景:实现文本环绕图片的效果. 除了用浮动外,目前暂无其他方法实现文本环绕 再来看看浮动的具体定义: 浮动的框可以左右移动,直至它 ...
- php红包功能
最近公司要开发 广告红包功能,这是写好的代码先放到这 https://files.cnblogs.com/files/jxkshu/PHP%E5%B9%BF%E5%91%8A%E7%BA%A2%E5% ...
- Linux学习篇(三)-Linux操作系统及常用命令
小知识:南桥北桥 北桥是高速总线控制器,在CPU附近,连接内存和CPU,需要传输大量数据. 南桥是低速总线控制器,用于连接IO设备(硬盘键盘鼠标等),IO设备由南桥汇总会直接传入北桥.,目前cpu可以 ...
- maven 依赖调解
项目A有两条依赖关系 A->B->C->X(1.0),A->D->X(2.0) ,X是A的传递性依赖,但是两条路径上有两个版本的依赖,会选择哪个呢? maven 依赖调 ...
- vue同意本站协议的制作
<!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...
- 1、Laravel 环境配置及安装
一.开发工具及环境 PHPStorm + phpStudy 最新版 Composer 安装 https://www.phpcomposer.com/ 下载就可以,设置中国镜像 安装完成后 compos ...
- jQuery基础--创建节点和 添加节点
创建节点 $(function () { // var box = document.getElementById("box"); // // var a = document.c ...
- lib.tcl
#********************************************************************# 功能描述:定义公共的函数# 依赖关系:依赖于全局aitoo ...