咱们公司开发的产品须要支持oracle和mssql两种数据库:a.使用ibatis的产品中,通常预先编写两份xml文件内容为使用不一样数据库特性的sql,而后使用ant命令build成两份;b.使用jdbcTemplate等类在代码中嵌入sql的产品中,若是使用一堆if..else会让代码显得臃肿,个人作法是面向接口编程,使用java多态的特性,引入工具类,简化代码。下面介绍第二种场景的解决办法。java
第一步,创建两份properties文件,写入键值对标记当前数据库类型,而后交由ant工具build,如/WEB-INF/classes/common.properties,写入dbtype=oracle或dbtype=mssql。sql
第二步,建立属性文件读取bean,并在Spring配置文件中引入该bean。数据库
a.属性文件读取bean:编程
public class CustomizedPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer { private static Map ctxPropertiesMap; protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException { super.processProperties(beanFactoryToProcess, props); ctxPropertiesMap = new HashMap(); for (Iterator iterator = props.keySet().iterator(); iterator.hasNext();) { String keyStr = (String) iterator.next(); String value = props.getProperty(keyStr); ctxPropertiesMap.put(keyStr, value); } } public static Object getContextProperty(String name) { return ctxPropertiesMap.get(name); } }
b.Spring配置:oracle
<bean id="propertyConfigurer" class="test.CustomizedPropertyPlaceholderConfigurer"> <property name="ignoreResourceNotFound" value="true" /> <property name="locations"> <list> <value>/WEB-INF/classes/common.properties</value> </list> </property> </bean>
第二步,建立数据库特性语法转换接口和oracle、mssql实现类。函数
a.接口类:工具
public interface ConvertTo { public String getDate(); /** * 日期转换为字符串(格式:2013-05-16 10:57:49) * @param dateColumn * @return */ public String getFormatDatetime(String dateColumn); /** * 替换空字段为指定字符 * @param column * @param replaceValue * @return */ public String getIsNULL(String column,String replaceValue); /** * 判断子串是否存在 * @param sourceString * @param targetString * @return */ public String getInstr(String sourceString, String targetString); /** * 取前n条记录 * @param sql * @param columnCount * @return */ public String getFirstServeralColumns(String sql, int columnCount); public String getFunction(String sql); public String getStrLink(); public String getFromDual(); }
b.oracle实现类:ui
public class ConvertToOracle implements ConvertTo { public String toDate(String dateText) { return "to_date( " + dateText + " , 'YYYY-MM-DD')"; } public String getFormatDatetime(String dateColumn) { return " to_char( "+dateColumn+" , 'YYYY-MM-DD hh:mm:ss')"; } /** *获取当前日期的sql串 * @return */ public String getDate(){ return " sysDate "; } public String getIsNULL(String column,String replaceValue) { return " NVL(" + column + "," + replaceValue + ") "; } /** * 判断子串是否存在 */ public String getInstr(String sourceString, String targetString) { return " INSTR("+sourceString+","+targetString+")>0 "; } /** * 取前n条记录 * @param sql * @param columnCount * @return */ public String getFirstServeralColumns(String sql, int columnCount) { if(StringUtils.isBlank(sql) && columnCount<0) { return null; } return " SELECT * FROM ("+sql+") VIVID WHERE ROWNUM<="+columnCount +" "; } /** * 返回函数 */ public String getFunction(String sql) { if(StringUtils.isBlank(sql)) { return null; } return " TABLE("+sql+") "; } public String getStrLink() { return " || "; } public String getFromDual() { return " from dual "; } }
c.mssql实现类:code
public class ConvertToSQL implements ConvertTo { public String getFormatDatetime(String dateColumn) { return " CONVERT(varchar(100), "+dateColumn+", 120)"; } /** * 获取当前日期的sql串 * * @return */ public String getDate() { return " getDate() "; } public String getIsNULL(String column, String replaceValue) { return " isNull(" + column + "," + replaceValue + ") "; } /** * 判断子串是否存在 */ public String getInstr(String sourceString, String targetString) { return " CHARINDEX("+targetString+","+sourceString+")>0 "; } /** * 取前n条记录 * @param sql * @param columnCount * @return */ public String getFirstServeralColumns(String sql, int columnCount) { if(StringUtils.isBlank(sql) && columnCount<0) { return null; } return " SELECT TOP "+columnCount+" * FROM ("+sql+") VIVID "; } /** * 返回函数 */ public String getFunction(String sql) { if(StringUtils.isBlank(sql)) { return null; } return sql; } public String getStrLink() { return " + "; } public String getFromDual() { return ""; } }
第三步,建立接口调用辅助类。orm
<!-- lang: java --> public class ConvertHelper { private static Map convertToMap; private ConvertHelper() { } private static synchronized void syncInit() { if(convertToMap==null) { convertToMap = new HashMap(); convertToMap.put("oracle", new ConvertToOracle()); convertToMap.put("mssql", new ConvertToSQL()); } } private static Map getConvertToMap() { if(convertToMap==null) { syncInit(); } return convertToMap; } public static ConvertTo getConvertTo(){ String dbtype = PropertyPlaceholderConfigurer.getProperty("dbtype"); return (ConvertTo)getConvertToMap().get(dbtype); } }
第四步,如何使用。
业务代码中获取ConvertTo对象,直接调用相关方法。如获取前5条用户数据:
ConvertTo convertTo = ConvertHelper.getConvertTo();
String mSql = getFirstServeralColumns('SELECT * FROM TEST_USERS',10);