一、前言
其实最近找工作面试,都能补缺自己好多知识点,对于源码的熟悉度,掌握程度都会有一个进步,一些问题应该怎么思考等等,这就是需要的成长。努力!!!
二、内容
离职前做了一个分表的功能,按照月分表处理埋点数据,遇到以下两个问题
1)、在分表查询数据的时候,出现异常,Unsupported Date type:class java.lang.String
2)、在分表查询跨表查的时候只查询出来一条数据
现在对这两个问题做下说明如下:
2.1、类型转换异常问题
@Override
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
try {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, params);
}
Object o = method.invoke(rs, params);
if ("next".equals(method.getName())) {
if (((Boolean) o)) {
rows++;
if (isTraceEnabled()) {
ResultSetMetaData rsmd = rs.getMetaData();
final int columnCount = rsmd.getColumnCount();
if (first) {
first = false;
printColumnHeaders(rsmd, columnCount);
}
printColumnValues(columnCount);
}
} else {
debug(" Total: " + rows, false);
}
}
clearColumnInfo();
return o;
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}
private void printColumnValues(int columnCount) {
StringBuilder row = new StringBuilder();
row.append(" Row: ");
for (int i = 1; i <= columnCount; i++) {
String colname;
try {
if (blobColumns.contains(i)) {
colname = "<>";
} else {
colname = rs.getString(i);
}
} catch (SQLException e) {
// generally can't call getString() on a BLOB column
colname = "<>";
}
row.append(colname);
if (i != columnCount) {
row.append(", ");
}
}
trace(row.toString(), false);
}
@Override
public String getString(final int columnIndex) throws SQLException {
Object result = mergeResultSet.getValue(columnIndex, String.class);
wasNull = null == result;
return (String) ResultSetUtil.convertValue(result, String.class);
}
### Cause: com.dangdang.ddframe.rdb.sharding.exception.ShardingJdbcException: Unsupported Date type:class java.lang.String
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
... 89 common frames omitted
Caused by: com.dangdang.ddframe.rdb.sharding.exception.ShardingJdbcException: Unsupported Date type:class java.lang.String
at com.dangdang.ddframe.rdb.sharding.merger.util.ResultSetUtil.convertDateValue(ResultSetUtil.java:122)
at com.dangdang.ddframe.rdb.sharding.merger.util.ResultSetUtil.convertValue(ResultSetUtil.java:56)
at com.dangdang.ddframe.rdb.sharding.jdbc.core.resultset.ShardingResultSet.getString(ShardingResultSet.java:168)
at org.apache.ibatis.logging.jdbc.ResultSetLogger.printColumnValues(ResultSetLogger.java:117)
at org.apache.ibatis.logging.jdbc.ResultSetLogger.invoke(ResultSetLogger.java:79)
at com.sun.proxy.$Proxy172.next(Unknown Source)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:345)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:322)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:295)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:192)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:64)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63)
at com.sun.proxy.$Proxy169.query(Unknown Source)
at org.apache.ibatis.executor.ReuseExecutor.doQuery(ReuseExecutor.java:60)
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324)
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148)
... 95 common frames omitted
ResultSetLogger.java ----- invoke(Object proxy,Method method,Object[] params) throws Throwable
ResultSetLogger.java ----- printColumnValues(columnCount);
ResultSetLogger.java ----- colname = rs.getString(i);
ShardingResultSet.java ----- getString(final int columnIndex);
ShardingResultSet.java ----- return (String) ResultSetUtil.convertValue(result, String.class);
ResultSetUtil.java ----- return convertDateValue(value, convertType);
ResultSetUtil.java convertDateValue(final Object value, final Class> convertType) 抛出异常
2.2、对于查询数据合并的问题
针对第二个问题,最开始思考的时候是觉得是不是sharding不支持跨库查询,因为单纯查询一张表是没问题的,所有也没办法,就是跟源码,在对于一列的时候count的时候,进行了合并操作,其实当时很纳闷,为什么,count这个字段有影响么,然后我尝试在sql里面把如下代码做了更改
原始sql:
select count,clickDate,clickName from table
修改完后
select t.count,t.clickDate,t.clickName from table t
其实就是给表加了个别名,然后也加到了字段前,这样就解决了,其实觉得很神奇,后面把这的源码那块放出来,之前忘记截图了。