本文是读 杨开振老师的《深入浅出 Mybatis技术原理与实践》第四章所记录的笔记,本文绝对没有推荐书的意思,只是看着记录学习,同时分享自己的观点而已。
1、映射器的主要元素
1)select
2)insert
3)update
4)delete
5)sql
6)resultMap
7)cache
8)cache-ref
2、积累
1)sql 引用可以节省很多代码,因为 select * 是不建议在生产环境中使用的。
<sql id> #{prefix.role_name}</sql>
然后使用
<include refid><property name="prefix" vlaue="r"></property></include>
2)ResultMap 使用时外键的困扰
A 表示主表 a_id 为主键,B 表示子表 b_id 为主键,a_id 为外键。使用 ResultMap映射的时候我希望映射B的POJO时有 a_id , 但是A和B是左外连接的。结果就会出现,无论B是否有结果集都会把 a_id
映射到 B的POJO上,这个是难以接受的。要是映射时可以指定是谁的 a_id 就好了,因为单从字段名称来看都是一样的。
3)N+1(独立sql导致) 问题的解决办法
A:延迟加载
B:连接查询
3、异议
P81
说到参数传递的三种方式,分别:Map、@Param、JavaBean
作者建议当参数多于5个时使用JavaBean,而而我觉得使用Map是最好的方式,可读性差了点,但是对于后期扩展以及开发效率老说是非常可观的。如果使用JavaBean,那么在我们系统中会充满大量的一次性JavaBean(使用一次,仅仅是在数据传输的时候),如果后期对数据关系调整时同时又要调整JavaBean的属性,这个是很难接受的,尤其是那种具有历史的字段,实在不敢动啊,可是如果你使用的是Map,那么这些都将不是问题。
P82
说到 insert 元素,
1) keyProperty 的描述是:表示以哪个列作为属性的主键。不能和 keyColumn 同时使用。
2)keyColumn 的描述是:指明第几列是主键,不能和 可以Property 同时使用,只接受整形参数。
关于以上两点我要提出质疑,首先 kerProperty 并不是指出关系的哪个列作为属性的主键,说实话属性的主键是什么意思我也不是很明白,主键应该是在关系中存在吧?关系中的主键应该也是有Primary标识出来的吧?这个字段说的是把主键值映射到返回值的哪个字段。比如 t_teacher 关系,主键是 teacher_id ,那么 keyProperty 配置的应该是 teacherId,那么就可以通过 teacherId 获取到主键的值了。然后作者又说 keyProperty 和 keyColumn 不能同时使用,其实二者并不矛盾为什么不能一起用呢?
另外,在<selectKey>中的 keyProperty 其意义和在<insert> 中是不一样的,前者是说赋值给<insert> 中参数为 keyProperty 的字段。
然后说到 keyColumn ,这个字段我也觉得不是读者解释那样,说必须给整数,指明第几列啊,我觉得都是有问题的。
官方文档是这样说的
P85
代码清单4-14:更新和删除(参数配置的顺序至少要统一,何况ID应该写在第一位便于维护)
P87
关于JDBCType参数的配置,作者是这样解释的,大部分的情况下 Mybatis 都会去推断你返回的数据类型,所以大部分情况下你都无需去配置参数类型和结果类型,要我们设置的往往只是可能返回为空的字段类型而已,因为null值,Mybatis无法判断其返回类型。
说得好像很有道理,可是在Mysql中,我就从来没有指定过这个数据类型,无论是否为null,都一样可以设置啊。
跟踪源码 BaseTypeHandler 你会发现,如果jdbcType没有设置,那么会有个类型为 OTHER,然后通过 PreparedStatement public void setNull(int parameterIndex, int sqlType) 设置为null。
这里特别指出 sqlType 是指 java.sql.Types , OTHER = 111
所以,就算为 null , 也可以不需要指定 jdbcType 的。
另外,#{search , jdbcType=INTEGER , javaType=int }
如果一个变量在Java中的数据类型是String,那么就算你在Mapper文件中设置 jdbcType = INTEGER,实际执行SQL语句时还是会使用String来替代占位符。
如果一个变量在Java中的数据类型是String,那么如果你还在Mapper文件中设置了 javaType = int,在注入参数时就会出现异常:
Caused by: org.apache.ibatis.type.TypeException: Could not set parameters for mapping: Cause: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
P117
自定义缓存说得太简单了,这个和Mybatis官方文档一样。
参考:http://note.youdao.com/share/?id=3e7ec71f3bcce3d54715f818f633a262&type=note#/