Mybatis映射配置
MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码。
Sql
这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。 参数可以静态地(在加载的时候)确定下来,并且可以在不同的 include
元素中定义不同的参数值。
<sql id="userSql">
select * from user
</sql>
如果要查找所有人员,我们就可以使用这个公共提取出来的sql
<select id="findAll" resultMap="myUser">
<include refid="userSql"></include>
</select>
要查找某个人员,也可以是使用这个公共的提取sql
使用include
方法来将公共的sql包含进来。
<select id="findAll" resultMap="myUser">
<include refid="userSql"></include>
</select>
参数
参数类型parameterType
可以填也可以不填,可以根据值进行默认处理。
<insert id="saveUser" parameterType="com.example.domain.User">
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(userName,address,sex,birthday) values (#{userName},#{address},#{sex},#{birthDay});
</insert>
比如在上面的Insert中,我们将参数指定User,并且这里使用了全限定名。mybatis会通过查找类User的get方法来获取值。注意这里会区分属性的大小写
。
结果映射
resultMap
元素是 MyBatis
中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets
数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC
不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap
能够代替实现同等功能的数千行代码。ResultMap
的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
使用alias别名,就可以不用一直使用全限定类名。
alisa别名可以指定某个类,也可以指定某个包
别名的设置放在SqlMapConfigure.xml
<typeAliases>
<typeAlias type="com.example.domain.User" alias="user"></typeAlias>
</typeAliases>
然后在IUserDao.xml中使用这个alias
在resultMap中的type里直接使用这个user即可,不用再使用全限定名了
使用package包名进行别名处理。这样这个包下面的所有类都是不区分大小写的了。
<typeAliases>
<package name="com.example.domain"></package>
</typeAliases>
高级结果映射
实际项目中数据库不可能永远是你想要的样子,并且是复杂多标查询的话,可能就需要自定义设置结果映射了。
以下取自mybatis官网
<!-- 非常复杂的语句 -->
<select id="selectBlogDetails" resultMap="detailedBlogResultMap">
select
B.id as blog_id,
B.title as blog_title,
B.author_id as blog_author_id,
A.id as author_id,
A.username as author_username,
A.password as author_password,
A.email as author_email,
A.bio as author_bio,
A.favourite_section as author_favourite_section,
P.id as post_id,
P.blog_id as post_blog_id,
P.author_id as post_author_id,
P.created_on as post_created_on,
P.section as post_section,
P.subject as post_subject,
P.draft as draft,
P.body as post_body,
C.id as comment_id,
C.post_id as comment_post_id,
C.name as comment_name,
C.comment as comment_text,
T.id as tag_id,
T.name as tag_name
from Blog B
left outer join Author A on B.author_id = A.id
left outer join Post P on B.id = P.blog_id
left outer join Comment C on P.id = C.post_id
left outer join Post_Tag PT on PT.post_id = P.id
left outer join Tag T on PT.tag_id = T.id
where B.id = #{id}
</select>
映射结果
<!-- 非常复杂的结果映射 -->
<resultMap id="detailedBlogResultMap" type="Blog">
<constructor>
<idArg column="blog_id" javaType="int"/>
</constructor>
<result property="title" column="blog_title"/>
<association property="author" javaType="Author">
<id property="id" column="author_id"/>
<result property="username" column="author_username"/>
<result property="password" column="author_password"/>
<result property="email" column="author_email"/>
<result property="bio" column="author_bio"/>
<result property="favouriteSection" column="author_favourite_section"/>
</association>
<collection property="posts" ofType="Post">
<id property="id" column="post_id"/>
<result property="subject" column="post_subject"/>
<association property="author" javaType="Author"/>
<collection property="comments" ofType="Comment">
<id property="id" column="comment_id"/>
</collection>
<collection property="tags" ofType="Tag" >
<id property="id" column="tag_id"/>
</collection>
<discriminator javaType="int" column="draft">
<case value="1" resultType="DraftPost"/>
</discriminator>
</collection>
</resultMap>
说明:
- constructor 用于在实例化类时,注入结果到构造方法中
- idArg:ID参数,彪指出作为ID的结果可以帮助提高整体性能
- arg:将被注入到构造方法的一个普通结果
- result:注入到字段或javabean属性的普通结果
- association:一个复杂类型的关联,类似left join
- 嵌套结果时,关联可以是resultType元素,或是对其他结果映射的引用
- collection– 一个复杂类型的集合嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用
- discriminator – 使用结果值来决定使用哪个 resultMap
- case – 基于某些值的结果映射嵌套结果映射 – case 也是一个结果映射,因此具有相同的结构和元素;或者引用其它的结果映射