MyBatis学习(3)-映射文件
**MyBatis 的真正强大在于它的映射语句,也是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。**这可是MyBatis自己说的哈XD。这一节学习MyBatis映射配置文件
<mapper namespace="com.main.Dao.CatDao">
<!--内容-->
</mapper>
cache缓存
缓存部分补充
cache-ref缓存引用
缓存部分补充
增删改标签
这三个标签有这些属性:
parameterType:不用管,MyBatis可以推断出具体类型。
flushCache:刷新缓存,待更新。
timeout:事务相关,spring做。
statementType:这个属性可以改变使用的statement,分别有Statement、PreparedStatement、CallableStatement(储存过程用到),对应属性值为:STATEMENT,PREPARED,CALLABLE,这个也同样,一般不会改动。
useGeneratedKeys与keyProperty:有用。这两个属性是一起的,可以获得插入、更新操作后的支持自增长主键的值。
具体使用:
<insert id="方法名" useGeneratedKeys="true"
keyProperty="注入主键值的属性名">
sql语句
</insert>
这样便会将主键值注入到对象当中。
对于不支持自增长的数据库,如Oracle,如何获得主键的值呢?可以如下这么做:
<insert id="方法名">
<selectKey order="BEFORE">
select max(主键列名)+1 from 表名
</selectKey>
<!--sql语句-->
</insert>
order是控制这个查询语句的顺序。
keyColumn:指定主键是哪一列,没什么用。
databaseId:这个属性是配合MyBatis学习(2)-配置文件中的databaseIdProvider数据库产商标识使用的,也就是在全局配置文件中为databaseIdProvider起的别名,就在这里使用,与数据库移植有关。
select查询
首先回顾,获取方法参数用的是#{参数名}获取,可当方法参数不止一个时,还能简单的使用#{参数名}吗?不能。
双参数查询方法:
<select id="getEmployee" resultType="com.main.pojo.Employee">
select * from t_employee where num = #{num} and gender = #{gender}
</select>
这是调用两个参数的方法的结果,报错原因。
Cause:org.apache.ibatis.binding.BindingException:Parameter 'num' not found. Available parameters are [0, 1, param1, param2]
将#{num}和#{gender}改为#{0}和#{1}或#{param1}和#{param2}就不会报错,正常查询
让我们来看看不同参数个数,类型产生的不同现象:
-
单个参数
1)基本类型
sql语句取值->#{随便写}都可以取到。
2)pojo(对象)
取值只需要**#{属性名}**。
-
多个参数
用#{参数名}是取不到值的。需要用#{0},#{1},#{参数列表索引}或者#{param1}、#{param2}、#{paramN},为什么会这样呢?原因是MyBatis对于多个参数(大于等于二)的方法,会将这些参数自动封装到一个map中,map的key就是参数索引或者参数表示(paramN),value则是对应的参数值。但是这样很糟糕,可读性很差,而且容易取错数据。
为了提高可读性,这里可以在多参数的方法的参数前加注解@Param(“参数名”),这样即是顺序变了,也没有问题,如下:
Employee getEmployee(@Param("num") Integer num, @Param("gender")Integer gender);
-
map
既然对于多参数而言,MyBatis会封装成map,所以取值就很简单,通过#{key}取对应的值value,而key由自己决定
-
混合类型
假设这里有一个方法:
method(@Param(“id”)Integer id,String name,Employee employee),employee中我需要邮箱email,那么对于这些参数怎么取:
id = #{id}
name = #{1} 或者#{param2}
email = #{2.email}或者#{param3.email}
尽管我们可以使用索引来取数据,但是非常不推荐这么做,然后多个参数的加注解@Param也是不推荐,推荐使用的是:如果是pojo,用pojo,不是的话,并且参数不少,推荐使用的是封装map,传递map。
#{key}:这个是取值的表达式,在里面可以添加一些属性,好几个,唯一可能用到的就是"jdbcType",这是指定数据类型的,需要记住,如果使用的是Oracle数据库(对于为null的数据插入会出现问题),这个属性就需要指定:
#{key,jdbcType=类型}
既然说到了#{key},MyBatis不止这种取值方法,他还有另外一种取值方法通过${key}:
区别:
#{key}:参数预编译的形式,会用 ? 占位,之后注入。
${key}:非参数预编译,直接sql拼接,会导致sql安全问题,用在那种不支持预编译sql语句的部分,利用分表操作
查询多条记录(list):
<select id="返回值为List的方法名" resultType="集合中元素类型">
查询结果封装map:
单条记录:
这个map首先键应当是String,值类型为Object,这种将会把列名作为键,而字段属性作为value
<select id="返回值为Map的方法名" resultType="map"></select>
多条记录:
假设希望键为Integer类型,对应记录的id,值类型为记录对应的对象,如Map<Integer,Employee>,需要在这个方法的上面加注解@MapKey(“主键列名”),这样MyBatis才会知道你用的什么充当Map的Key
<select id="方法名" resultType="value对象的全路径类名"></select>
resultMap结果映射
自定义结果集的封装规则,MyBatis一般都会提供默认的,但是很多时候是不够用的。
这个标签是用来处理查询返回结果的,为了处理一些特定的数据就有了自定义结果映射。
他之下有四个标签用的较多(总共不止4个):
id:控制主键注入的
<id property="主键属性名" column="主键列名"></id>
result:控制其余数据注入的,当然他也可以注入主键数据,支持级联注入。
<result property="属性名" column="列名"></result>
association:针对于查询结果中对象的注入,这里其实在result中级联注入就可以完成,但是MyBatis推荐用这种来完成对象属性的注入。
<association property="属性名" javaType="对象类型全类名">
<id property="主键属性名" column="主键列名"></id>
<result property="属性名" column="列名"></result>
<!-- 意味你可以套娃 -->
</association>
collection:控制查询结果中集合属性的注入。
<collection property="属性名" ofType="集合元素类型全类名">
<id property="主键属性名" column="主键列名"></id>
<result property="属性名" column="列名"></result>
<!-- 意味你可以套娃 -->
</collection>
对于collection和association标签,用到他们的时候,基本是连接查询的时候。
parameterMap参数映射(已废弃)
这个标签原本是做复杂参数映射的,已废弃。
sql重用
这是抽取重复度高的sql语句,然后在动态sql中使用。