Java tutorial
/* * Copyright 2009-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ibatis.plugin; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import org.apache.ibatis.executor.ErrorContext; import org.apache.ibatis.executor.ExecutorException; import org.apache.ibatis.io.ResolverUtil; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.ParameterMapping; import org.apache.ibatis.mapping.ParameterMode; import org.apache.ibatis.reflection.ExceptionUtil; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.property.PropertyTokenizer; import org.apache.ibatis.scripting.xmltags.ForEachSqlNode; import org.apache.ibatis.session.Configuration; import org.apache.ibatis.type.TypeHandler; import org.apache.ibatis.type.TypeHandlerRegistry; import com.lanyuan.plugin.PagePlugin; import com.lanyuan.plugin.PageView; import com.lanyuan.util.Common; import com.lanyuan.util.EhcacheUtils; /** * @author Clinton Begin */ public class Plugin implements InvocationHandler { private Object target; private Interceptor interceptor; private Map<Class<?>, Set<Method>> signatureMap; private Plugin(Object target, Interceptor interceptor, Map<Class<?>, Set<Method>> signatureMap) { this.target = target; this.interceptor = interceptor; this.signatureMap = signatureMap; } public static Object wrap(Object target, Interceptor interceptor) { Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor); Class<?> type = target.getClass(); Class<?>[] interfaces = getAllInterfaces(type, signatureMap); if (interfaces.length > 0) { return Proxy.newProxyInstance(type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap)); } return target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { Set<Method> methods = signatureMap.get(method.getDeclaringClass()); if (methods != null && methods.contains(method)) { return interceptor.intercept(new Invocation(target, method, args)); } return method.invoke(target, args); } catch (Exception e) { throw ExceptionUtil.unwrapThrowable(e); } } private static Map<Class<?>, Set<Method>> getSignatureMap(Interceptor interceptor) { Intercepts interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class); if (interceptsAnnotation == null) { // issue #251 throw new PluginException( "No @Intercepts annotation was found in interceptor " + interceptor.getClass().getName()); } Signature[] sigs = interceptsAnnotation.value(); Map<Class<?>, Set<Method>> signatureMap = new HashMap<Class<?>, Set<Method>>(); for (Signature sig : sigs) { Set<Method> methods = signatureMap.get(sig.type()); if (methods == null) { methods = new HashSet<Method>(); signatureMap.put(sig.type(), methods); } try { Method method = sig.type().getMethod(sig.method(), sig.args()); methods.add(method); } catch (NoSuchMethodException e) { throw new PluginException( "Could not find method on " + sig.type() + " named " + sig.method() + ". Cause: " + e, e); } } return signatureMap; } private static Class<?>[] getAllInterfaces(Class<?> type, Map<Class<?>, Set<Method>> signatureMap) { Set<Class<?>> interfaces = new HashSet<Class<?>>(); while (type != null) { for (Class<?> c : type.getInterfaces()) { if (signatureMap.containsKey(c)) { interfaces.add(c); } } type = type.getSuperclass(); } return interfaces.toArray(new Class<?>[interfaces.size()]); } @SuppressWarnings("unchecked") public static final String joinSql(Connection connection, MappedStatement mappedStatement, BoundSql boundSql, Map<String, Object> formMap, List<Object> formMaps) throws Exception { Object table = null; String sql = ""; Map<String, Object> mapfield = null; String field = null; if (null != formMap) { table = formMap.get("ly_table"); mapfield = (Map<String, Object>) EhcacheUtils.get(table); field = mapfield.get("field").toString(); sql = " select " + field + " from " + String.valueOf(table); } String sqlId = mappedStatement.getId(); sqlId = sqlId.substring(sqlId.lastIndexOf(".") + 1); if (Configuration.FINDBYWHERE.equals(sqlId)) { if (null != formMap.get("where") && !StringUtils.isBlank(formMap.get("where").toString())) { sql += " " + formMap.get("where").toString(); } } else if (Configuration.FINDBYPAGE.equals(sqlId)) { String[] fe = field.split(","); String param = ""; for (String string : fe) { if (formMap.containsKey(string)) { Object v = formMap.get(string); String sf = v.toString(); if (sf.indexOf("%") > -1) { param += " and " + string + " like '" + v + "'"; } else { if (sf.indexOf(",") > -1)// ? { StringBuffer sbuffer = new StringBuffer(); String[] se = sf.split(","); for (String sst : se) { if (0 >= sbuffer.length()) { sbuffer.append(" and ("); sbuffer.append(" " + string + " = '" + sst + "' "); } else { sbuffer.append(" or " + string + " = '" + sst + "' "); } } sbuffer.append(")"); param += sbuffer.toString(); } else { param += " and " + string + " = '" + v + "'"; } } } } Object where = formMap.get("where"); if (null != where) { String sf = where.toString(); if (StringUtils.isNotBlank(sf)) { if (sf.indexOf("null") == -1) { param += sf; } } } if (StringUtils.isNotBlank(param)) { param = param.substring(param.indexOf("and") + 4); sql += " where " + param; } Object by = formMap.get("orderby"); if (null != by) { sql += " " + by; } Object paging = formMap.get("paging"); if (null == paging) { throw new Exception( "findByPage?,PageView! formMap.set(\"paging\", pageView);"); } else if (StringUtils.isBlank(paging.toString())) { throw new Exception( "findByPage?,PageView! formMap.set(\"paging\", pageView);"); } PageView pageView = (PageView) paging; setPageParameter(sql, connection, mappedStatement, boundSql, pageView); sql = PagePlugin.generatePagesSql(sql, pageView); } else if (Configuration.DELETEBYNAMES.equals(sqlId)) { sql = "delete from " + table.toString() + " where "; String param = ""; for (Entry<String, Object> entry : formMap.entrySet()) { if (!"ly_table".equals(entry.getKey()) && null != entry.getValue() && !"_t".equals(entry.getKey())) param += " and " + entry.getKey() + " in (" + entry.getValue() + ")"; } if (StringUtils.isNotBlank(param)) { param = param.substring(param.indexOf("and") + 4); sql += param; } } else if (Configuration.DELETEBYATTRIBUTE.equals(sqlId)) { sql = "delete from " + table.toString() + " where " + formMap.get("key"); if (null != formMap.get("value")) { sql += " in (" + formMap.get("value") + ")"; } } else if (Configuration.FINDBYNAMES.equals(sqlId)) { String[] fe = field.split(","); String param = ""; for (String string : fe) { if (formMap.containsKey(string)) { Object v = formMap.get(string); if (v.toString().indexOf("%") > -1)// ? { param += " and " + string + " like '" + v + "'"; } else { param += " and " + string + " = '" + v + "'"; } } } if (StringUtils.isNotBlank(param)) { param = param.substring(param.indexOf("and") + 4); sql += " where " + param; } Object by = formMap.get("orderby"); if (null != by) { sql += " " + by; } } else if (Configuration.FINDBYATTRIBUTE.equals(sqlId)) { sql = "select * from " + table.toString() + " where " + formMap.get("key"); if (null != formMap.get("value") && formMap.get("value").toString().indexOf("%") > -1)// ? { sql += " LIKE '" + formMap.get("value") + "'"; } else { Object v = formMap.get("value"); sql += " in ('" + v + "')"; } } else if (Configuration.ADDENTITY.equals(sqlId)) { String[] fe = field.split(","); String fieldString = ""; String fieldValues = ""; for (String string : fe) { Object v = formMap.get(string); if (null != v) { fieldString += string + ","; fieldValues += "'" + v + "',"; } } sql = "insert into " + table.toString() + " (" + ResolverUtil.trimComma(fieldString) + ") values (" + ResolverUtil.trimComma(fieldValues) + ")"; } else if (Configuration.EDITENTITY.equals(sqlId)) { String[] fe = field.split(","); String fieldString = ""; String where = ""; for (String string : fe) { Object v = formMap.get(string); if (null != v) { String key = mapfield.get(Configuration.COLUMN_KEY).toString(); if (!StringUtils.isBlank(key)) { if (key.equals(string)) { where = "WHERE " + key + " = '" + v + "'"; } else { fieldString += string + "='" + v + "',"; } } else { throw new NullPointerException("update?!"); } } } sql = "update " + table.toString() + " set " + ResolverUtil.trimComma(fieldString) + " " + where; } else if (Configuration.FINDBYFRIST.equals(sqlId)) { sql = "select * from " + table.toString() + " where " + formMap.get("key"); if (null != formMap.get("value") && !"".equals(formMap.get("value").toString())) { sql += " = '" + formMap.get("value") + "'"; } else { throw new Exception(sqlId + " !,??"); } } else if (Configuration.BATCHSAVE.equals(sqlId)) { if (null != formMaps && formMaps.size() > 0) { table = Common.toHashMap(formMaps.get(0)).get(Configuration.LY_TABLE); mapfield = (Map<String, Object>) EhcacheUtils.get(table); field = mapfield.get(Configuration.FIELD).toString(); } sql = "insert into " + table.toString(); String fieldString = ""; String fs = ""; String fd = ""; String fieldValues = ""; String fvs = ""; for (int i = 0; i < formMaps.size(); i++) { Object object = formMaps.get(i); Map<String, Object> froMmap = (Map<String, Object>) object; String[] fe = field.split(","); for (String string : fe) { Object v = froMmap.get(string); if (null != v) { fieldString += string + ","; fieldValues += "'" + v + "',"; } } if (i == 0) { fd = fieldString; } fvs += "(" + ResolverUtil.trimComma(fieldValues) + "),"; fs += " insert into " + table.toString() + " (" + ResolverUtil.trimComma(fieldString) + ") values (" + ResolverUtil.trimComma(fieldValues) + ");"; fieldValues = ""; fieldString = ""; } String v = ResolverUtil.trimComma(fvs); sql = "insert into " + table.toString() + " (" + ResolverUtil.trimComma(fd) + ") values " + ResolverUtil.trimComma(fvs) + ""; String[] vs = v.split("\\),"); boolean b = false; for (String string : vs) { if (string.split(",").length != fd.split(",").length) { b = true; } } if (b) { sql = fs.substring(0, fs.length() - 1); } } else { throw new Exception("!"); } return sql; } /** * ??<code>PageParameter</code>,? ? * <code>PageParameter</code>? * * @param sql * @param connection * @param mappedStatement * @param boundSql * @param page * @throws SQLException */ private static void setPageParameter(String sql, Connection connection, MappedStatement mappedStatement, BoundSql boundSql, PageView pageView) throws SQLException { // PreparedStatement countStmt = null; ResultSet rs = null; try { String countSql = ""; try { countSql = "select count(1) " + suffixStr(sql); countStmt = connection.prepareStatement(countSql); BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql.toString(), boundSql.getParameterMappings(), boundSql.getParameterObject()); setParameters(countStmt, mappedStatement, countBS, boundSql.getParameterObject()); rs = countStmt.executeQuery(); } catch (Exception e) { PagePlugin.logger.info(countSql + " Sql,?Sql?!"); countSql = "select count(1) from (" + sql + ") tmp_count"; BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql.toString(), boundSql.getParameterMappings(), boundSql.getParameterObject()); setParameters(countStmt, mappedStatement, countBS, boundSql.getParameterObject()); rs = countStmt.executeQuery(); } int count = 0; if (rs.next()) { count = ((Number) rs.getObject(1)).intValue(); } pageView.setRowCount(count); } finally { try { rs.close(); } catch (Exception e) { } try { countStmt.close(); } catch (Exception e) { } } } /** * select id, articleNofrom, sum(ddd) ss, articleName, ( SELECT * loginName,sum(ddd) from oss_userinfo u where u.id=userId order by id) * loginName, (SELECT userName from oss_userinfo u where u.id=userId and * fromaa = (SELECT userName from oss_userinfo u where u.id=userId) * fromuserName, sum(ddd) ss from article,(select xxx) where = (SELECT * userName from oss_userinfo u where u.id=userId order by id desc) order by * id desc ? //sql ..from ?? aafrom fromdd */ static String source_sql = ""; public static String suffixStr(String toSql) { toSql = getStringNoBlank(toSql); if (StringUtils.isBlank(source_sql)) source_sql = toSql; toSql = toSql.toLowerCase(); int sun = toSql.indexOf(" from "); String s1 = toSql.substring(0, sun); if (s1.indexOf("( select ") > -1 || s1.indexOf("(select ") > -1) { return suffixStr(toSql.substring(sun + 5)); } else { toSql = toSql.substring(sun); source_sql = source_sql.substring(source_sql.length() - toSql.length()); int s = 0; int e = 0; String sql = source_sql.toLowerCase(); sun = sql.lastIndexOf(" order "); if (sun > -1) { String f = sql.substring(sun); if (f.lastIndexOf(")") == -1) { int a = sql.lastIndexOf(" asc"); if (a > -1) { String as = sql.substring(a + 4, a + 5); if (as.trim().isEmpty()) { s = sql.lastIndexOf(" order "); e = a + 5; } } int d = sql.lastIndexOf(" desc"); if (d > -1) { String ds = sql.substring(d + 5, d + 6); if (ds.trim().isEmpty()) { s = sql.lastIndexOf(" order "); e = d + 6; } } String ss = source_sql.substring(0, s + 1); String ee = source_sql.substring(e); source_sql = ss + ee; } } } toSql = source_sql; source_sql = ""; return toSql; } public static void main(String[] args) throws Exception { String sql = "" + " select id, articleNoorder by id desc, sum(ddd) ss, articleName, ( SELECT loginName,sum(ddd) from" + " oss_userinfo u where u.id=userId) loginName, (SELECT userName from" + " oss_userinfo u where u.id=userId and order by id descaa = (SELECT userName from" + " oss_userinfo u where u.id=userId order by id asc) userNameorder by id desc, sum(ddd) ss from article,(select xxx) where = (SELECT userName from" + " oss_userinfo u where u.id=userId order By id desc) order by f1 group by xx"; System.err.println((suffixStr(sql))); } public static String getStringNoBlank(String str) { if (str != null && !"".equals(str)) { Pattern p = Pattern.compile("\t|\r|\n"); Matcher m = p.matcher(str); String strNoBlank = m.replaceAll(" "); p = Pattern.compile("\\s+"); m = p.matcher(str); strNoBlank = m.replaceAll(" "); return strNoBlank; } else { return str; } } /** * SQL?(?),?org.apache.ibatis.executor.parameter.DefaultParameterHandler * @param ps * @param mappedStatement * @param boundSql * @param parameterObject * @throws SQLException */ @SuppressWarnings("rawtypes") public static void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject) throws SQLException { ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId()); List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); if (parameterMappings != null) { Configuration configuration = mappedStatement.getConfiguration(); TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry(); MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject); for (int i = 0; i < parameterMappings.size(); i++) { ParameterMapping parameterMapping = parameterMappings.get(i); if (parameterMapping.getMode() != ParameterMode.OUT) { Object value; String propertyName = parameterMapping.getProperty(); PropertyTokenizer prop = new PropertyTokenizer(propertyName); if (parameterObject == null) { value = null; } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { value = parameterObject; } else if (boundSql.hasAdditionalParameter(propertyName)) { value = boundSql.getAdditionalParameter(propertyName); } else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX) && boundSql.hasAdditionalParameter(prop.getName())) { value = boundSql.getAdditionalParameter(prop.getName()); if (value != null) { value = configuration.newMetaObject(value) .getValue(propertyName.substring(prop.getName().length())); } } else { value = metaObject == null ? null : metaObject.getValue(propertyName); } TypeHandler typeHandler = parameterMapping.getTypeHandler(); if (typeHandler == null) { throw new ExecutorException("There was no TypeHandler found for parameter " + propertyName + " of statement " + mappedStatement.getId()); } typeHandler.setParameter(ps, i + 1, value, parameterMapping.getJdbcType()); } } } } }