package com.github.walker.easydb.dao.oracle; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.StringTokenizer; import java.util.Vector; import com.github.walker.easydb.assistant.MappingUtil; import com.github.walker.easydb.dao.FieldExp; import com.github.walker.easydb.dao.SqlConstructor; import com.github.walker.easydb.datatype.EBinFile; import com.github.walker.easydb.datatype.ETxtFile; import com.github.walker.easydb.exception.IllegalParamException; import com.github.walker.easydb.criterion.Criteria; import com.github.walker.easydb.dao.EntityParser; import com.github.walker.easydb.dao.SqlParamIndexer; import com.github.walker.easydb.datatype.UpdateIdentifier; import com.github.walker.easydb.exception.IllegalEntityException; /** * The oracle version of sql constructor. * * @author HuQingmiao */ public class OracleSqlConstructor extends SqlConstructor { // 以下关键字是EasyDB专用的, 在客户程序传入的SQL中不得使用. private static final String EASYDB_PAGER_ROW = "EASYDB_PAGER_ROW"; private static final String EASYDB_A = "EASYDB_A"; private static final String EASYDB_B = "EASYDB_B"; private static final String EASYDB_COUNT = "EASYDB_COUNT"; private static OracleSqlConstructor instance = new OracleSqlConstructor(); private OracleSqlConstructor() { } public static OracleSqlConstructor getInstance() { return instance; } public SqlParamIndexer buildInsert(EntityParser entityParser) throws IllegalParamException { StringBuffer forePart = new StringBuffer();// the fore part of the sql StringBuffer backPart = new StringBuffer();// the back part of the sql // 等待更新的属性 HashMap<String, FieldExp> fieldExpMap = entityParser.getFieldExpMap(); // 非置空的大字段属性 HashSet<String> bigFieldNameSet = entityParser.getBigFieldNameSet(); // 按'?'在values子句中的先后顺序存储对应属性名 Vector<String> valuesParamVec = new Vector<String>(10); boolean hasValue = false; for (Iterator<String> it = fieldExpMap.keySet().iterator(); it.hasNext(); ) { String fieldName = it.next(); String columnName = MappingUtil.getColumnName(fieldName); forePart.append(columnName + ','); // 如果此属性是非置空的文件类型 if (bigFieldNameSet.contains(fieldName)) { FieldExp fieldExp = (FieldExp) fieldExpMap.get(fieldName); UpdateIdentifier idFieldValue = (UpdateIdentifier) fieldExp.getFieldValue(); // 对于BLOB/CLOB类型的字段, 写入前需要对其初始化 if (idFieldValue instanceof EBinFile) { backPart.append("EMPTY_BLOB(),"); } else if (idFieldValue instanceof ETxtFile) { backPart.append("EMPTY_CLOB(),"); } } else { backPart.append("?,"); valuesParamVec.add(fieldName); } hasValue = true; } if (hasValue) { forePart.deleteCharAt(forePart.length() - 1); backPart.deleteCharAt(backPart.length() - 1); } else { throw new IllegalParamException(IllegalParamException.ENTITY_NOVALUE, ""); } forePart.insert(0, "INSERT INTO " + MappingUtil.getTableName(entityParser.getClassName()) + " ("); forePart.append(") "); backPart.insert(0, "VALUES ("); backPart.append(") "); String sql = forePart.append(backPart).toString(); return new SqlParamIndexer(sql, valuesParamVec); } public SqlParamIndexer buildUpdateByPk(EntityParser entityParser) throws IllegalParamException, IllegalEntityException { // update子句 StringBuffer update = new StringBuffer("UPDATE "); update.append(MappingUtil.getTableName(entityParser.getClassName())); update.append(" SET "); // where子句 StringBuffer where = new StringBuffer(" WHERE 1=1"); // 等待更新的属性 HashMap<String, FieldExp> fieldExpMap = entityParser.getFieldExpMap(); // 主键属性 HashSet<String> pkSet = entityParser.getPKSet(); if (pkSet.isEmpty()) { throw new IllegalEntityException(IllegalEntityException.NOT_SPECIFY_PK, ""); } // 非置空的大字段属性 HashSet<String> bigFieldNameSet = entityParser.getBigFieldNameSet(); // 按'?'在SQL中的先后顺序存储对应属性名 Vector<String> indexedParamVec = new Vector<String>(12); boolean hasUpdateValue = false; for (Iterator<String> it = fieldExpMap.keySet().iterator(); it.hasNext(); ) { String fieldName = (String) it.next(); String columnName = MappingUtil.getColumnName(fieldName); // 如果不是主键属性 if (!pkSet.contains(fieldName)) { update.append(columnName); // 如果此属性是非置空的文件类型, 则初始化 if (bigFieldNameSet.contains(fieldName)) { FieldExp fieldExp = (FieldExp) fieldExpMap.get(fieldName); UpdateIdentifier idFieldValue = (UpdateIdentifier) fieldExp.getFieldValue(); // 对于BLOB/CLOB类型的字段, 写入前需要对其初始化 if (idFieldValue instanceof EBinFile) { update.append("=EMPTY_BLOB(),"); } else if (idFieldValue instanceof ETxtFile) { update.append("=EMPTY_CLOB(),"); } } else { update.append("=?,"); indexedParamVec.add(fieldName); } hasUpdateValue = true; } } // 没有要更新的属性 if (!hasUpdateValue) { throw new IllegalParamException(IllegalParamException.ENTITY_NOVALUE, ""); } // 删除最后的',' update.deleteCharAt(update.length() - 1); // 以主键为更新条件 boolean hasPkValue = false; for (Iterator<String> it = pkSet.iterator(); it.hasNext(); ) { String fieldName = (String) it.next(); String columnName = MappingUtil.getColumnName(fieldName); where.append(" AND "); where.append(columnName); where.append("=? "); indexedParamVec.add(fieldName); hasPkValue = true; } // 没有找到主键值 if (!hasPkValue) { throw new IllegalParamException(IllegalParamException.NOVALUE_FOR_ENTITY_PK, ""); } // combom the where clause update.append(where.toString()); return new SqlParamIndexer(update.toString(), indexedParamVec); } public SqlParamIndexer buildUpdateByCriteria(EntityParser entityParser, Criteria criteria) throws IllegalParamException { StringBuffer sql = new StringBuffer("UPDATE "); sql.append(MappingUtil.getTableName(entityParser.getClassName())); sql.append(" SET "); // 等待更新的属性 HashMap<String, FieldExp> fieldExpMap = entityParser.getFieldExpMap(); // 非置空的大字段属性 HashSet<String> bigFieldNameSet = entityParser.getBigFieldNameSet(); // 按'?'在SQL中的先后顺序存储对应属性名 Vector<String> indexedParamVec = new Vector<String>(12); boolean hasUpdateValue = false; for (Iterator<String> it = fieldExpMap.keySet().iterator(); it.hasNext(); ) { String fieldName = (String) it.next(); String columnName = MappingUtil.getColumnName(fieldName); sql.append(columnName); // 如果此属性是非置空的文件类型 if (bigFieldNameSet.contains(fieldName)) { FieldExp fieldExp = (FieldExp) fieldExpMap.get(fieldName); UpdateIdentifier idFieldValue = (UpdateIdentifier) fieldExp.getFieldValue(); // 对于BLOB/CLOB类型的字段, 写入前需要对其初始化 if (idFieldValue instanceof EBinFile) { sql.append("=EMPTY_BLOB(),"); } else if (idFieldValue instanceof ETxtFile) { sql.append("=EMPTY_CLOB(),"); } } else { sql.append("=?,"); indexedParamVec.add(fieldName); } hasUpdateValue = true; } // 没有要更新的属性 if (!hasUpdateValue) { throw new IllegalParamException(IllegalParamException.ENTITY_NOVALUE, ""); } // 删除最后的',' sql.deleteCharAt(sql.length() - 1); // 以参数Criteria为更新条件 String c = criteria.toString().trim(); if (!"".equals(c)) { // build the where clause sql.append(" WHERE "); sql.append(criteria.toString()); } return new SqlParamIndexer(sql.toString(), indexedParamVec); } /** * Builds the pager sql by decorating the common business logic sql. * * @param originSql the common business logic sql * @param startPos starting position in searching records * @param endPos end position of in searching records * @return */ public String buildPageSql(String originSql, int startPos, int endPos) { final String select = "SELECT "; final String from = " FROM "; originSql = originSql.trim(); //替换制表符 originSql = originSql.replaceAll("\t", " "); //合并空格符 originSql = originSql.replaceAll("\\s{1,}", " "); int selectPosi = this.indexIgloreCase(originSql, select, 0, originSql.length()); int fromPosi = this.indexIgloreCase(originSql, from, 0, originSql.length()); // 取得要查询的列, 即originSql中"SELECT" 到 "FROM" 之间的字符串 String columns = originSql.substring(selectPosi + select.length(), fromPosi); // 去掉左右括号及其中间的内容, 如SELECT A.NAME, // (TO_DATE('2003-02-04','YYYY-MM-DD')-SYSDATE) EXCEED_DAY_CN columns = trimBracket(columns); // 存放转换后的查询列 StringBuffer colStr = new StringBuffer(); StringTokenizer st = new StringTokenizer(columns); // 取得各个查询列 while (st.hasMoreElements()) { String col = st.nextToken(",").trim(); // 如果该列带有表名或表的别名, 则过滤之 int dotPosi = col.indexOf('.'); if (dotPosi > 0) { col = col.substring(dotPosi + 1); } // 如果该列定义了别名, 则取别名作为列名 int asPosi = col.lastIndexOf(' '); if (asPosi > 0) { col = col.substring(asPosi + 1).trim(); } colStr.append(EASYDB_A).append('.').append(col).append(','); } colStr.deleteCharAt(colStr.length() - 1); // 构造分页SQL StringBuffer pagerSql = new StringBuffer("SELECT ").append(EASYDB_B).append(".*"); pagerSql.append(" FROM ( SELECT "); pagerSql.append(colStr.toString()); pagerSql.append(", ROWNUM "); pagerSql.append(EASYDB_PAGER_ROW); pagerSql.append(" FROM (").append(originSql).append(") "); pagerSql.append(EASYDB_A); pagerSql.append(" WHERE ROWNUM < ").append(endPos); pagerSql.append(" ) ").append(EASYDB_B); pagerSql.append(" WHERE "); pagerSql.append(EASYDB_B).append('.').append(EASYDB_PAGER_ROW); pagerSql.append(" >= ").append(startPos); colStr.delete(0, colStr.length()); return pagerSql.toString(); } /** * Builds the sql for retrieveing the column meta of the table. * * @param tableName * @return the sql */ public String buildGettingMetaSql(String tableName) { StringBuffer sql = new StringBuffer("SELECT * FROM "); sql.append(tableName); sql.append(" A WHERE 1 = 2"); return sql.toString(); } /** * Builds the sql which calculate the total records of pager query. * * @param originSql the common business logic sql * @return */ public String buildCountSql(String originSql) { final String orderBy = " ORDER BY "; originSql = originSql.trim(); //替换制表符 originSql = originSql.replaceAll("\t", " "); //合并空格符 originSql = originSql.replaceAll("\\s{1,}", " "); // 去掉ORDER BY 子句 int orderPosi = originSql.toUpperCase().indexOf(orderBy); if (orderPosi > 0) { originSql = originSql.substring(0, orderPosi); } StringBuffer countSql = new StringBuffer("SELECT COUNT(*) FROM ("); countSql.append(originSql); countSql.append(") ").append(EASYDB_COUNT); return countSql.toString(); } // 忽略大小写, 检索baseStr中从位置startPos至endPos的子串, 看是否存在子串indexedStr. 返回第一次匹配的位置. private int indexIgloreCase(String baseStr, String indexedStr, int startPos, int endPos) { int baseLength = baseStr.length(); int indexedLength = indexedStr.length(); for (int i = startPos; i < (baseLength - indexedLength) && i < endPos; i++) { if (indexedStr.equalsIgnoreCase(baseStr.substring(i, i + indexedLength))) { return i; } } return -1; } /** * 去掉左右括号中间的字符 * * @param colstr 左右括号必须成对出现的字符串 */ private String trimBracket(String colstr) { String str = colstr.trim(); int i = str.indexOf("("); if (i < 0) { return str; } StringBuffer buff = new StringBuffer(str); buff.deleteCharAt(i);// 删除出现的第一个'(', 此时i指向'('后面的那个字符 int leftCnt = 1;// 出现的左括号数 int rightCnt = 0;// 出现的右括号数 while (i < buff.length() && rightCnt < leftCnt) { char ch = buff.charAt(i); buff.deleteCharAt(i); if (ch == '(') { leftCnt++; } if (ch == ')') { rightCnt++; } } String s = buff.toString(); buff.delete(0, s.length()); return trimBracket(s); } public static void main(String[] arsg) { OracleSqlConstructor osc = new OracleSqlConstructor(); StringBuffer sql = new StringBuffer(); sql.append(" SELECT L.CREATE_USER,K.KIND_DESC FEE_KIND,W.OPERATOR_NAME "); sql.append(" ,(SUM(L.CHARGED_PAGES)) FREE_PAGES,SUM(L.CHARGED_FEE) CHARGED_FEE "); sql.append(" FROM FEE_LOG L,FEE_KIND K,WORK_CARD W "); sql.append(" WHERE L.FEE_KIND = K.KIND AND K.TC = ? AND L.CREATE_USER = W.CARD_CODE"); String a = osc.buildPageSql(sql.toString(), 1, 11); System.out.println(a); } }