mybatis使用笔记

1. mapper.xml配置文件中,只要调用到了insert方法,不管name为不为空都会执行到preparedStatement.update()方法,如果name为null,此时就会报Query is Empty的异常

1 <insert id="insert">
2               <if test="name != null">
3               INSERT INTO user(name) VALUES(
4                #{name}
5               )
6               </if>
7 </insert>

2. mapper.xml中过滤条件中可以调用方法,但不能使用< > <=等特殊符号(加CDATA也不行), and或者or不能大写,这与XML要求有关

如下:

 1 <select id="selectById" resultMap="BaseResultMap">
 2         SELECT *
 3         from account
 4         WHERE
 5         <if test="list != null and list.size() != 0">
 6             <foreach collection="list" item="model" open="id in (" close=")" separator=",">
 7                 #{model}
 8             </foreach>
 9         </if>
10         <if test="id != null">
11             and id = #{id}
12         </if>
13         limit 0, 1
14     </select> 

3.  对于SQL语句的执行mybatis使用的是StatementHandler,在newXxxStatementHandler()时会调用BaseStatementHandler的构造方法,详见随笔(http://www.cnblogs.com/stefanking/p/5102837.html)

  PreparedStatementHandler执行过程:获取最终需要执行的SQL语句 --> prepare(sql) --> PreparedStatementHandler.update(Statement) --> PreparedStatement.execute() --> ... 

  对第一步的解释:在BaseStatementHandler的构造函数中获取最终要执行的SQL语句

  代码:

 1 protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
 2     this.configuration = mappedStatement.getConfiguration();
 3     this.executor = executor;
 4     this.mappedStatement = mappedStatement;
 5     this.rowBounds = rowBounds;
 6 
 7     this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
 8     this.objectFactory = configuration.getObjectFactory();
 9 
10     if (boundSql == null) { // issue #435, get the key before calculating the statement
11       generateKeys(parameterObject);
12       boundSql = mappedStatement.getBoundSql(parameterObject);
13     }
14 
15     this.boundSql = boundSql;
16 
17     this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
18     this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql);
19   }
20 
21 /**
22 *  MappedStatement
23 */
24 public BoundSql getBoundSql(Object parameterObject) {
25     BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
26     List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
27     if (parameterMappings == null || parameterMappings.size() <= 0) {
28       boundSql = new BoundSql(configuration, boundSql.getSql(), parameterMap.getParameterMappings(), parameterObject);
29     }
30 
31     // check for nested result maps in parameter mappings (issue #30)
32     for (ParameterMapping pm : boundSql.getParameterMappings()) {
33       String rmId = pm.getResultMapId();
34       if (rmId != null) {
35         ResultMap rm = configuration.getResultMap(rmId);
36         if (rm != null) {
37           hasNestedResultMaps |= rm.hasNestedResultMaps();
38         }
39       }
40     }
41 
42     return boundSql;
43   }
44 
45 /**
46 * DynamicSqlSource implements SqlSource
47 */
48 public BoundSql getBoundSql(Object parameterObject) {
49     DynamicContext context = new DynamicContext(configuration, parameterObject);
50     rootSqlNode.apply(context); //此处处理if where trim等内部标签过滤条件,得到最终需要编译的SQL语句,参数未替换, 如: select * from user where userName = #{param.userName} and age = #{param.age}
51     SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);
52     Class<?> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();
53     SqlSource sqlSource = sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings()); //此处替换掉占位符,得到最终参数,和最终预编译的SQL语句: 如:select * from user where userName = ? and age = ?
54     BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
55     for (Map.Entry<String, Object> entry : context.getBindings().entrySet()) {  //占位符对应位置的参数值
56       boundSql.setAdditionalParameter(entry.getKey(), entry.getValue());
57     }
58     return boundSql;
59   }

 

  

posted @ 2016-01-05 17:47  桦沐  阅读(271)  评论(0编辑  收藏  举报