构建 in sql语句
构建 in sql语句
package nc.util.hbbb;import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;import nc.bs.logging.Logger;
import nc.bs.mw.sqltrans.TempTable;
import nc.jdbc.framework.ConnectionFactory;
import nc.jdbc.framework.DataSourceCenter;
import nc.jdbc.framework.JdbcSession;
import nc.jdbc.framework.PersistenceManager;
import nc.jdbc.framework.SQLParameter;
import nc.jdbc.framework.crossdb.CrossDBConnection;
import nc.jdbc.framework.exception.DbException;
import nc.vo.pub.BusinessException;
import nc.vo.pub.SuperVO;
/**** <p>* 和责任会计sql构建一样* </p>* modified by jiaah at 20130829* 此处构建的in语句全部都不在使用临时表了,否则再多线程处理的时候有问题,先暂时这么处理了* 修改记录:<br>* <li>修改人:修改日期:修改内容:</li>* <br><br>**/
public class UFOCSqlUtil {public static final int MAXLENGTH = 200;public static final int inMaxLimitCount = 800;// in(...)里面元素的最大阀值,超过该阀值的时候,SQL解析可能会出错,必须使用临时表等其他办法public static final int TMPMAXCOUNT = 20000;public static String tempTableName = "ufoc_tmp_table";public static String tempcolname = "pk";public static String tempcoltype = "varchar(60)";/*** 构建In sql条件,根据参数构建in list或者临时表* <p>* 修改记录:* </p>** @param fieldName* @param values* 值数组* @param listMax* 是否建临时表的阈值* @return 包含in关键字的完成sql 片段* @see* @since V6.0*/public static String buildInSql(String fieldName, String[] values,int listMax) throws BusinessException {return buildInSql(fieldName, Arrays.asList(values), true);}/*** * 构建In sql条件,根据参数构建in list或者临时表* <p>修改记录:</p>* @param fieldName* @param values* @return* @throws BusinessException* @see * @since V6.0*/public static String buildInSql(String fieldName, String[] values)throws BusinessException {return buildInSql(fieldName, Arrays.asList(values), true);}/*** * 构建In sql条件,根据参数构建in list或者临时表* <p>修改记录:</p>* @param fieldName* @param values* @return* @throws BusinessException* @see * @since V6.0*/public static String buildInSql(String fieldName, Collection<String> values)throws BusinessException {return buildInSql(fieldName, values, true);}public static <T extends SuperVO>String buildInSql(String fieldName, Collection<T> values,String attrName)throws BusinessException {Collection<String> col = new ArrayList<String>();for(T vo : values)col.add((String)vo.getAttributeValue(attrName));return buildInSql(fieldName, col, true);}/*** 获得In 语句** @param fieldName* 字段名* @param pks* 主键数组* @return* @throws SQLException*/public static String buildInSql(String fieldName, Collection<String> values, boolean autoUseTempTable) throws BusinessException {if (fieldName == null) {throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("pub_0","01830001-0524")/*@res "字段名不允许传空值。"*/);}if (values == null || values.isEmpty()) {return fieldName + " in ('') ";}else if(values.size() == 1){// @edit by wuyongc at 2013-10-31,下午1:28:20 如果数组只有一个值,就不需要使用in了return " " + fieldName + " ='" + values.toArray(new String[0])[0] + "'";}List<String> pks = null;if(values instanceof List) {pks = (List<String>) values;} else {pks = new ArrayList<String>();pks.addAll(values);}String rsStr = null;int length = pks.size();if (length > MAXLENGTH && autoUseTempTable) {return autoUseTmpTable(fieldName, pks, length);}if (length > inMaxLimitCount) {// 超过in(...)的最大阀值,使用( field in(...) or field in(...) or// ...)的方式来实现,效率非常低StringBuffer sb = new StringBuffer();sb.append(" (");for (int i = 0; i < length;) {sb.append(getInStr(fieldName, pks, i, i+ inMaxLimitCount - 1));sb.append(" or");i = i + inMaxLimitCount;}rsStr = sb.substring(0, sb.length() - 3) + ") ";} else {// 没有超过最大阀值,可以写在一个in(...)里面rsStr = getInStr(fieldName, pks, 0, length - 1);}return rsStr;}/*** 自动使用临时表* <p>修改记录:</p>* @param fieldName* @param pks* @param length* @return* @see* @since V6.0*/private static String autoUseTmpTable(String fieldName, List<String> pks,int length) {String rsStr;boolean canCreateTable = false;// 只有在服务器上运行的时候才可以创建临时表try {// canCreateTable = RuntimeEnv.getInstance().isRunningInServer();} catch (Exception e) {Logger.error("UFOCSQLUtil查看服务器运行与否出错!", e);} catch (Error e) {Logger.error("UFOCSQLUtil查看服务器运行与否出错!", e);}if (canCreateTable) {try {String tablename = getTempTablename(fieldName);String colname = tempcolname;String coltype = tempcoltype;tablename = createTempTable(tablename, colname, coltype);if (tablename == null) {// 临时表创建失败,重新尝试创建一次tablename = getTempTablename(fieldName);tablename = createTempTable(tablename, colname, coltype);}if (tablename == null) {throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("pub_0","01830001-0525")/*@res "创建临时表失败"*/);} else {insertIntoTable(tablename, colname, pks);}rsStr = fieldName + " in (select " + colname + " from "+ tablename + " where "+colname+" is not null ) ";} catch (Exception e) {Logger.error("创建临时表失败。尝试使用OR方式。", e);if (length > inMaxLimitCount) {// 超过in(...)的最大阀值,使用( field in(...) or field in(...)// or ...)的方式来实现,效率非常低StringBuffer sb = new StringBuffer();sb.append(" (");for (int i = 0; i < length;) {sb.append(getInStr(fieldName, pks, i, i+ inMaxLimitCount - 1));sb.append(" or");i = i + inMaxLimitCount;}rsStr = sb.substring(0, sb.length() - 3) + ") ";} else {// 没有超过最大阀值,可以写在一个in(...)里面rsStr = getInStr(fieldName, pks, 0, length - 1);}}} else if (length > inMaxLimitCount) {// 超过in(...)的最大阀值,使用( field in(...) or field in(...) or// ...)的方式来实现,效率非常低StringBuffer sb = new StringBuffer();sb.append(" (");for (int i = 0; i < length;) {sb.append(getInStr(fieldName, pks, i, i+ inMaxLimitCount - 1));sb.append(" or");i = i + inMaxLimitCount;}rsStr = sb.substring(0, sb.length() - 3) + ") ";} else {// 没有超过最大阀值,可以写在一个in(...)里面rsStr = getInStr(fieldName, pks, 0, length - 1);}return rsStr;}// public static String getTempTable(String tempTableName,String[] pks) {//
// if(pks == null || pks.length ==0) {// return null;
// }
//
// boolean canCreateTable = false;// 只有在服务器上运行的时候才可以创建临时表
// try {// canCreateTable = RuntimeEnv.getInstance().isRunningInServer();
// } catch (Exception e) {// Logger.error("UFOCSQLUtil查看服务器运行与否出错!", e);
// } catch (Error e) {// Logger.error("UFOCSQLUtil查看服务器运行与否出错!", e);
// }
// if (canCreateTable) {// String tablename = null;
// if(StringUtils.isEmpty(tempTableName)) {// tablename = getTempTablename(null);
// }else {// tablename = tempTableName;
// }
// String colname = tempcolname;
// String coltype = tempcoltype;
// try {// tablename = createTempTable(tablename, colname, coltype);
// if (tablename == null) {// // 临时表创建失败,重新尝试创建一次
// tablename = createTempTable(tablename, colname, coltype);
// }
// if (tablename == null) {// throw new BusinessException("创建临时表失败");
// } else {// insertIntoTable(tablename, colname, Arrays.asList(pks));
// return tablename;
// }
// } catch (Exception e) {// Logger.error(e);
// }
// }
// return null;
// }/*** * 拼出in条件:* <p>修改记录:</p>* @param fieldName* @param pks* @param start* @param end* @return* @see * @since V6.0*/private static String getInStr(String fieldName, List<String> pks, int start, int end) {start = Math.min(start, end);end = Math.max(start, end);StringBuffer sb = new StringBuffer();sb.append(" ");sb.append(fieldName);sb.append(" in (");String key = null;for (int i = start; i < pks.size(); i++) {if (i > end) {break;}if (pks.get(i) == null)continue;key = pks.get(i).trim();sb.append("'");sb.append(key);sb.append("',");}String inStr = sb.substring(0, sb.length() - 1) + ") ";return inStr;}/**** 构造临时表名, 返回表名长度<=18位** @param fieldName* @return*/private static String getTempTablename(String fieldName) {return tempTableName;}/*** 创建临时表** <p>* 修改记录:* </p>** @param fieldName* @return* @throws SQLException* @see* @since V6.0*/public static String createTempTable(String tablename, String colname, String coltype) throws SQLException {Connection con = null;try {con = ConnectionFactory.getConnection();TempTable tt = new TempTable();tablename = tt.createTempTable(con, tablename, " " + colname + " " + coltype + " ", null);} finally {try {if (con != null)con.close();} catch (Exception e) {}}return tablename;}/*** 把数据插入临时表** <p>* 修改记录:* </p>** @param tableName* @param colName* @param datas* @throws java.sql.SQLException* @throws DbException* @see* @since V6.0*/private static void insertIntoTable(String tableName, String colName, Collection<String> datas) throws java.sql.SQLException, DbException {java.sql.Connection con = null;JdbcSession session = null;try {PersistenceManager manager = PersistenceManager.getInstance(DataSourceCenter.getInstance().getSourceName());manager.setAddTimeStamp(false);session = manager.getJdbcSession();con = session.getConnection();if (con instanceof CrossDBConnection) {((CrossDBConnection) con).setAddTimeStamp(false);}String sql_insert = "insert into " + tableName + " (" + colName + ") values( ? ) ";session.setBatchSize(TMPMAXCOUNT);for (String string : datas) {SQLParameter sqlParam = new SQLParameter();sqlParam.addParam(string);session.addBatch(sql_insert, sqlParam);}session.executeBatch();} finally {try {if (con != null)con.close();} catch (Exception e) {}try {if (session != null)session.closeAll();} catch (Exception e) {}}}/*** * 执行完成后,删除临时表* <p>修改记录:</p>* @throws SQLException* @see * @since V6.0*/public void dropTempTable() throws SQLException{Connection con = null;try {con = ConnectionFactory.getConnection();TempTable tt = new TempTable();tt.dropTempTable(con, tempTableName);} finally {try {if (con != null)con.close();} catch (Exception e) {}}}// /**
// *
// * 执行完成后,删除临时表
// * <p>修改记录:</p>
// * @throws SQLException
// * @see
// * @since V6.0
// */
// public static void dropTempTable(String tempTable) throws SQLException{// Connection con = null;
// try {// con = ConnectionFactory.getConnection();
// TempTable tt = new TempTable();
// if(StringUtils.isEmpty(tempTable)) {// tt.dropTempTable(con, tempTableName);
// }else {// tt.dropTempTable(con, tempTable);
// }
// } finally {// try {// if (con != null)
// con.close();
// } catch (Exception e) {// }
// }
// }
}
构建 in sql语句相关推荐
- 在存储过程中构建动态SQL
目录 介绍 sp_executesql与EXECUTE命令 例1.0 例1.1 存储过程中的动态SQL 例2.0 在动态SQL中使用Like操作符,IN操作符和Order By 例3.0 - 使用LI ...
- MyBatis超详细介绍——SQL语句构建器类
MyBatis超详细介绍--SQL语句构建器类 (本文作为学习笔记,了解更多请参考:MyBatis参考文档) MyBatis3提供了SQL类帮助构造SQL语句: private String sele ...
- mybatis入门(六)之SQL语句构建器类
转载自 mybatis SQL语句构建器类 问题 Java程序员面对的最痛苦的事情之一就是在Java代码中嵌入SQL语句.这么来做通常是由于SQL语句需要动态来生成-否则可以将它们放到外部文件或 ...
- mybatis的SQL语句构建器
mybatis的SQL语句构建器 SQLProvider.java package com.qfedu.test;import com.qfedu.pojo.User; import org.apac ...
- mybatis_user_guide(7) SQL语句构建器类
[0]README 1)本文全文总结于 http://www.mybatis.org/mybatis-3/zh/statement-builders.html [1]在Java代码中来动态生成SQL ...
- 转在同一个sql语句中如何写不同条件的count数量
今天在做Portal中的Dashboard展现的时候,需要对多个统计字段做展现,根据我现在的掌握水平,我只能在sql调用构建器中实现一种sql语 句返回的resultSet做展现.没有办法,只能从数据 ...
- beeline执行sql语句_由“Beeline连接HiveServer2后如何使用指定的队列(Yarn)运行Hive SQL语句”引发的一系列思考...
背景 我们使用的HiveServer2的版本为0.13.1-cdh5.3.2,目前的任务使用Hive SQL构建,分为两种类型:手动任务(临时分析需求).调度任务(常规分析需求),两者均通过我们的We ...
- Mybatis Plus 是如何实现动态 SQL 语句的?原理你懂吗?
作者 | 稻草江南 来源 | https://juejin.cn/post/6883081187103866894 Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,那么它是怎么 ...
- mysql load xml_MySQL的SQL语句 - 数据操作语句(10)- LOAD XML 语句
LOAD XML 语句 1. LOAD XML 2. [LOW_PRIORITY | CONCURRENT] [LOCAL] 3. INFILE 'file_name' 4. [REPLACE | I ...
最新文章
- 7-flutter Navigator 和Route
- Electron-builder打包详解
- 2072. Kirill the Gardener 3
- VTK:参数化超环形用法实战
- Optical_Flow(3)
- Poor God Water【矩阵快速幂】
- 【Java】JDBC连接MySQL驱动
- Java常见排序算法之Shell排序
- JAVA毕业设计高速公路收费管理计算机源码+lw文档+系统+调试部署+数据库
- JS前端怎样通过程序来获取当前浏览器是什么版本的浏览器(或者判断当前浏览器是否为IE8及以下浏览器)
- 路遥《平凡的世界》读后感
- gbq可以算出土建量吗_广联达土建算量软件必备操作指南
- 使用css让div半透明
- 手机识别图片文字的方法
- 关于多个Jenkins实例共享同一个工作目录的问题
- CMD快捷指令之打开磁盘清理工具
- Django--基于Python的Web应用框架
- 浅析 Transformer Stage 在 DataStage 作业中的用法及功能实现
- Vue+SpringBoot+ElementUI实战学生管理系统-9.教师管理模块
- trac linux,CentOS下安装Trac笔记