package net.hasor.data.jdbc.core; import java.io.StringWriter; import java.math.BigDecimal; import java.math.BigInteger; import java.sql.*; import java.util.*; /** * * @version : 2014-3-29 * @author 赵永春 (zyc@byshell.org) */ class InnerStatementSetterUtils { public static final int TYPE_UNKNOWN = Integer.MIN_VALUE; private static Map<Class<?>, Integer> javaTypeToSqlTypeMap = new HashMap<Class<?>, Integer>(32); static { /* JDBC 3.0 only - not compatible with e.g. MySQL at present*/ javaTypeToSqlTypeMap.put(boolean.class, new Integer(Types.BOOLEAN)); javaTypeToSqlTypeMap.put(Boolean.class, new Integer(Types.BOOLEAN)); // javaTypeToSqlTypeMap.put(byte.class, Types.TINYINT); javaTypeToSqlTypeMap.put(Byte.class, Types.TINYINT); javaTypeToSqlTypeMap.put(short.class, Types.SMALLINT); javaTypeToSqlTypeMap.put(Short.class, Types.SMALLINT); javaTypeToSqlTypeMap.put(int.class, Types.INTEGER); javaTypeToSqlTypeMap.put(Integer.class, Types.INTEGER); javaTypeToSqlTypeMap.put(long.class, Types.BIGINT); javaTypeToSqlTypeMap.put(Long.class, Types.BIGINT); javaTypeToSqlTypeMap.put(BigInteger.class, Types.BIGINT); javaTypeToSqlTypeMap.put(float.class, Types.FLOAT); javaTypeToSqlTypeMap.put(Float.class, Types.FLOAT); javaTypeToSqlTypeMap.put(double.class, Types.DOUBLE); javaTypeToSqlTypeMap.put(Double.class, Types.DOUBLE); javaTypeToSqlTypeMap.put(BigDecimal.class, Types.DECIMAL); javaTypeToSqlTypeMap.put(java.sql.Date.class, Types.DATE); javaTypeToSqlTypeMap.put(java.sql.Time.class, Types.TIME); javaTypeToSqlTypeMap.put(java.sql.Timestamp.class, Types.TIMESTAMP); javaTypeToSqlTypeMap.put(Blob.class, Types.BLOB); javaTypeToSqlTypeMap.put(Clob.class, Types.CLOB); } // /**根据 Java 类型Derive a default SQL type from the given Java type.*/ public static int javaTypeToSqlParameterType(final Class<?> javaType) { Integer sqlType = javaTypeToSqlTypeMap.get(javaType); if (sqlType != null) { return sqlType; } if (Number.class.isAssignableFrom(javaType)) { return Types.NUMERIC; } if (isStringValue(javaType)) { return Types.VARCHAR; } if (isDateValue(javaType) || Calendar.class.isAssignableFrom(javaType)) { return Types.TIMESTAMP; } return TYPE_UNKNOWN; } /***/ public static void setParameterValue(final PreparedStatement ps, final int parameterPosition, final Object inValue) throws SQLException { if (inValue == null) { ps.setObject(parameterPosition, null); } else { setValue(ps, parameterPosition, inValue); } } private static void setValue(final PreparedStatement ps, final int paramIndex, final Object inValue) throws SQLException { int sqlType = javaTypeToSqlParameterType(inValue.getClass()); if (sqlType == Types.VARCHAR || sqlType == Types.LONGVARCHAR || sqlType == Types.CLOB && isStringValue(inValue.getClass())) { //字符 ps.setString(paramIndex, inValue.toString()); } else if (sqlType == Types.DECIMAL || sqlType == Types.NUMERIC) { //数字 if (inValue instanceof BigDecimal) { ps.setBigDecimal(paramIndex, (BigDecimal) inValue); } else { ps.setObject(paramIndex, inValue, sqlType); } } else if (sqlType == Types.DATE) { //日期 if (inValue instanceof java.util.Date) { /*时间*/ if (inValue instanceof java.sql.Date) { ps.setDate(paramIndex, (java.sql.Date) inValue); } else { ps.setDate(paramIndex, new java.sql.Date(((java.util.Date) inValue).getTime())); } } else if (inValue instanceof Calendar) { /*日历*/ Calendar cal = (Calendar) inValue; ps.setDate(paramIndex, new java.sql.Date(cal.getTime().getTime()), cal); } else { /*其他*/ ps.setObject(paramIndex, inValue, Types.DATE); } } else if (sqlType == Types.TIME) { //时间 if (inValue instanceof java.util.Date) { /*SQL时间*/ if (inValue instanceof java.sql.Time) { ps.setTime(paramIndex, (java.sql.Time) inValue); } else { ps.setTime(paramIndex, new java.sql.Time(((java.util.Date) inValue).getTime())); } } else if (inValue instanceof Calendar) { /*日历*/ Calendar cal = (Calendar) inValue; ps.setTime(paramIndex, new java.sql.Time(cal.getTime().getTime()), cal); } else { /*其他*/ ps.setObject(paramIndex, inValue, Types.TIME); } } else if (sqlType == Types.TIMESTAMP) { //日期时间 if (inValue instanceof java.util.Date) { /*SQL时间戳*/ if (inValue instanceof java.sql.Timestamp) { ps.setTimestamp(paramIndex, (java.sql.Timestamp) inValue); } else { ps.setTimestamp(paramIndex, new java.sql.Timestamp(((java.util.Date) inValue).getTime())); } } else if (inValue instanceof Calendar) { /*日历*/ Calendar cal = (Calendar) inValue; ps.setTimestamp(paramIndex, new java.sql.Timestamp(cal.getTime().getTime()), cal); } else { /*其他*/ ps.setObject(paramIndex, inValue, Types.TIMESTAMP); } } else if (sqlType == TYPE_UNKNOWN) { //不确定类型 if (isStringValue(inValue.getClass())) { ps.setString(paramIndex, inValue.toString()); } else if (isDateValue(inValue.getClass())) { ps.setTimestamp(paramIndex, new java.sql.Timestamp(((java.util.Date) inValue).getTime())); } else if (inValue instanceof Calendar) { Calendar cal = (Calendar) inValue; ps.setTimestamp(paramIndex, new java.sql.Timestamp(cal.getTime().getTime()), cal); } else { ps.setObject(paramIndex, inValue);//通用的参数设置方法 } } else { //确定类型 ps.setObject(paramIndex, inValue, sqlType);//通用的参数设置方法 } } /** * Clean up all resources held by parameter values which were passed to an execute method. This is for example important for closing LOB values. * @param paramValues parameter values supplied. May be <code>null</code>. * @see DisposableSqlTypeValue#cleanup() * @see org.noe.lib.jdbcorm.jdbc.core.support.SqlLobValue#cleanup() */ public static void cleanupParameters(final Object[] paramValues) { if (paramValues != null) { cleanupParameters(Arrays.asList(paramValues)); } } /** * Clean up all resources held by parameter values which were passed to an execute method. This is for example important for closing LOB values. * @param paramValues parameter values supplied. May be <code>null</code>. * @see DisposableSqlTypeValue#cleanup() * @see org.noe.lib.jdbcorm.jdbc.core.support.SqlLobValue#cleanup() */ public static void cleanupParameters(final Collection<Object> paramValues) { if (paramValues == null) { return; } for (Object inValue : paramValues) { cleanupParameter(inValue); } } public static void cleanupParameter(final Object paramValue) { if (paramValue == null) { return; } if (paramValue instanceof ParameterDisposer) { ((ParameterDisposer) paramValue).cleanupParameters(); } } /**Check whether the given value can be treated as a String value.*/ private static boolean isStringValue(final Class<?> inValueType) { // Consider any CharSequence (including StringBuffer and StringBuilder) as a String. return CharSequence.class.isAssignableFrom(inValueType) || StringWriter.class.isAssignableFrom(inValueType); } /**Check whether the given value is a <code>java.util.Date</code>(but not one of the JDBC-specific subclasses).*/ private static boolean isDateValue(final Class<?> inValueType) { return java.util.Date.class.isAssignableFrom(inValueType) && !(java.sql.Date.class.isAssignableFrom(inValueType) || java.sql.Time.class.isAssignableFrom(inValueType) || java.sql.Timestamp.class.isAssignableFrom(inValueType)); } }