終於接觸一點mybatis高階一點的用法了 真實知識是個浩瀚無垠的海洋啊
正文
今天遇到的業務場景是這樣的。兩個數據庫,主庫和從庫,希望通過springboot項目把主庫中的表結構同步到從庫中。也就是在從庫中建表,但表結構不確定。因此不能使用統一的sql語句,需要根據不同表拼接sql。
- 所以主要學習了一下mybatis的進階知識;
- 看過技術文獻後我的解決辦法主要是通過反射把要執行的sql語句替換成自己已經拼接好的。
我主要看的文檔是這個 <mybatis技術文檔鏈接>
以及通過idea看一點源碼;
重新把自己的感悟寫一下
mybatis
數據庫接口層
這個是和數據庫打交道,直接對數據庫增刪改查。主要涉及到的執行類爲SqlSession
。
SqlSessionFactory
—>SqlSession
SqlSession
可以直接執行相應的statement,也可以通過Mapper接口執行;
sql綁定與結果解析
主要涉及到了
BoundSql
綁定具體sql語句;SqlSource
構建BoundSql對象;MappedStatement
每個註解或者xml中的sql函數對應一個MappedStatementConfiguration
mybatis外部配置類ResultMap
具體查詢結果與java中類的轉換
所以,看到這些後我主要想到:把BoundSql中的sql語句綁定成我自己的就好了。
框架支撐
- 註解配置sql語句
- xml配置sql語句
我的動態sql語句生成類:
public List<String> createTableSql(DbTableInfo dbTableInfo) {
List<String> sqls = Collections.emptyList();
if (dbTableInfo != null && dbTableInfo.getTableStructure() != null
&& !dbTableInfo.getTableStructure().isEmpty()) {
sqls = dbTableInfo.getTableStructure().entrySet().stream().map(e -> {
StringBuilder sb = new StringBuilder();
sb.append("CREATE TABLE `" + e.getKey() + "` (");
List<RowInfo> rows = e.getValue();
for (RowInfo row : rows) {
sb.append("`" + row.getFieldName() + "` ");
sb.append(row.getFieldType() + " COMMENT '" + row.getFieldComment() + "',");
}
String tempSql = sb.toString();
String sql = tempSql.substring(0, tempSql.length() - 1) + ");";
return sql;
}).collect(Collectors.toList());
}
return sqls;
}
通過反射獲得具體feild,並將對象的feild重新設置:
private void dynamicReplaceSqlStatementIfNecessary(String sql, String sqlStatementId) {
if (StringUtils.hasText(sql)) {
Configuration configuration = sqlSessionFactory.getConfiguration();
MappedStatement mappedStatement = configuration.getMappedStatement(sqlStatementId);
SqlSource sqlSource = mappedStatement.getSqlSource();
if (sqlSource instanceof StaticSqlSource && sqlSource.getBoundSql(null).getSql().equalsIgnoreCase(sql)) {
return;
}
try {
Field sqlSourceField = mappedStatement.getClass().getDeclaredField("sqlSource");//反射
sqlSourceField.setAccessible(true);
sqlSourceField.set(mappedStatement, new StaticSqlSource(mappedStatement.getConfiguration(), sql));
} catch (Exception e) {
e.printStackTrace();
}
}
}
還是要多看源碼,多看大神總結的文章啊。