Mapper文件详解
Mapper文件是mybatis的核心文件,是业务逻辑sql书写的地方,每个应用ssm框架的开发者基本都用到过,当然也可以同tk-mapper这种方式,不用mapper文件也能比较好的操作数据库,但是个人觉得还是书写sql比较好,控制权在开发者手中,方面调试与问题跟踪,而不是交给一个黑盒子,问题出在哪儿都不知道。
以后的代码示例来源于mybatis-3.5.0的源码中的测试用例BlogMapper.xml文件,中间加上一些解释说明。
1. 命名空间
Mapper文件首先要配置命名空间,区分各个Mapper以解决可能存在的id冲突,在configuration中的mappedStatements中的key是以命名空间加上sql的id一起的,如果没有namespace,可能会很麻烦。
如果采用接口的方式映射,那么namespace的名称必须与接口的全类名相同
2. ResultMap
ResultMap的定义是数据库的表与对象映射的关键,是查询语句中的结果创建的依据,也是Mapper文件配置的核心内容之一,如果不采用自动映射的方式,那么必须的配置ResultMap,ResultMap的定义有是这样的:
本身有两个重要的属性是必须要写的
id:为结果映射取一个名字,方面在CRUD中使用,相关与一个别名,
type:是javaBean的类型,结果映射到哪个类
resultMap有多个字节点:id,result,discriminator,association,collection,现在分开对这些配置讲解
1) id,Id是指明数据库表中的主键与对象映射的关系,在进行关联查询中有优化sql的作用,有多个自身的属性:
property:javaBean的属性名称
javaType:java的数据类型,可以是别名,可以是全限定名
column:数据表的字段名称
jdbcType:jdbc中定义的数据类型
typeHandler:指定数据在获取或传递参数的处理,那么在此讲解一下TypeHandler, 在mybatis中typeHandler负责去数据的设置与或者进行类型处理,可以通过实现TypeHandler接口或者继承BaseTypeHandler,通常如果需要处理非mybatis框架定义的数据类型,那么可以自定义,在常用的过程中用不到,继承BaseTypeHandler简单一些,不需要实现所有的方法,只需要处理自己需要的,怎么做,随便找一个默认实现的源码一看就明白,举个例子,BlobTypeHandler是怎么做的了:
public class BlobTypeHandler extends BaseTypeHandler { @Override public void setNonNullParameter(PreparedStatement ps, int i, byte[] parameter, JdbcType jdbcType) throws SQLException { ByteArrayInputStream bis = new ByteArrayInputStream(parameter); ps.setBinaryStream(i, bis, parameter.length); } @Override public byte[] getNullableResult(ResultSet rs, String columnName) throws SQLException { Blob blob = rs.getBlob(columnName); byte[] returnValue = null; if (null != blob) { returnValue = blob.getBytes(1, (int) blob.length()); } return returnValue; } @Override public byte[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException { Blob blob = rs.getBlob(columnIndex); byte[] returnValue = null; if (null != blob) { returnValue = blob.getBytes(1, (int) blob.length()); } return returnValue; } @Override public byte[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { Blob blob = cs.getBlob(columnIndex); byte[] returnValue = null; if (null != blob) { returnValue = blob.getBytes(1, (int) blob.length()); } return returnValue; }}
就实现这四个方法,设置或者获取,需要怎么处理,返回什么,根据自己的情况定义即可。
2)result
Result是普通字段的映射关系
属性的相关说明与Id相同
3)association
Assosiation是一对一的关联中用到,可以关联到,定义如下:
基础的几个字段有result的意义一样,这个还多了一些一段,只在此解释两个重要的
Select:是查询一个mybatis的语句作为结果映射,只需要指明是哪个属性,哪个地段参数就行
ResultMap:可以指明是是映射到哪个resultMap
在来看看怎么用:
①select的使用
② 映射关系自定义
③ resultMap的方式
4)collection
Collection的用法与association一样,定义也基本相同,只是collection是一对多的关联,映射一个集合,这是一个子查询,使用的使用要相关注意,子查询的效率比较低。
3. 增删改查操作
1) insert操作标签,定义如下
中定义的,很少用这个属性parameterType CDATA #IMPLIED //参数类型,mybatis内置的基本类型以及类的全限定名resultMap CDATA #IMPLIED //结果类型,在中定义的id名称resultType CDATA #IMPLIED //结果类型,内置的基本类型以及类的全限定名resultSetType (FORWARD_ONLY | SCROLL_INSENSITIVE | SCROLL_SENSITIVE) #IMPLIEDstatementType (STATEMENT|PREPARED|CALLABLE) #IMPLIED//statement的类型,括号中三种可选择的,默认的是Prepared,不需要更改fetchSize CDATA #IMPLIED //获取数据的大小timeout CDATA #IMPLIED //超时时间flushCache (true|false) #IMPLIED //时候清空缓存,默认是trueuseCache (true|false) #IMPLIED//是否开启结果缓存databaseId CDATA #IMPLIED //数据源的类型id,在provider中定义lang CDATA #IMPLIEDresultOrdered (true|false) #IMPLIED //结果是否排序resultSets CDATA #IMPLIED >
常用的只有id,parameterType,resultType|resultMap,其他的基本用不到,只需要数量掌握这三个就行了,
示例1:
select * from Blog where id = #{id}
示例2:
select count(1) from post
2) 插入语句
定义如下
中定义的parameterType CDATA #IMPLIED //参数类型timeout CDATA #IMPLIED//超时时间flushCache (true|false) #IMPLIED //是否清空缓存statementType (STATEMENT|PREPARED|CALLABLE) #IMPLIED//statement类型keyProperty CDATA #IMPLIED //主键对应的属性useGeneratedKeys (true|false) #IMPLIED//是否开启自动生成idkeyColumn CDATA #IMPLIED//主键的列databaseId CDATA #IMPLIED//数据源idlang CDATA #IMPLIED>
常用的属性是id,parameterType, useGeneratedKeys, keyProperty,生成主键有个好处就是在插入以后可以返回主键的值,如果有后续处理,不需要在查询一遍。
示例1:
insert into country (countryname,countrycode) values (#{countryname},#{countrycode})
3) 更新标签
Update表示更新数据,定义为:
和插入的定义基本一样,用法也基本相同,只是写的业务sql不一样
示例1:
update Author set username=#{username, javaType=String}, password=#{password}, email=#{email}, bio=#{bio} where id=#{id}
4) 删除标签
Delete的定义如下:
每个属性的意义与insert一样,没有做详细的注释
示例1:
delete from Author where id = #{id}
4. 标签
可以将反复使用的sql语句以变量的形式定义出来,在其他的需要的地方用标签引用:
例如:
field1, field2
使用的地方这样用
select from table1
到此为止基本的用法讲解已经讲述完毕,在下一节中,将介绍动态sql