JDBC的一些通用封装+动态代理做缓存存取(自动解析返回的数据装载成实体类)
2018-01-15 14:48
465 查看
最近一个项目要用微服务改造,但是已有SQL很复杂感觉不适合用JPA,于是自己封装了下JDBC,以下代码也算是做下笔记吧。
PS:由于没有分页查询的需求所以没做分页功能。
public interface BaseDao {
public <T> List<T> find(String sql,Class<T> clazz, Object... params);
/**
* @Title: find
* @Description: TODO(查询,参数是数组)
* @param @param sql
* @param @param clazz
* @param @param params
* @param @return
* @return T 返回类型
* @date 2017年12月5日
*/
public <T> List<T> find(String sql,Class<T> clazz, List<?> params);
/**
* @Title: getProxy
* @Description: TODO(获得BaseDao的代理对象)
* @param @param clazz 查询返回结果对象的类型
* @param @return
* @return BaseDao 返回代理对象BaseDao
* @date 2017年12月1日
*/
public <T> BaseDao getProxy(Class<T> clazz);
public boolean insert(String sql, Object... params);
public boolean insert(String sql, List<?> params);
public boolean update(String sql,Object... params);
public <T> T find(String sql,Class<T> clazz, Object params);
}basedao 实现类:
@Component
public class BaseDaoImpl implements BaseDao{
@Autowired
private Dialect dialect;
@Autowired
private DataSource ds;
@Autowired
ICtgCacheManager cache;
public boolean insert(String sql, Object... params){
return excuteUpdate(sql,params)>0?true:false;
}
public boolean insert(String sql, List<?> params){
return excuteUpdate(sql,params)>0?true:false;
}
public boolean update(String sql,Object... params){
return excuteUpdate(sql,params)>0?true:false;
}
public <T> T find(String sql,Class<T> clazz, Object params){
List<T> list = excuteQuery(sql,clazz,params);
if(list!=null&&list.size()>0){
return list.get(0);
}
return null;
}
public <T> List<T> find(String sql,Class<T> clazz, Object... params) {
return excuteQuery(sql,clazz,params);
}
public <T> List<T> find(String sql,Class<T> clazz,List<?> params) {
return excuteQuery(sql,clazz,params);
}
private <T> int excuteUpdate(String sql,Object... params){
Connection conn = null;
try {
conn = ds.getConnection();
PaasLogger.info("Excute Sql:{}", sql);
PreparedStatement pst = conn.prepareStatement(sql);
prepareValue(pst, params);
return pst.executeUpdate();
} catch (SQLException e) {
PaasLogger.error("操作数据库出错!{}", e.getMessage());
e.printStackTrace();
return -1;
}finally {
closeConnection(conn);
}
}
private <T> int excuteUpdate(String sql,List<?> params){
Connection conn = null;
try {
conn = ds.getConnection();
PaasLogger.info("Excute Sql:{}", sql);
PreparedStatement pst = conn.prepareStatement(sql);
prepareValue(pst, params);
return pst.executeUpdate();
} catch (SQLException e) {
PaasLogger.error("操作数据库出错!{}", e.getMessage());
e.printStackTrace();
return -1;
}finally {
closeConnection(conn);
}
}
private <T> List<T> excuteQuery(String sql,Class<T> clazz, Object... params){
Connection conn = null;
try {
conn = ds.getConnection();
PaasLogger.info("Excute Sql:{}", sql);
PreparedStatement pst = conn.prepareStatement(sql);
prepareValue(pst, params);
ResultSet rs = pst.executeQuery();
return mapRersultSetToObject(rs,clazz);
} catch (SQLException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
PaasLogger.error("查询数据库出错!{}", e.getMessage());
e.printStackTrace();
return null;
}finally {
closeConnection(conn);
}
}
private <T> List<T> excuteQuery(String sql,Class<T> clazz, List<?> params){
Connection conn = null;
try {
conn = ds.getConnection();
PaasLogger.info("Excute Sql:{}", sql);
PreparedStatement pst = conn.prepareStatement(sql);
prepareValue(pst, params);
ResultSet rs = pst.executeQuery();
return mapRersultSetToObject(rs,clazz);
} catch (SQLException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
PaasLogger.error("查询数据库出错!{}", e.getMessage());
e.printStackTrace();
return null;
}finally {
closeConnection(conn);
}
}
private void closeConnection(Connection conn){
try {
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
private void prepareValue(PreparedStatement pst,List<?> params) throws SQLException {
int index = 1;
for (Object param : params) {
if(param!=null&&!param.equals("")){
dialect.setValue(pst, param, index);
index++;
}
}
}
private void prepareValue(PreparedStatement pst, Object... params) throws SQLException {
int index = 1;
for (Object param : params) {
if(param!=null&&!param.equals("")){
dialect.setValue(pst, param, index);
index++;
}
}
}
public <T> List<T> mapRersultSetToObject(ResultSet rs, Class<T> outputClass) throws SQLException, InstantiationException, IllegalAccessException, InvocationTargetException {
List<T> outputList = null;
// make sure resultset is not null
if (rs != null) {
// get the resultset metadata
ResultSetMetaData rsmd = rs.getMetaData();
// get all the attributes of outputClass
Field[] fields = outputClass.getDeclaredFields();
while (rs.next()) {
T bean = (T) outputClass.newInstance();
for (int _iterator = 0; _iterator < rsmd.getColumnCount(); _iterator++) {
//优先获取别名
String columnName = rsmd.getColumnLabel(_iterator + 1);
if(columnName==null||columnName.trim().equals("")){
columnName = rsmd.getColumnName(_iterator + 1);
}
// reading the value of the SQL column
Object columnValue = rs.getObject(_iterator + 1);
for (Field field : fields) {
if(!field.getName().equalsIgnoreCase(columnName))
columnName = camelName(columnName);
if (field.getName().equalsIgnoreCase(columnName) && columnValue != null) {
BeanUtils.setProperty(bean, field.getName(), columnValue);
break;
}
}
}
if (outputList == null) {
outputList = new ArrayList<T>();
}
outputList.add(bean);
}
} else {
return null;
}
return outputList;
}
private String camelName(String name) {
StringBuilder result = new StringBuilder();
// 快速检查
if (name == null || name.isEmpty()) {
// 没必要转换
return "";
} else if (!name.contains("_")) {
// 不含下划线,仅将首字母小写
return name.substring(0, 1).toLowerCase() + name.substring(1);
}
// 用下划线将原始字符串分割
String camels[] = name.split("_");
for (String camel : camels) {
// 跳过原始字符串中开头、结尾的下换线或双重下划线
if (camel.isEmpty()) {
continue;
}
// 处理真正的驼峰片段
if (result.length() == 0) {
// 第一个驼峰片段,全部字母都小写
result.append(camel.toLowerCase());
} else {
// 其他的驼峰片段,首字母大写
result.append(camel.substring(0, 1).toUpperCase());
result.append(camel.substring(1).toLowerCase());
}
}
return result.toString();
}
public <T> BaseDao getProxy(Class<T> clazz) {
InvocationHandler invocationHandler = new MyInvocationHandler(this,cache,clazz);
return (BaseDao)Proxy.newProxyInstance(this.getClass().getClassLoader(),
this.getClass().getInterfaces(), invocationHandler);
}
上面的dataSource是spring注入的,JDBC连接框架是已经配置好了的。
public class BaseService {
@Autowired
private BaseDao baseDao;
@InitBinder
protected void initBinder(WebDataBinder binder) {
//解除spring mvc list参数限制长度问题
//binder.setAutoGrowCollectionLimit(1024);
binder.registerCustomEditor(Date.class,
new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
public <T> List<T> findList(String sql, Class<T> clazz, Object... params) {
return baseDao.getProxy(clazz).find(sql, clazz, params);
}
public <T> List<T> findList(String sql, Class<T> clazz,List<?> params) {
return baseDao.getProxy(clazz).find(sql, clazz, params);
}
public <T> T find(String sql, Class<T> clazz, Object params) {
return baseDao.getProxy(clazz).find(sql, clazz, params);
}
public boolean insert(String sql){
return baseDao.insert(sql);
}
public boolean insert(String sql,Object...params){
return baseDao.insert(sql,params);
}
public boolean insert(String sql,List<?> params){
return baseDao.insert(sql,params);
}
public boolean update(String sql,Object... params){
return baseDao.update(sql, params);
}以上查询方法都是先拿代理对象再调用JDBC方法,为的是走缓存,而增删是直接调用。
下面两个类是BaseDao需要用到的实体类
public class ColumnInfo {
private String name;
private int idx;
private int type;
public ColumnInfo(String name, int idx, int type) {
super();
this.name = name;
this.idx = idx;
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIdx() {
return idx;
}
public void setIdx(int idx) {
this.idx = idx;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public class MyInvocationHandler implements InvocationHandler {
private Object target;
private ICtgCacheManager cache;
private Class<?> clazz;
public MyInvocationHandler(Object target,ICtgCacheManager cache,Class<?> clazz) {
super();
this.target = target;
this.cache=cache;
this.clazz=clazz;
}
@Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
//如果是获取代理类则直接执行
if(!"getProxy".equals(method.getName())){
StringBuffer sb = new StringBuffer();
//解析参数拼装成key
for (Object p : args) {
if(p instanceof Object[]){
Object[] params = (Object[]) p;
for (Object string : params) {
if(string instanceof String){
sb.append("#{");
sb.append(string);
sb.append("}");
}
}
}else{
sb.append(p);
}
}
String key = MD5.encode(sb.toString());
String cacheResult = cache.get(key);
Object result=null;
if(cacheResult==null||cacheResult.trim().equals("")){
result = method.invoke(target, args);
if(result!=null){
cache.set(key,JSON.toJSONString(result));
}
}else{
try {
result = JSON.parseObject(cacheResult, clazz);
} catch (Exception e) {
try {
result = JSON.parseArray(cacheResult,clazz);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
return result;
}else{
Object result = method.invoke(target, args);
return result;
}
}
} 上面是将JSON和实体对象之间互转,应该还有其他更高效的转换方法。
最后控制器直接继承base service 然后this.findxxx
PS:由于没有分页查询的需求所以没做分页功能。
public interface BaseDao {
public <T> List<T> find(String sql,Class<T> clazz, Object... params);
/**
* @Title: find
* @Description: TODO(查询,参数是数组)
* @param @param sql
* @param @param clazz
* @param @param params
* @param @return
* @return T 返回类型
* @date 2017年12月5日
*/
public <T> List<T> find(String sql,Class<T> clazz, List<?> params);
/**
* @Title: getProxy
* @Description: TODO(获得BaseDao的代理对象)
* @param @param clazz 查询返回结果对象的类型
* @param @return
* @return BaseDao 返回代理对象BaseDao
* @date 2017年12月1日
*/
public <T> BaseDao getProxy(Class<T> clazz);
public boolean insert(String sql, Object... params);
public boolean insert(String sql, List<?> params);
public boolean update(String sql,Object... params);
public <T> T find(String sql,Class<T> clazz, Object params);
}basedao 实现类:
@Component
public class BaseDaoImpl implements BaseDao{
@Autowired
private Dialect dialect;
@Autowired
private DataSource ds;
@Autowired
ICtgCacheManager cache;
public boolean insert(String sql, Object... params){
return excuteUpdate(sql,params)>0?true:false;
}
public boolean insert(String sql, List<?> params){
return excuteUpdate(sql,params)>0?true:false;
}
public boolean update(String sql,Object... params){
return excuteUpdate(sql,params)>0?true:false;
}
public <T> T find(String sql,Class<T> clazz, Object params){
List<T> list = excuteQuery(sql,clazz,params);
if(list!=null&&list.size()>0){
return list.get(0);
}
return null;
}
public <T> List<T> find(String sql,Class<T> clazz, Object... params) {
return excuteQuery(sql,clazz,params);
}
public <T> List<T> find(String sql,Class<T> clazz,List<?> params) {
return excuteQuery(sql,clazz,params);
}
private <T> int excuteUpdate(String sql,Object... params){
Connection conn = null;
try {
conn = ds.getConnection();
PaasLogger.info("Excute Sql:{}", sql);
PreparedStatement pst = conn.prepareStatement(sql);
prepareValue(pst, params);
return pst.executeUpdate();
} catch (SQLException e) {
PaasLogger.error("操作数据库出错!{}", e.getMessage());
e.printStackTrace();
return -1;
}finally {
closeConnection(conn);
}
}
private <T> int excuteUpdate(String sql,List<?> params){
Connection conn = null;
try {
conn = ds.getConnection();
PaasLogger.info("Excute Sql:{}", sql);
PreparedStatement pst = conn.prepareStatement(sql);
prepareValue(pst, params);
return pst.executeUpdate();
} catch (SQLException e) {
PaasLogger.error("操作数据库出错!{}", e.getMessage());
e.printStackTrace();
return -1;
}finally {
closeConnection(conn);
}
}
private <T> List<T> excuteQuery(String sql,Class<T> clazz, Object... params){
Connection conn = null;
try {
conn = ds.getConnection();
PaasLogger.info("Excute Sql:{}", sql);
PreparedStatement pst = conn.prepareStatement(sql);
prepareValue(pst, params);
ResultSet rs = pst.executeQuery();
return mapRersultSetToObject(rs,clazz);
} catch (SQLException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
PaasLogger.error("查询数据库出错!{}", e.getMessage());
e.printStackTrace();
return null;
}finally {
closeConnection(conn);
}
}
private <T> List<T> excuteQuery(String sql,Class<T> clazz, List<?> params){
Connection conn = null;
try {
conn = ds.getConnection();
PaasLogger.info("Excute Sql:{}", sql);
PreparedStatement pst = conn.prepareStatement(sql);
prepareValue(pst, params);
ResultSet rs = pst.executeQuery();
return mapRersultSetToObject(rs,clazz);
} catch (SQLException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
PaasLogger.error("查询数据库出错!{}", e.getMessage());
e.printStackTrace();
return null;
}finally {
closeConnection(conn);
}
}
private void closeConnection(Connection conn){
try {
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
private void prepareValue(PreparedStatement pst,List<?> params) throws SQLException {
int index = 1;
for (Object param : params) {
if(param!=null&&!param.equals("")){
dialect.setValue(pst, param, index);
index++;
}
}
}
private void prepareValue(PreparedStatement pst, Object... params) throws SQLException {
int index = 1;
for (Object param : params) {
if(param!=null&&!param.equals("")){
dialect.setValue(pst, param, index);
index++;
}
}
}
public <T> List<T> mapRersultSetToObject(ResultSet rs, Class<T> outputClass) throws SQLException, InstantiationException, IllegalAccessException, InvocationTargetException {
List<T> outputList = null;
// make sure resultset is not null
if (rs != null) {
// get the resultset metadata
ResultSetMetaData rsmd = rs.getMetaData();
// get all the attributes of outputClass
Field[] fields = outputClass.getDeclaredFields();
while (rs.next()) {
T bean = (T) outputClass.newInstance();
for (int _iterator = 0; _iterator < rsmd.getColumnCount(); _iterator++) {
//优先获取别名
String columnName = rsmd.getColumnLabel(_iterator + 1);
if(columnName==null||columnName.trim().equals("")){
columnName = rsmd.getColumnName(_iterator + 1);
}
// reading the value of the SQL column
Object columnValue = rs.getObject(_iterator + 1);
for (Field field : fields) {
if(!field.getName().equalsIgnoreCase(columnName))
columnName = camelName(columnName);
if (field.getName().equalsIgnoreCase(columnName) && columnValue != null) {
BeanUtils.setProperty(bean, field.getName(), columnValue);
break;
}
}
}
if (outputList == null) {
outputList = new ArrayList<T>();
}
outputList.add(bean);
}
} else {
return null;
}
return outputList;
}
private String camelName(String name) {
StringBuilder result = new StringBuilder();
// 快速检查
if (name == null || name.isEmpty()) {
// 没必要转换
return "";
} else if (!name.contains("_")) {
// 不含下划线,仅将首字母小写
return name.substring(0, 1).toLowerCase() + name.substring(1);
}
// 用下划线将原始字符串分割
String camels[] = name.split("_");
for (String camel : camels) {
// 跳过原始字符串中开头、结尾的下换线或双重下划线
if (camel.isEmpty()) {
continue;
}
// 处理真正的驼峰片段
if (result.length() == 0) {
// 第一个驼峰片段,全部字母都小写
result.append(camel.toLowerCase());
} else {
// 其他的驼峰片段,首字母大写
result.append(camel.substring(0, 1).toUpperCase());
result.append(camel.substring(1).toLowerCase());
}
}
return result.toString();
}
public <T> BaseDao getProxy(Class<T> clazz) {
InvocationHandler invocationHandler = new MyInvocationHandler(this,cache,clazz);
return (BaseDao)Proxy.newProxyInstance(this.getClass().getClassLoader(),
this.getClass().getInterfaces(), invocationHandler);
}
上面的dataSource是spring注入的,JDBC连接框架是已经配置好了的。
public class BaseService {
@Autowired
private BaseDao baseDao;
@InitBinder
protected void initBinder(WebDataBinder binder) {
//解除spring mvc list参数限制长度问题
//binder.setAutoGrowCollectionLimit(1024);
binder.registerCustomEditor(Date.class,
new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
public <T> List<T> findList(String sql, Class<T> clazz, Object... params) {
return baseDao.getProxy(clazz).find(sql, clazz, params);
}
public <T> List<T> findList(String sql, Class<T> clazz,List<?> params) {
return baseDao.getProxy(clazz).find(sql, clazz, params);
}
public <T> T find(String sql, Class<T> clazz, Object params) {
return baseDao.getProxy(clazz).find(sql, clazz, params);
}
public boolean insert(String sql){
return baseDao.insert(sql);
}
public boolean insert(String sql,Object...params){
return baseDao.insert(sql,params);
}
public boolean insert(String sql,List<?> params){
return baseDao.insert(sql,params);
}
public boolean update(String sql,Object... params){
return baseDao.update(sql, params);
}以上查询方法都是先拿代理对象再调用JDBC方法,为的是走缓存,而增删是直接调用。
下面两个类是BaseDao需要用到的实体类
public class ColumnInfo {
private String name;
private int idx;
private int type;
public ColumnInfo(String name, int idx, int type) {
super();
this.name = name;
this.idx = idx;
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIdx() {
return idx;
}
public void setIdx(int idx) {
this.idx = idx;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
@Component public class Dialect { @SuppressWarnings("unchecked") public void fillStatement(PreparedStatement pst, Object... paras) throws SQLException { if (paras.length > 0) { Object value = paras[0]; if (value instanceof Collection) { fillStatementArray(pst, ((Collection<Object>) value).toArray()); } else { fillStatementArray(pst, paras); } } } private void fillStatementArray(PreparedStatement pst, Object[] paras) throws SQLException { for (int i = 0, length = paras.length; i < length;) { Object value = paras[i++]; setValue(pst, value, i); } } // private void fillStatementList(PreparedStatement pst, List<Object> paras) throws SQLException { // for (int i = 0, size = paras.size(); i < size;) { // Object value = paras.get(i++); // setValue(pst, value, i); // } // } public void setValue(PreparedStatement stmt, Object value, int index) throws SQLException { if (value == null) { stmt.setObject(index, null); } else if (String.class.equals(value.getClass())) { stmt.setString(index, (String) value); } else if (Integer.class.equals(value.getClass())) { stmt.setInt(index, (Integer) value); } else if (Long.class.equals(value.getClass())) { stmt.setLong(index, (Long) value); } else if (Double.class.equals(value.getClass())) { stmt.setDouble(index, (Double) value); } else if (Float.class.equals(value.getClass())) { stmt.setFloat(index, (Float) value); } else if (value instanceof Calendar) { long inMillis = ((Calendar) value).getTimeInMillis(); stmt.setTimestamp(index, new Timestamp(inMillis)); } else if (value instanceof Date) { long time = ((Date) value).getTime(); stmt.setTimestamp(index, new Timestamp(time)); } else if (value instanceof java.util.Date) { long time = ((java.util.Date) value).getTime(); stmt.setTimestamp(index, new Timestamp(time)); } else if (Boolean.class.equals(value.getClass())) { stmt.setBoolean(index, (Boolean) value); } else if (Byte.class.equals(value.getClass())) { stmt.setByte(index, (Byte) value); } else if (Short.class.equals(value.getClass())) { stmt.setShort(index, (Short) value); } else if (Character.class.equals(value.getClass())) { stmt.setString(index, value.toString()); } else if (BigDecimal.class.equals(value.getClass())) { stmt.setBigDecimal(index, (BigDecimal) value); } else { stmt.setObject(index, value); } } public String buildCountSql(String sql) { sql = sql.replaceAll("(\\s)+", " ").toLowerCase(); sql = replaceFormatSqlOrderBy(sql); if (sql.indexOf("distinct") > -1) { return new StringBuilder(sql.length() + 24).append("select count(*) cnt from ( ").append(sql).append(" ) temp_ ").toString(); } else { int index = sql.lastIndexOf("from"); if (index != -1) { String subSql = sql.substring(index); return new StringBuilder(subSql.length() + 24).append("select count(*) cnt ").append(subSql).toString(); } } return sql; } public Object convertValue(ColumnInfo info, ResultSet rs, Type javaType) throws SQLException, IOException { Object value = null; int type = info.getType(); int idx = info.getIdx(); switch (type) { case Types.CHAR: String str = rs.getString(idx); value = StringUtil.empty(str) ? str : ConverterUtil.string2Other(str, javaType); break; case Types.VARCHAR: str = rs.getString(idx); value = StringUtil.empty(str) ? str : ConverterUtil.string2Other(str, javaType); break; case Types.LONGVARCHAR: str = rs.getString(idx); value = StringUtil.empty(str) ? str : ConverterUtil.string2Other(str, javaType); break; case Types.NUMERIC: BigDecimal bd = rs.getBigDecimal(idx); if (bd != null) { value = ConverterUtil.bigDecimal2Other(bd, javaType); } break; case Types.DECIMAL: bd = rs.getBigDecimal(idx); if (bd != null) { value = ConverterUtil.bigDecimal2Other(bd, javaType); } break; case Types.BIT: if (Boolean.class == javaType || boolean.class == javaType) { value = rs.getBoolean(idx); break; } str = rs.getString(idx); value = StringUtil.empty(str) ? str : ConverterUtil.string2Other(str, javaType); break; case Types.TINYINT: value = rs.getByte(idx); break; case Types.SMALLINT: Short s = rs.getShort(idx); if (s != null) { value = ConverterUtil.bigDecimal2Other(new BigDecimal(s), javaType); } break; case Types.INTEGER: Integer i = rs.getInt(idx); if (i != null) { value = ConverterUtil.bigDecimal2Other(new BigDecimal(i), javaType); } break; case Types.BIGINT: Long l = rs.getLong(idx); if (l != null) { value = ConverterUtil.bigDecimal2Other(new BigDecimal(l), javaType); } break; case Types.REAL: value = rs.getFloat(idx); break; case Types.FLOAT: Double d = rs.getDouble(idx); if (d != null) { value = ConverterUtil.double2Other(d, javaType); } break; case Types.DOUBLE: d = rs.getDouble(idx); if (d != null) { value = ConverterUtil.double2Other(d, javaType); } break; case Types.BINARY: byte[] bytes = rs.getBytes(idx); if (bytes != null) { value = ConverterUtil.bytes2Other(bytes, javaType); } break; case Types.VARBINARY: bytes = rs.getBytes(idx); value = ConverterUtil.bytes2Other(bytes, javaType); break; case Types.LONGVARBINARY: bytes = rs.getBytes(idx); if (bytes != null) { value = ConverterUtil.bytes2Other(bytes, javaType); } break; case Types.DATE: Date date = rs.getDate(idx); if (date != null) { value = ConverterUtil.date2Other(date, javaType); } break; case Types.TIME: Time time = rs.getTime(idx); if (time != null) { value = ConverterUtil.time2Other(time, javaType); } break; case Types.TIMESTAMP: Timestamp timestamp = rs.getTimestamp(idx); if (timestamp != null) { value = ConverterUtil.timestamp2Other(timestamp, javaType); } break; case Types.BLOB: Blob blob = rs.getBlob(idx); if (blob != null) { bytes = ConverterUtil.handleBlob(blob); value = ConverterUtil.bytes2Other(bytes, javaType); } break; case Types.CLOB: Clob clob = rs.getClob(idx); if (clob != null) { value = ConverterUtil.handleClob(clob); } break; case Types.NCLOB: clob = rs.getClob(idx); if (clob != null) { value = ConverterUtil.handleClob(clob); } break; case Types.ARRAY: value = rs.getArray(idx); break; case Types.REF: value = rs.getRef(idx); break; default: break; } return value; } // @SuppressWarnings("unchecked") // public List<Object> fillPageStatement(PreparedStatement pst, PageSql pageSql, Object... paras) throws SQLException { // List<Object> obj = null; // if (paras != null && paras.length > 0) { // Object value = paras[0]; // if (value instanceof Collection) { // obj = (List<Object>) value; // } else { // obj = new ArrayList<Object>(); // for (Object object : paras) { // obj.add(object); // } // } // obj.add(pageSql.getStart()); // obj.add(pageSql.getEnd()); // fillStatementList(pst, obj); // } else { // obj = fillStatement(pst, pageSql.getStart(), pageSql.getEnd()); // } // return obj; // } // // public Object getData(ResultSet rs, int[] types, int i) throws SQLException, IOException { // switch (types[i]) { // case Types.CHAR: // return rs.getString(i); // case Types.VARCHAR: // return rs.getString(i); // case Types.LONGVARCHAR: // return rs.getString(i); // case Types.NUMERIC: // return rs.getBigDecimal(i); // case Types.DECIMAL: // return rs.getBigDecimal(i); // case Types.BIT: // return rs.getBoolean(i); // case Types.TINYINT: // return rs.getByte(i); // case Types.SMALLINT: // return rs.getShort(i); // case Types.INTEGER: // return rs.getInt(i); // case Types.BIGINT: // return rs.getLong(i); // case Types.REAL: // return rs.getFloat(i); // case Types.FLOAT: // return rs.getDouble(i); // case Types.DOUBLE: // return rs.getDouble(i); // case Types.BINARY: // return rs.getBytes(i); // case Types.VARBINARY: // return rs.getBytes(i); // case Types.LONGVARBINARY: // return rs.getBytes(i); // case Types.DATE: // return rs.getDate(i); // case Types.TIME: // return rs.getTime(i); // case Types.TIMESTAMP: // return rs.getTimestamp(i); // case Types.BLOB: // Blob blob = rs.getBlob(i); // return blob != null ? ConverterUtil.handleBlob(blob) : null; // case Types.CLOB: // Clob clob = rs.getClob(i); // return clob != null ? ConverterUtil.handleClob(clob) : null; // case Types.NCLOB: // clob = rs.getClob(i); // return clob != null ? ConverterUtil.handleClob(clob) : null; // case Types.ARRAY: // return rs.getArray(i); // case Types.REF: // return rs.getRef(i); // default: // return null; // } // } protected String replaceFormatSqlOrderBy(String sql) { int index = sql.lastIndexOf("order by"); if (index > sql.lastIndexOf(")")) { String sql1 = sql.substring(0, index); String sql2 = sql.substring(index); sql2 = sql2 .replaceAll( "[oO][rR][dD][eE][rR] [bB][yY] [\u4e00-\u9fa5a-zA-Z0-9_.']+((\\s)+(([dD][eE][sS][cC])|([aA][sS][cC])))?(( )*,( )*[\u4e00-\u9fa5a-zA-Z0-9_.']+(( )+(([dD][eE][sS][cC])|([aA][sS][cC])))?)*", ""); return sql1 + sql2; } return sql; } }最后一个了,动态代理类:
public class MyInvocationHandler implements InvocationHandler {
private Object target;
private ICtgCacheManager cache;
private Class<?> clazz;
public MyInvocationHandler(Object target,ICtgCacheManager cache,Class<?> clazz) {
super();
this.target = target;
this.cache=cache;
this.clazz=clazz;
}
@Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
//如果是获取代理类则直接执行
if(!"getProxy".equals(method.getName())){
StringBuffer sb = new StringBuffer();
//解析参数拼装成key
for (Object p : args) {
if(p instanceof Object[]){
Object[] params = (Object[]) p;
for (Object string : params) {
if(string instanceof String){
sb.append("#{");
sb.append(string);
sb.append("}");
}
}
}else{
sb.append(p);
}
}
String key = MD5.encode(sb.toString());
String cacheResult = cache.get(key);
Object result=null;
if(cacheResult==null||cacheResult.trim().equals("")){
result = method.invoke(target, args);
if(result!=null){
cache.set(key,JSON.toJSONString(result));
}
}else{
try {
result = JSON.parseObject(cacheResult, clazz);
} catch (Exception e) {
try {
result = JSON.parseArray(cacheResult,clazz);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
return result;
}else{
Object result = method.invoke(target, args);
return result;
}
}
} 上面是将JSON和实体对象之间互转,应该还有其他更高效的转换方法。
最后控制器直接继承base service 然后this.findxxx
相关文章推荐
- [置顶] 动态grid java 后台封装json数据返回到前台解析并展示
- 关于对发送HTTP请求以及解析服务器返回的数据操作的提取到一个公共类中进行封装
- 用jdbc返回集合数据时的一些小问题
- 2018.01.10-01.12 登陆返回数据缓存以及判断自动登陆
- 【动态代理】使用动态代理解析注解原数据,获取接口信息
- 练习题——Gson解析、利用JDBC连接数据库进行数据的存取及查询等的综合
- Mybatits数据插入后自动返回主键封装到添加的对象里面
- 使用Redis缓存同步,从缓存中存取数据的一些使用
- ###Springmvc封装复杂表单数据:表单提交多个实体类的参数【对象类型参数,自动封装】name属性值不能重复。和实体类属性名一致
- Web开发——如何使JDBC插入数据的时候返回自动增长的主键值
- 网络数据解析及加载本地 缓存封装
- 支持连接池和结果集缓存的MySQL数据库JDBC通用框架的轻量级封装(二)——向上封装
- 做一些Spring AOP做过的事,封装 jdk动态代理成为一个黑盒子
- nginx 域名代理动态解析,需要一些新的模块
- 支持连接池和结果集缓存的MySQL数据库JDBC通用框架的轻量级封装(一)——粗略实现
- tomcat源码分析3—>cglib动态代理深度解析
- 禁止表单自动提示缓存数据
- jQuery使用ajax方法解析返回的json数据功能示例
- 前端工程化之动态数据代理
- 请求第三方接口返回json格式数据的解析