Mybatis映射文件

Mybatis映射文件

select元素返回类型resultType,resultMap
<select id="selectGoodById" parameterType="int" resultType="goods">
        select id,cate_id,name,price,description,order_no,update_time 
        from goods where id = #{id}
</select>

<select id="selectAllGoods" resultMap="t_good">
        select id,cate_id,name,price,description,order_no,update_time from goods
</select>

如上面映射配置所示,第一句采用resultType作为该参数返回类型的定义,这样查询该语句之后,数据库表中的字段就会映射到goods中各种属性.而该属性的值一般是权限定类名
resultMap属性,表示外部 resultMap 的命名引用.也就是ResultMap元素的引用,其值为ResultMap元素中的id
以上两种属性不能同时出现

两者之间的区别:
如果pojo的属性可以与数据库表中的属性对应起来,则直接使用resultType就可以,如果不能直接对应,要进行相关的映射处理,这时候选择resultMap.

关于#{}id参数:正如上面示例所示,id参数是goods中一个property,(javaBean的属性),除了上述之外,如果parameterType类型改为hashMap,那么id的值就会从hashMap中获取key=id的值


sql元素

sql元素是用来定义可重用的SQL代码片段.定义完成之后,可以在其他sql语句内使用.
例如:

<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>

如上述所示定义sql元素相关语句,下面是在select语句中使用该sql:

<select id="selectUsers" resultType="map">
  select
    <include refid="userColumns"><property name="alias" value="t1"/></include>
  from some_table t1
</select>

上面include元素是引用sql标签的元素,property标签内的属性名称对应于sql标签中的alias变量,并且将改占位符的值设置为t1,所以上面这句select 语句可以翻译成如下:

select
    t1.id,t1.username,t1.password
  from some_table t1

参数问题(parameterType)
<select id="selectPerson" parameterType="int" resultType="hashmap">
    SELECT * FROM PERSON WHERE ID = #{id}
</select>

上面指明了调用select语句时候,需要传入的参数类型为int类型,查询结果集返回的是hashMap.该语句首先会变成如下java语句:

String selectUser = "select * from person where Id = ?"
PrepareStatement ps = conn.prepareStatement(selectUser);
ps.setInt(1,id);

#{id}先会告诉Mybatis先创建预处理语句参数.
除了上面简单的参数类型之外,还可以接收复杂的参数类型(接收一个对象参数)
例如

<select id="insertPerson" parameterType="user">
    insert into person values(#{id},#{name},#{password})
</select>

#{id}会告诉mybatis去寻找user对象中的id属性值,然后填充相关的sql语句.


ResultMap
基本映射关系
<resultMap id="blogResult" type="Blog">
  <id property="id" column="blog_id" />
  <result property="title" column="blog_title"/>
</resultMap>
  • type表示实际的返回类型
  • resultMap中两个子元素id和result. Id表示数据库主键,column表示表的字段,property表示数据映射 到返回类型的属性.
  • ResultMap元素所起到的作用就是将数据库表中的字段映射到java POJO中的各种字段,如上述代码所示,Blog类中的id属性对应于数据库表中的blog_id属性(逐渐使用id子元素),title属性对应于数据库表中的blog_title属性(result元素)
  • ResultMap存在是为了避免数据库字段与pojo字段对应不一致的情况,在编程的时候最好显示表明.
关联
<association property="author" column="blog_author_id" javaType="Author">
  <id property="id" column="author_id"/>
  <result property="username" column="author_username"/>
</association>

1.关联元素处理“有一个”类型的关系。比如,在我们的示例中,一 个博客有一个用户(来处理组合类)。
2.你需要告诉 MyBatis 如何加载关联。MyBatis 在这方面会有两种不同的 方式:
- 嵌套查询:通过执行另外一个 SQL 映射语句来返回预期的复杂类型
- 嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集

关联的嵌套查询
属性描述
column来自数据库的表格的列名,或重命名的列标签。
select另外一个映射语句的 ID,可以加载这个属性映射需要的复杂类型。在获取的时候,指定的列的值将被传递给目标 select 语句作为参数
fetchType可选的。有效值为 lazy和eager
<resultMap id="blogResult" type="Blog">
  <association property="author" column="author_id" javaType="Author" select="selectAuthor"/>
</resultMap>

<select id="selectBlog" resultMap="blogResult">
  SELECT * FROM BLOG WHERE ID = #{id}
</select>

<select id="selectAuthor" resultType="Author">
  SELECT * FROM AUTHOR WHERE ID = #{id}
</select>

在上面示例配制文件中,assocation元素中的select属性调用另一个sql查询,查询的结果填充author属性,而查询参数id就是数据库表中的author_id.

关联的嵌套结果
属性描述
resultMap指明另一个resutlMap的ID,可以映射关联的嵌套结果到一个合适的对象中
columnPrefix当连接多表时,你将不得不使用列别名来避免ResultSet中的重复列名。指定columnPrefix允许你映射列名到一个外部的结果集中
notNullColumn默认情况下,子对象仅在至少一个列映射到其属性非空时才创建。
autoMapping如果使用了,当映射结果到当前属性时,Mybatis将启用或者禁用自动映射。

示例代码:

<select id="selectBlog" resultMap="blogResult">
  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
  from Blog B left outer join Author A on B.author_id = A.id
  where B.id = #{id}
</select>

映射结果:

<resultMap id="blogResult" type="Blog">
  <id property="id" column="blog_id" />
  <result property="title" column="blog_title"/>
  <!--与上面字段对应
    B.id            as blog_id,
    B.title         as blog_title,
    B.author_id     as blog_author_id,
-->
  <association property="author" column="blog_author_id" javaType="Author" resultMap="authorResult"/><!--上面查询语句中Author表中的字段被映射成authorResult中的各种字段,两个表格的关联查询-->
  <!--与下面字段对应
    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
-->
</resultMap>

<resultMap id="authorResult" type="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"/>
</resultMap>

如果blog有一个co-author怎么办? select语句将看起来这个样子:

<select id="selectBlog" resultMap="blogResult">
  select
    B.id            as blog_id,
    B.title         as blog_title,
    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,
    CA.id           as co_author_id,
    CA.username     as co_author_username,
    CA.password     as co_author_password,
    CA.email        as co_author_email,
    CA.bio          as co_author_bio
  from Blog B
  left outer join Author A on B.author_id = A.id
  left outer join Author CA on B.co_author_id = CA.id
  where B.id = #{id}
</select>

再次调用Author的resultMap将定义如下:

<resultMap id="authorResult" type="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"/>
</resultMap>

因为结果中的列名与resultMap中的列名不同。 你需要指定columnPrefix重用映射co-author结果的resultMap。

<resultMap id="blogResult" type="Blog">
  <id property="id" column="blog_id" />
  <result property="title" column="blog_title"/>
  <association property="author"
    resultMap="authorResult" />
  <association property="coAuthor"
    resultMap="authorResult"
    columnPrefix="co_" /><!--表示co_开头的数据表列名-->
</resultMap>
集合
<collection property="posts" ofType="domain.blog.Post">
  <id property="id" column="post_id"/>
  <result property="subject" column="post_subject"/>
  <result property="body" column="post_body"/>
</collection>

集合元素的作用几乎和关联是相同的。实际上,它们也很相似,文档的异同是多余的。 所以我们更多关注于它们的不同。我们来继续上面的示例,一个博客只有一个作者。但是博客有很多文章。在博客类中, 这可以由下面这样的写法来表示:

private List<Post> posts;

要映射嵌套结果集合到 List 中,我们使用集合元素。就像关联元素一样,我们可以从 连接中使用嵌套查询,或者嵌套结果。
- 集合的嵌套查询
首先,让我们看看使用嵌套查询来为博客加载文章。

<resultMap id="blogResult" type="Blog">
  <collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPostsForBlog"/>
</resultMap>

<select id="selectBlog" resultMap="blogResult">
  SELECT * FROM BLOG WHERE ID = #{id}
</select>

<select id="selectPostsForBlog" resultType="Blog">
  SELECT * FROM POST WHERE BLOG_ID = #{id}
</select>

这里你应该注意很多东西,但大部分代码和上面的关联元素是非常相似的。首先,你应该注意我们使用的是集合元素。然后要注意那个新的“ofType”属性。这个属性用来区分 JavaBean(或字段)属性和集合属性。上面classId属性是Blog对应表中的id字段,树POST的外键.所以你可以读出下面这个 映射:

<collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPostsForBlog"/>

读作: “在 Post 类型的 ArrayList 中的 posts 的集合。”
javaType 属性是不需要的,因为 MyBatis 在很多情况下会为你算出来。所以你可以缩短 写法:

<collection property="posts" column="id" ofType="Post" select="selectPostsForBlog"/>
  • 集合的嵌套结果
    至此,你可以猜测集合的嵌套结果是如何来工作的,因为它和关联完全相同,除了它应 用了一个“ofType”属性
<select id="selectBlog" resultMap="blogResult">
  select
  B.id as blog_id,
  B.title as blog_title,
  B.author_id as blog_author_id,
  P.id as post_id,
  P.subject as post_subject,
  P.body as post_body,
  from Blog B
  left outer join Post P on B.id = P.blog_id
  where B.id = #{id}
</select>

我们又一次联合了博客表和文章表,而且关注于保证特性,结果列标签的简单映射。现 在用文章映射集合映射博客,可以简单写为:

<resultMap id="blogResult" type="Blog">
  <id property="id" column="blog_id" />
  <result property="title" column="blog_title"/>
  <collection property="posts" ofType="Post">
    <id property="id" column="post_id"/>
    <result property="subject" column="post_subject"/>
    <result property="body" column="post_body"/>
  </collection>
</resultMap>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值