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标签使我们 ...
随机推荐
- 关于VS调试
环境配置始终是我的弱项,碰到关于环境配置的问题就各种束手无策.但是这种事情,不能总凑合着,尤其你进不去环境或者没法调试的时候,代码写的多漂亮都没用.下面就来说一下最近关于调试的了解. 首先我们现在的项 ...
- OC + RAC (二) Command 命令的用法
-(void)_test2{ ///////////////////////////////////////Command 命令的用法 注意使用command.executionSignals去订阅时 ...
- Object and Collection Initializers (C# Programming Guide) 类初始化
public class Cat { // Auto-implemented properties. public int Age { get; set; } public string Name { ...
- Linux内核设计与实现 总结笔记(第四章)进程调度
进程调度 调度程序负责决定将哪个进程投入运行,何时运行以及运行多长时间. 调度程序没有太复杂的原理,最大限度地利用处理器时间的原则是,只要有可以执行的进程,那么就总会有进程正在执行. 一.多任务 多任 ...
- C++ 得到系统时间
Time::Time() {//得到系统时间 初始化 time_t t; t=time(NULL); tm *lt; lt=localtime(&t); hour=lt->tm_hour ...
- python之-框架
MVC:Model-View-Controller,中文名“模型-视图-控制器” C——Python处理URL的函数:Controller,Controller负责业务逻辑,比如检查用户名是否存在,取 ...
- HTTP请求时候总是设置的两个参数ConnectionTimeOut和SocketTimeOut
在HTTP请求时候总是设置两个参数,就是连接超时和Socket超时 public static final String SO_TIMEOUT = "http.socket.timeout& ...
- mybatis有结果返回null
解决:application.yml 中mybatis此项(解决驼峰及数据库字段有下划线问题) map-underscore-to-camel-case: true 问题: mybatis debug ...
- mysql一主多从配置详情
https://www.cnblogs.com/zgx/archive/2011/09/13/2174823.html 1.准备好3台虚机,一台master,两台slave且都安装好mysql 2.主 ...
- 2019年Java Web最流行的开发框架总结
ORM型框架:对数据进行持久化操作,例如:基于SQL的MyBatis框架和Hibernate框架. MVC型框架:从逻辑上分为视图层,控制层,模型层,各层各司其职,之间是相互调用的关系,而不是相互依赖 ...