java通过反射拿到mybatis中的sql语句并操作

1private static final int MaxBatchLength = 100; 2 3public void updateBatch(List<T>list, BaseMapper<T> mapper){ 4 5 if (!Proxy.isProxyClass(mapper.getClass())){ 6 throw new RuntimeException("mapper必须是代理对象"); 7 } 8 InvocationHandler invocationHandler = Proxy.getInvocationHandler(mapper); 9 if (null==invocationHandler){ 10 throw new RuntimeException("mapper必须是有处理器的代理对象"); 11 } 12 Field fieldSession; 13 try { 14 fieldSession = invocationHandler.getClass().getDeclaredField("sqlSession"); 15 } catch (NoSuchFieldException e) { 16 throw new RuntimeException("从mapper代理对象中获取不到sqlSession", e); 17 } 18 Field fieldMapper; 19 try { 20 fieldMapper = invocationHandler.getClass().getDeclaredField("mapperInterface"); 21 } catch (NoSuchFieldException | SecurityException e) { 22 throw new RuntimeException("从mapper代理对象中获取不到mapperInterface", e); 23 } 24 fieldSession.setAccessible(true); 25 SqlSession session; 26 try { 27 session = (SqlSession) fieldSession.get(invocationHandler); 28 } catch (IllegalArgumentException | IllegalAccessException e) { 29 throw new RuntimeException("从mapper代理对象中获取sqlSession失败,不应该出现此异常", e); 30 } 31 fieldMapper.setAccessible(true); 32 Class<?> mapperInterface; 33 try { 34 mapperInterface = (Class<?>) fieldMapper.get(invocationHandler); 35 } catch (IllegalArgumentException | IllegalAccessException e) { 36 throw new RuntimeException("从mapper代理对象中获取mapperInterface失败,不应该出现此异常", e); 37 } 38 // 方法名(mybatis的对应xml中的sql语句的id) 39 String methodName = mapperInterface.getName() + ".updateEntityBatch"; 40 System.out.println("获取方法的SQL:"+methodName); 41 //传递参数保证,要更新的字段存在(若没有判空,则可以不用传递参数) 42 BoundSql boundSql = session.getConfiguration().getMappedStatement(methodName).getBoundSql(list.get(0)); 43 44 //是否是独立的事务 45 boolean atmo = true, succ = false; 46 System.out.println("每次批量执行最大长度为:"+MaxBatchLength ); 47 48 //获取批量执行的sql 49 String sql = boundSql.getSql(); 50 //获取连接 51 Connection connection = null; 52 PreparedStatement ps = null; 53 List<Closeable> closeables = new LinkedList<>(); 54 try { 55 connection = session.getConnection(); 56 if (atmo = null == connection || connection.isClosed()) { 57 DataSource dataSource = session.getConfiguration().getEnvironment().getDataSource(); 58 connection = dataSource.getConnection(); 59 //事务不自动提交 60 connection.setAutoCommit(false); 61 System.out.println("session中的连接不可使用,使用独立的连接和事务"); 62 } else { 63 System.out.println("使用session的连接,事务和session保持一致"); 64 } 65 66 ps = connection.prepareStatement(sql); 67 68 int index = 0; 69 System.out.println("需要批量更新"+list.size()+"个对象"); 70 71 for (int i = 0, j = list.size(); i < j; i++, index++) { 72 T t = list.get(i); 73 //将实体类转换为map 74 BeanMap map = BeanMap.create(t); 75 System.out.println("绑定对象:"+ map); 76 for (int ii = 1, jj = boundSql.getParameterMappings().size(); ii <= jj; ii++) { 77 ParameterMapping parameterMapping = boundSql.getParameterMappings().get(ii - 1); 78 String name = parameterMapping.getProperty(); 79 Object value = map.get(name); 80 if (null == value) { 81 // 为空时候尝试取默认值 82 value = map.get(name + "Default"); 83 } 84 if (null != value && value instanceof Date) { 85 Timestamp date = new Timestamp(((Date) value).getTime()); 86 value = date; 87 } 88 // 单独处理clob类型 89 if (JdbcType.CLOB.equals(parameterMapping.getJdbcType())) { 90 StringReader sr = new StringReader(null == value ? "" : value.toString()); 91 ps.setClob(ii, sr); 92 closeables.add(sr); 93 } else { 94 ps.setObject(ii, value, parameterMapping.getJdbcType().TYPE_CODE); 95 } 96 } 97 ps.addBatch(); 98 if (index > MaxBatchLength) { 99 ps.executeBatch(); 100 ps.clearBatch(); 101 index = 0; 102 } 103 } 104 if (index > 0) { 105 //执行剩下的 106 ps.executeBatch(); 107 } 108 succ = true; 109 }catch (Exception e){ 110 throw new RuntimeException("批量更新失败",e); 111 }finally { 112 // 如果是独立的事务 113 if (atmo && null != connection) { 114 log.info("检测到独立事务,判断提交/回滚"); 115 if (succ) { 116 try { 117 connection.commit(); 118 log.info("独立事务提交成功"); 119 } catch (SQLException e) { 120 log.info("独立事务提交失败"); 121 throw new RuntimeException(e); 122 } 123 } else { 124 try { 125 connection.rollback(); 126 log.info("独立事务回滚成功"); 127 } catch (SQLException e) { 128 log.info("独立事务回滚失败"); 129 throw new RuntimeException(e); 130 } 131 } 132 } 133 if (null != ps) { 134 try { 135 ps.close(); 136 } catch (SQLException e) { 137 e.printStackTrace(); 138 } 139 } 140 if (atmo && null != connection) { 141 try { 142 connection.close(); 143 } catch (SQLException e) { 144 e.printStackTrace(); 145 } 146 } 147 for (Closeable closeable : closeables) { 148 try { 149 closeable.close(); 150 } catch (IOException e) { 151 e.printStackTrace(); 152 } 153 } 154 } 155 }
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Java日期时间API系列31

  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前