深入淺出Mybatis-sql自動(dòng)生成
來源:程序員人生 發(fā)布時(shí)間:2017-03-04 08:59:00 閱讀次數(shù):9024次
本文提供了1種自動(dòng)生成sql語句的方法,它針對(duì)的對(duì)象是有主鍵或唯1索引的單表,提供的操作有增、刪、改、查4種。理解本文和本文的提供的代碼需要有java注解的知識(shí),由于本文是基于注解生成sql的。本文適配的mybatis版本是3.2.2。
準(zhǔn)備
為何在StatementHandler攔截
在深入淺出MyBatis-Sqlsession章節(jié)介紹了1次sqlsession的完全履行進(jìn)程,從中可以知道sql的解析是在StatementHandler里完成的,所以為了自動(dòng)生成sql需要攔截StatementHandler。
MetaObject簡介
在我的實(shí)現(xiàn)里大量使用了MetaObject這個(gè)對(duì)象,因此有必要先介紹下它。MetaObject是Mybatis提供的1個(gè)的工具類,通過它包裝1個(gè)對(duì)象后可以獲得或設(shè)置該對(duì)象的本來不可訪問的屬性(比如那些私有屬性)。它有個(gè)3個(gè)重要方法常常用到:
1) MetaObject
forObject(Object object,ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory)
2) Object
getValue(String name)
3) void
setValue(String name, Object value)
方法1)用于包裝對(duì)象;方法2)用于獲得屬性的值(支持OGNL的方法);方法3)用于設(shè)置屬性的值(支持OGNL的方法);
插件的原理
參見深入淺出Mybatis-插件原理。
有了上面這些基礎(chǔ)知識(shí)的準(zhǔn)備后,就能夠我們的主題了。
攔截器簽名
-
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})})
-
public class AutoMapperInterceptor implements Interceptor {
-
...
-
}
從簽名里可以看出,要攔截的目標(biāo)類型是StatementHandler(注意:type只能配置成接口類型),攔截的方法是名稱為prepare參數(shù)為Connection類型的方法。
intercept的實(shí)現(xiàn)
-
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})})
-
public class AutoMapperInterceptor implements Interceptor {
-
private static final Log logger = LogFactory.getLog(AutoMapperInterceptor.class);
-
private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
-
private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
-
-
@Override
-
public Object intercept(Invocation invocation) throws Throwable {
-
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
-
MetaObject metaStatementHandler = MetaObject.forObject(statementHandler, DEFAULT_OBJECT_FACTORY,
-
DEFAULT_OBJECT_WRAPPER_FACTORY);
-
-
while (metaStatementHandler.hasGetter("h")) {
-
Object object = metaStatementHandler.getValue("h");
-
metaStatementHandler = MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
-
}
-
-
while (metaStatementHandler.hasGetter("target")) {
-
Object object = metaStatementHandler.getValue("target");
-
metaStatementHandler = MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
-
}
-
String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
-
Configuration configuration = (Configuration) metaStatementHandler.getValue("delegate.configuration");
-
Object parameterObject = metaStatementHandler.getValue("delegate.boundSql.parameterObject");
-
if (null == originalSql || "".equals(originalSql)) {
-
String newSql = "";
-
MappedStatement mappedStatement = (MappedStatement) metaStatementHandler
-
.getValue("delegate.mappedStatement");
-
-
String id = mappedStatement.getId();
-
id = id.substring(id.lastIndexOf(".") + 1);
-
if ("insert".equals(id)) {
-
newSql = SqlBuilder.buildInsertSql(parameterObject);
-
} else if ("update".equals(id)) {
-
newSql = SqlBuilder.buildUpdateSql(parameterObject);
-
} else if ("delete".equals(id)) {
-
newSql = SqlBuilder.buildDeleteSql(parameterObject);
-
} else if ("select".equals(id)) {
-
newSql = SqlBuilder.buildSelectSql(parameterObject);
-
}
-
logger.debug("Auto generated sql:" + newSql);
-
-
SqlSource sqlSource = buildSqlSource(configuration, newSql, parameterObject.getClass());
-
&n
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)