其实mybatis并不是一个dao层的完整处理方案(它并不像jpa),你可以将它单纯地看做一个提供sql映射的框架,你在xml映射文件中的配置最终都会调用jdbc的api来对数据库进行具体操作。
select,insert,update,delete:
像select中的where id = #{id}这种,mybatis会为其生成一个预处理sql语句,并且在where后面提供一个占位符?,然后通过数据库连接对象con.prepareStatement来执行这条sql,在这个过程中还要通过setId来注入参数,最后得到结果值,你还需要手动将结果值注入对应的实体对象中,以上的工作mybatis都会为你自动完成,你只需要在xml中配置正确的sql并在对应的接口中使用它就好了。
select,insert,update,delete共用的参数差不多,insert会多一点:useGeneratedKeys和keyProperty(这两者仅对insert有效)
<insert id="save" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO t_customer(name,gender,tel,seller,customerSource)
VALUES (#{name},#{gender},#{tel},#{seller.sn},#{customerSource.requence})
</insert>
sql:
定义可重用的sql语句,比如某些where语句:
<sql id="whereSql">
<where>
<if test="name!=null and name!=''">
AND name LIKE CONCAT("%",#{name},"%")
</if>
</where>
</sql>
$和#的区别:
- #方式能够很大程度防止sql注入,因为mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值
- 方 式 无 法 防 止 S q l 注 入 , 因 为 m y b a t i s 在 处 理 方式无法防止Sql注入,因为mybatis在处理 方式无法防止Sql注入,因为mybatis在处理{}时,就是把${}替换成变量的值
- $方式一般用于传入数据库对象,例如传入表名.或者用在排序中
- 一般能用#的就别用$.
- ${}变量的替换阶段是在动态SQL解析阶段,而 #{}变量的替换是在DBMS中
- #性能高于$
注意点:
- 如果排序的话,请必须使用$,因为#最后生成的sql对应位置都是占位符?,而我只是想在预编译的时候单纯传一个写死的字符串过去用于排序而已
- 如果你要这样使用:
<select id="selectById" resultType="cn.myllxy._01.domain.Product">
SELECT * FROM product WHERE id=${id}
</select>
并且你的传入值为Long id:
productMapper.selectById(1L);
这将会报错:
There is no getter for property named 'id' in 'class java.lang.Long'
#{}更丰富的用法:
可以指定其参数数据类型等:
WHERE sn=#{sn,javaType=int}
jdbcType通常需要在某种特殊情况下呗设置:
有些数据库不识别mybatis对null的处理比如oracle,null在mybatis中会被处理成
OTHER(Types.OTHER),oracle是不识别这个的,解决方案一是手动指定jdbcType为null,二是该全局配置文件
public enum JdbcType {
/*
* This is added to enable basic support for the
* ARRAY data type - but a custom type handler is still required
*/
...
OTHER(Types.OTHER)
...
}