java通过反射拿到mybatis中的sql语句并操作private static final int MaxBatchLength = 100;
public void updateBatch(List<T>list, BaseMapper<T> mapper){
if (!Proxy.Class())){
throw new RuntimeException("mapper必须是代理对象");
}
InvocationHandler invocationHandler = InvocationHandler(mapper);
if (null==invocationHandler){
throw new RuntimeException("mapper必须是有处理器的代理对象");
}
Field fieldSession;
try {
fieldSession = Class().getDeclaredField("sqlSession");
} catch (NoSuchFieldException e) {
throw new RuntimeException("从mapper代理对象中获取不到sqlSession", e);
}
Field fieldMapper;
try {
fieldMapper = Class().getDeclaredField("mapperInterface");
} catch (NoSuchFieldException | SecurityException e) {
throw new RuntimeException("从mapper代理对象中获取不到mapperInterface", e);
}
fieldSession.setAccessible(true);
SqlSession session;
try {
session = (SqlSession) (invocationHandler);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException("从mapper代理对象中获取sqlSession失败,不应该出现此异常", e);
}
fieldMapper.setAccessible(true);
Class<?> mapperInterface;
try {
mapperInterface = (Class<?>) (invocationHandler);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException("从mapper代理对象中获取mapperInterface失败,不应该出现此异常", e);
}
// ⽅法名(mybatis的对应xml中的sql语句的id)
String methodName = Name() + ".updateEntityBatch";
System.out.println("获取⽅法的SQL:"+methodName);
//传递参数保证,要更新的字段存在(若没有判空,则可以不⽤传递参数)
BoundSql boundSql = Configuration().getMappedStatement(methodName).(0));
//是否是独⽴的事务
boolean atmo = true, succ = false;
System.out.println("每次批量执⾏最⼤长度为:"+MaxBatchLength );
//获取批量执⾏的sql
String sql = Sql();
//获取连接
Connection connection = null;
PreparedStatement ps = null;
List<Closeable> closeables = new LinkedList<>();
try {
connection = Connection();
if (atmo = null == connection || connection.isClosed()) {
DataSource dataSource = Configuration().getEnvironment().getDataSource();
connection = Connection();
/
/事务不⾃动提交
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 = (i);
/
/将实体类转换为map
BeanMap map = ate(t);
System.out.println("绑定对象:"+ map);
for (int ii = 1, jj = ParameterMappings().size(); ii <= jj; ii++) {
ParameterMapping parameterMapping = ParameterMappings().get(ii - 1);
String name = Property();
Object value = (name);
if (null == value) {
// 为空时候尝试取默认值
value = (name + "Default");
}
if (null != value && value instanceof Date) {
Timestamp date = new Timestamp(((Date) value).getTime());
value = date;
}
// 单独处理clob类型
if (JdbcType.CLOB.JdbcType())) {
StringReader sr = new StringReader(null == value ? "" : String()); ps.setClob(ii, sr);
closeables.add(sr);
} else {
ps.setObject(ii, value, JdbcType().TYPE_CODE); }
}
ps.addBatch();
if (index > MaxBatchLength) {
ps.clearBatch();
index = 0;
}
}
if (index > 0) {
//执⾏剩下的
}
succ = true;
}catch (Exception e){
throw new RuntimeException("批量更新失败",e);
}finally {
// 如果是独⽴的事务
if (atmo && null != connection) {
log.info("检测到独⽴事务,判断提交/回滚");批量更新sql语句
if (succ) {
try {
connectionmit();
log.info("独⽴事务提交成功");
} catch (SQLException e) {
log.info("独⽴事务提交失败");
throw new RuntimeException(e);
}
} else {
try {
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();
}
}
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论