本文中mybatis的扩展主要是解决时区以及动态的设置某些参数值的问题
1,解决时区的问题
package com.herokuCenter.config.mybatis;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import org.apache.ibatis.executor.result.ResultMapException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.TypeException;
import com.herokuCenter.utils.TimeZoneUtils;
@MappedJdbcTypes(value=JdbcType.TIMESTAMP, includeNullJdbcType=true)
public class MyDateTypeHandler extends BaseTypeHandler<Date>{
@Override
public void setParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null) {
if (jdbcType == null) {
throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");
}
try {
ps.setNull(i, jdbcType.TYPE_CODE);
} catch (SQLException e) {
throw new TypeException("Error setting null for parameter #" + i + " with JdbcType " + jdbcType + " . " +
"Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. " +
"Cause: " + e, e);
}
} else {
try {
setNonNullParameter(ps, i, parameter, jdbcType);
} catch (Exception e) {
throw new TypeException("Error setting non null for parameter #" + i + " with JdbcType " + jdbcType + " . " +
"Try setting a different JdbcType for this parameter or a different configuration property. " +
"Cause: " + e, e);
}
}
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType)
throws SQLException {
//System.out.println("MyDateTypeHandler.setNonNullParameter - PreparedStatement - parameter");
//对日期进行时区转化
Date date = TimeZoneUtils.default2UTC(parameter);
ps.setTimestamp(i, new Timestamp(date.getTime()));
}
@Override
public Date getResult(ResultSet rs, String columnName) throws SQLException {
try {
return getNullableResult(rs, columnName);
} catch (Exception e) {
throw new ResultMapException("Error attempting to get column '" + columnName + "' from result set. Cause: " + e, e);
}
}
@Override
public Date getResult(ResultSet rs, int columnIndex) throws SQLException {
try {
return getNullableResult(rs, columnIndex);
} catch (Exception e) {
throw new ResultMapException("Error attempting to get column #" + columnIndex+ " from result set. Cause: " + e, e);
}
}
@Override
public Date getResult(CallableStatement cs, int columnIndex) throws SQLException {
try {
return getNullableResult(cs, columnIndex);
} catch (Exception e) {
throw new ResultMapException("Error attempting to get column #" + columnIndex+ " from callable statement. Cause: " + e, e);
}
}
@Override
public Date getNullableResult(ResultSet rs, String columnName)
throws SQLException {
//System.out.println("MyDateTypeHandler.getNullableResult - ResultSet - columnName");
Timestamp sqlTimestamp = rs.getTimestamp(columnName);
if (sqlTimestamp != null) {
return TimeZoneUtils.UTC2Default(sqlTimestamp.getTime());
}
return null;
}
@Override
public Date getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
//System.out.println("MyDateTypeHandler.getNullableResult - ResultSet - columnIndex");
Timestamp sqlTimestamp = rs.getTimestamp(columnIndex);
if (sqlTimestamp != null) {
return TimeZoneUtils.UTC2Default(sqlTimestamp.getTime());
}
return null;
}
@Override
public Date getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
//System.out.println("MyDateTypeHandler.getNullableResult - CallableStatement - columnIndex");
Timestamp sqlTimestamp = cs.getTimestamp(columnIndex);
if (sqlTimestamp != null) {
return TimeZoneUtils.UTC2Default(sqlTimestamp.getTime());
}
return null;
}
}
时区工具类
public class TimeZoneUtils {
private static TimeZone T_Z_UTC = TimeZone.getTimeZone("UTC");
private static TimeZone T_Z_DEFAULT = TimeZone.getDefault();
/**
* 将本地时区转化为UTC
*
* @param date
* @return
*/
public static Date default2UTC(Date date) {
Long targetTime = date.getTime() - T_Z_DEFAULT.getRawOffset() + T_Z_UTC.getRawOffset();
return new Date(targetTime);
}
/**
* 将本地时区转化为UTC
*
* @param time
* @return
*/
public static Date default2UTC(Long time) {
Long targetTime = time - T_Z_DEFAULT.getRawOffset() + T_Z_UTC.getRawOffset();
return new Date(targetTime);
}
/**
* 将UTC转化为本地时区
*
* @param date
* @return
*/
public static Date UTC2Default(Date date) {
Long targetTime = date.getTime() - T_Z_UTC.getRawOffset() + T_Z_DEFAULT.getRawOffset();
return new Date(targetTime);
}
/**
* 将UTC转化为本地时区
*
* @param time
* @return
*/
public static Date UTC2Default(Long time) {
Long targetTime = time - T_Z_UTC.getRawOffset() + T_Z_DEFAULT.getRawOffset();
return new Date(targetTime);
}
public static void main(String[] args) {
Date utcDate = default2UTC(new Date());
System.out.println("UTC : " + utcDate);
Date localDate = UTC2Default(utcDate.getTime());
System.out.println("Local : " + localDate);
}
}
2,解决动态数据传入
应用场景:
更新时间以及插入时间的动态设置
@Intercepts({
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
})
public class MapperInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
// 获取 SQL 命令
SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
// 获取参数
Object parameter = invocation.getArgs()[1];
if(null != parameter){
// 获取私有成员变量
Field[] declaredFields = parameter.getClass().getSuperclass().getDeclaredFields();
if(declaredFields != null && declaredFields.length > 0){
for(Field field : declaredFields){
if("createddate".equals(field.getName().toLowerCase())){
if(SqlCommandType.INSERT.equals(sqlCommandType)){
//插入时设置创建时间
field.setAccessible(true);
field.set(parameter, new Date());
}
}
if("lastmodifieddate".equals(field.getName().toLowerCase()) || "updatedate".equals(field.getName().toLowerCase())){
if(SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)){
//插入或修改时设置修改时间
field.setAccessible(true);
field.set(parameter, new Date());
}
}
}
}
}
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
}