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语句并操作的更多相关文章

  1. 控制台输出 mybatis 中的sql语句

    控制台输出 mybatis 中的sql语句 在 log4j.xml 文件中 增加如下配置 <!-- mybatis 输出的sql,DEBUG级别 --> <logger name=& ...

  2. MyBatis中动态SQL语句完成多条件查询

    一看这标题,我都感觉到是mybatis在动态SQL语句中的多条件查询是多么的强大,不仅让我们用SQL语句完成了对数据库的操作:还通过一些条件选择语句让我们SQL的多条件.动态查询更加容易.简洁.直观. ...

  3. Mybatis中动态SQL语句中的parameterType不同数据类型的用法

    Mybatis中动态SQL语句中的parameterType不同数据类型的用法1. 简单数据类型,    此时#{id,jdbcType=INTEGER}中id可以取任意名字如#{a,jdbcType ...

  4. MyBatis 中实现SQL语句中in的操作 (11)

    MyBatis 中实现SQL语句中in的操作 概括:应用myBatis实现SQL查询中IN的操作 1.数据库结构及其数据 2.mapper.xml文件 <?xml version="1 ...

  5. 在mybatis中写sql语句的一些体会

    本文会使用一个案例,就mybatis的一些基础语法进行讲解.案例中使用到的数据库表和对象如下: article表:这个表存放的是文章的基础信息 -- ------------------------- ...

  6. mybatis中打印sql语句

    在mybatis-config.xml中properties节点下,配置一个settings节点 <settings> <setting name="cacheEnable ...

  7. EF Core中执行Sql语句查询操作之FromSql,ExecuteSqlCommand,SqlQuery

    一.目前EF Core的版本为V2.1 相比较EF Core v1.0 目前已经增加了不少功能. EF Core除了常用的增删改模型操作,Sql语句在不少项目中是不能避免的. 在EF Core中上下文 ...

  8. 阶段3 1.Mybatis_08.动态SQL_03.mybatis中动态sql语句-foreach和sql标签

    foreach标签 in的查询 sql语句好写,但是传参在映射文件里面改怎么传呢 定义一个List<Integer>成员变量,然后生成get和set 定义一个新的查询方法 open:开始符 ...

  9. 阶段3 1.Mybatis_08.动态SQL_02.mybatis中动态sql语句-where标签的使用

    这里的userSex是实体类里面的属性名,而不是数据库内的字段名称 一个老王改成性别女,为了区分一下 增加sex字段的查询 where标签 用上where和刚才的执行效果是一样的 where标签使我们 ...

随机推荐

  1. CentOS下安装Chrome浏览器中文显示为方框

    执行如下三条命令 yum groupinstall "X Window System" -y yum -y groupinstall chinese-support yum -y  ...

  2. C# 常用的ToString("xxxx")

    Convert.ToDecimal("-123").ToString("#,#.##") 结果:-123 Convert.ToDecimal("-12 ...

  3. elasticsearch6.8.1 x-pack插件破解

    一.为什么要破解x-pack?       因为涉及到了ES服务的安全性.ES服务如果被劫持,数据直接会被删除.ES登录账号和密码的设置是通过x-pack来实现的,官方只给了免费的30天的使用权,而且 ...

  4. linux RZ 命令

    root 账号登陆后,依次执行以下命令: 1 cd /tmp 2 wget http://www.ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz 3 tar zxv ...

  5. elasticsearch 5.1 认证过期 (your license has expired)

    首先说一下License过期后的状况: if 设置了登录认证,license过期后将无法登录(无法填入用户名密码,下方给出报错,license过期): if 没有设置登录认证,打开kibaba界面中M ...

  6. Vue混入:全局混入

    一 项目结构 二 main.js import Vue from "vue"; import App from "./App.vue"; Vue.config. ...

  7. springboot jpa 级联操作及测试问题 (@Transactional与@Test)

    前言:测试springboot版本     :springBootVersion = '2.0.5.RELEASE' 一 :搬运@Transactional B. 如果加了事务,必须做好开发环境测试( ...

  8. 2019/11/02 TZOJ

    1001 ShaoLin http://www.tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=6003 标记一下i ...

  9. Rust SDL2配置

    github地址 https://github.com/Rust-SDL2/rust-sdl2 clone或下载这个项目 本文使用的是MSVC版本 上面链接页面搜Windows (MSVC) 得知需要 ...

  10. maven基础--下载安装配置命令生命周期

    maven apache 公司开源项目,项目构建工具 好处: 项目小 坐标:公司名称+项目名称+版本信息 通过坐标去 仓库查找jar包 maven的两大核心: *赖管理:对jar包管理过程. 项目构建 ...