package cn.zwork.crm.testdata; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 将多条sql根据表名合并成多值sql的正规表达式分组应用 * */ public class Test { public static void main(String[] args) { //下面进行测试 //下面的sql可以认为是通过程序生成的sql,如果sql条数很多(如几百万),需要很长时间才能执行完。 List<String> sqlList = new ArrayList<String>(); sqlList.add("INSERT INTO BUSSINESS_1(EMPLOYEE_ID, OCCUR_DATE, ACTION_TYPE, MODULE) VALUES(17, '2012-9-17', 'insert', 'CUSTOMER')"); sqlList.add("INSERT INTO BUSSINESS_1(EMPLOYEE_ID, OCCUR_DATE, ACTION_TYPE, MODULE) VALUES(17, '2012-9-17', 'update', 'CUSTOMER')"); sqlList.add("INSERT INTO BUSSINESS_2(EMPLOYEE_ID, OCCUR_DATE, ACTION_TYPE, MODULE) VALUES(17, '2012-9-17', 'insert', 'PERSON')"); sqlList.add("INSERT INTO BUSSINESS_2(EMPLOYEE_ID, OCCUR_DATE, ACTION_TYPE, MODULE) VALUES(17, '2012-9-17', 'update', 'PERSON')"); //通过合并sql,使sql的条数减少,本例中由四条减少到2条。在实际项目中,由100万减少到20几万。 List<String> sql = mergeSql(sqlList); System.out.println(sql); /* * 结果为,用这个结果生成文本文件,再在数据库上执行 * INSERT INTO BUSSINESS_2(EMPLOYEE_ID, OCCUR_DATE, ACTION_TYPE, MODULE) VALUES (17, '2012-9-17', 'insert', 'PERSON'),(17, '2012-9-17', 'update', 'PERSON') * INSERT INTO BUSSINESS_1(EMPLOYEE_ID, OCCUR_DATE, ACTION_TYPE, MODULE) VALUES (17, '2012-9-17', 'insert', 'CUSTOMER'),(17, '2012-9-17', 'update', 'CUSTOMER') * * */ } /** * * 将多条sql根据表名合并成多值sql. * 应用场景:在做几百万测试数据时(通过程序生成单条sql),执行单条sql,效率很低,通过合并后大大提高了执行效率。 * * * @param sqlList * @return */ private static List<String> mergeSql(List<String> sqlList) { List<String> result; Map<String, String> sqlGroup = new HashMap<String, String>(); Pattern p = Pattern.compile("(INSERT *INTO)(.*)( *\\(.*\\) *)VALUES(.*)"); /* * 详细说明一下表达式: * 1 ()用来分组,本例中共分四组 * 2 \\ 表示转义符,本例中(和)需要转义,即\\(和\\) * 3 . 表示任何字符,包括空格 * 4 X* X被匹配零次或多次,本例中空格和.被匹配零次或多次 * 5 第一组匹配:INSERT INTO,第二组匹配:表名,第三组匹配:列,第四组匹配:值 * */ for (String eachSql : sqlList) { Matcher m = p.matcher(eachSql); if (m.matches()) { String op = m.group(1); String tableName = m.group(2).trim();//表名 String column = m.group(3);//列 String value = m.group(4);//值 if (sqlGroup.get(tableName) != null) { String sql = sqlGroup.get(tableName); sql += "," + value; sqlGroup.put(tableName, sql); } else { String sql = op + " " + tableName + column + " VALUES " + value; sqlGroup.put(tableName, sql); } } } // 将map中的值,转成list返回 result = new ArrayList(sqlGroup.values()); return result; } }