如何开发支持oracle和mssql双版本数据库的产品

咱们公司开发的产品须要支持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);

相关文章
相关标签/搜索