zoukankan      html  css  js  c++  java
  • Hello Mybatis 03 数据关联

    ResultMap

    在实际的开发中,数据库不总是我们希望看到的样子。比如我们希望User的主键是id但是数据库偏偏喜欢叫它u_id,这样一来原先的resultType似乎就失效了,不带这么玩的,整个人都不好了。

    于是mybatis给出了他的方案——resultMap。把我们从复杂的命名问题中解救出来~~~

    在上一篇中已经用mybatis generator生成好了一个BlogMapper.xml。现在让我们分析下这个文件。

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
     3 <mapper namespace="pro.app.inter.BlogMapper" >
     4   <resultMap id="BaseResultMap" type="pro.app.model.Blog" >
     5     <id column="b_id" property="bId" jdbcType="INTEGER" />
     6     <result column="b_title" property="bTitle" jdbcType="VARCHAR" />
     7     <result column="b_content" property="bContent" jdbcType="VARCHAR" />
     8     <result column="user_id" property="userId" jdbcType="INTEGER" />
     9   </resultMap>
    10   
    11   <sql id="Base_Column_List" >
    12     b_id, b_title, b_content, user_id
    13   </sql>
    14   <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    15     select 
    16     <include refid="Base_Column_List" />
    17     from blog
    18     where b_id = #{bId,jdbcType=INTEGER}
    19   </select>
    20   <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
    21     delete from blog
    22     where b_id = #{bId,jdbcType=INTEGER}
    23   </delete>
    24   <insert id="insert" parameterType="pro.app.model.Blog" >
    25     <selectKey resultType="java.lang.Integer" keyProperty="bId" order="AFTER" >
    26       SELECT LAST_INSERT_ID()
    27     </selectKey>
    28     insert into blog (b_title, b_content, user_id
    29       )
    30     values (#{bTitle,jdbcType=VARCHAR}, #{bContent,jdbcType=VARCHAR}, #{userId,jdbcType=INTEGER}
    31       )
    32   </insert>
    33   <insert id="insertSelective" parameterType="pro.app.model.Blog" >
    34     <selectKey resultType="java.lang.Integer" keyProperty="bId" order="AFTER" >
    35       SELECT LAST_INSERT_ID()
    36     </selectKey>
    37     insert into blog
    38     <trim prefix="(" suffix=")" suffixOverrides="," >
    39       <if test="bTitle != null" >
    40         b_title,
    41       </if>
    42       <if test="bContent != null" >
    43         b_content,
    44       </if>
    45       <if test="userId != null" >
    46         user_id,
    47       </if>
    48     </trim>
    49     <trim prefix="values (" suffix=")" suffixOverrides="," >
    50       <if test="bTitle != null" >
    51         #{bTitle,jdbcType=VARCHAR},
    52       </if>
    53       <if test="bContent != null" >
    54         #{bContent,jdbcType=VARCHAR},
    55       </if>
    56       <if test="userId != null" >
    57         #{userId,jdbcType=INTEGER},
    58       </if>
    59     </trim>
    60   </insert>
    61   <update id="updateByPrimaryKeySelective" parameterType="pro.app.model.Blog" >
    62     update blog
    63     <set >
    64       <if test="bTitle != null" >
    65         b_title = #{bTitle,jdbcType=VARCHAR},
    66       </if>
    67       <if test="bContent != null" >
    68         b_content = #{bContent,jdbcType=VARCHAR},
    69       </if>
    70       <if test="userId != null" >
    71         user_id = #{userId,jdbcType=INTEGER},
    72       </if>
    73     </set>
    74     where b_id = #{bId,jdbcType=INTEGER}
    75   </update>
    76   <update id="updateByPrimaryKey" parameterType="pro.app.model.Blog" >
    77     update blog
    78     set b_title = #{bTitle,jdbcType=VARCHAR},
    79       b_content = #{bContent,jdbcType=VARCHAR},
    80       user_id = #{userId,jdbcType=INTEGER}
    81     where b_id = #{bId,jdbcType=INTEGER}
    82   </update>
    83 </mapper>

    在文件的开头位置,就能够发现一个名为BaseResultMapresultMap标签。在这个标签当中我们可以发现几个子标签。这几个子标签对通过columnproperty属性将数据库字段和model对应类型关联起来。而<id/>标签代表这个model类的属性对应的数据库字段为这张表的主键。定义完成这个BaseResultMap之后,我们就可以在后面的标签对中使用它作为返回的结果使用。 这里可以注意到select的属性resultMap="BaseResultMap" 。返回的数据通过resultMap被封装成了相应的对象,如果返回的数据是多条,mybatis也会自动将结果集转换为List集合。

    这里还可以关注下resultMap下的sql标签对,在这个标签对中可以写入数据库的字段名称。在CRUDxml文件中使用<include/>标签引用这它,在数据库需要修改的时候,我们就不用去修改这个配置文件下每一个sql语句。

    数据关联

    有人会说。这样resultMapresultType有什么区别!还要多写这么一堆配置,这不是吃饱了撑着么!!!真的是这个样子?

    我们之前设计了两张表,一个用户表和一个博客列表,一个用户可以有多篇博客吧,一篇博客只有一个作者。现在就让resultMap帮助我们把数据关联起来~

    先给表Blog添加几条数据

    1 INSERT INTO `blog`.`blog` (`b_id`, `b_title`, `b_content`, `user_id`) VALUES ('1', '001', 'mybatis001', '1');
    2 INSERT INTO `blog`.`blog` (`b_id`, `b_title`, `b_content`, `user_id`) VALUES ('2', '002', 'mybatis002', '1');
    3 INSERT INTO `blog`.`blog` (`b_id`, `b_title`, `b_content`, `user_id`) VALUES ('3', '003', 'mybatis003', '1');
    4 INSERT INTO `blog`.`blog` (`b_id`, `b_title`, `b_content`, `user_id`) VALUES ('4', '004', 'mybatis004', '1');
    5 INSERT INTO `blog`.`blog` (`b_id`, `b_title`, `b_content`, `user_id`) VALUES ('5', '005', 'mybatis005', '1');

    在此之前我们需要再定义一个BlogVo类,并继承Blog类,然后添加一个User类型属性user。

     1 package pro.app.model;
     2 
     3 public class BlogVo extends Blog{
     4     private User user;
     5     public User getUser() {
     6         return user;
     7     }
     8     public void setUser(User user) {
     9         this.user = user;
    10     }
    11 }

    接着在BlogMapper.xml中添加一个resultMap。

     1 <resultMap id="BaseResultMapWithUser" type="pro.app.model.BlogVo" >
     2     <id column="b_id" property="bId" jdbcType="INTEGER" />
     3     <result column="b_title" property="bTitle" jdbcType="VARCHAR" />
     4     <result column="b_content" property="bContent" jdbcType="VARCHAR" />
     5     <association property="user"  javaType="pro.app.model.User">
     6         <id column="user_id" property="id" jdbcType="INTEGER" />
     7         <result column="name" property="name" jdbcType="VARCHAR" />
     8         <result column="age" property="age" jdbcType="INTEGER" />
     9     </association>
    10   </resultMap>

    在resultMap中通过子标签association,我们将外键与对应的model类型对应起来。用association中的property属性对应java属性的用户。association下的子标签id对应blog表中的外键,这也是数据关联的关键!接着再给这个文件添加一个select标签。

    1  <select id="selectByPrimaryKeyWithUser" resultMap="BaseResultMapWithUser" parameterType="java.lang.Integer" >
    2     select * 
    3     from blog b
    4     join user u
    5     on b.user_id=u.id
    6     where b.b_id= #{id,jdbcType=INTEGER}
    7  </select>

    ok,让我们在BlogMapper.java里添加一个selectByPrimaryKeyWithUser()方法。

     1 package pro.app.inter;
     2 
     3 import org.apache.ibatis.annotations.Param;
     4 
     5 import pro.app.model.Blog;
     6 import pro.app.model.BlogVo;
     7 
     8 public interface BlogMapper {
     9     int deleteByPrimaryKey(Integer bId);
    10 
    11     int insert(Blog record);
    12 
    13     int insertSelective(Blog record);
    14 
    15     Blog selectByPrimaryKey(Integer bId);
    16 
    17     int updateByPrimaryKeySelective(Blog record);
    18 
    19     int updateByPrimaryKey(Blog record);
    20     
    21     BlogVo selectByPrimaryKeyWithUser(@Param("id")Integer id);
    22     
    23 }

    建立一个测试类来看看效果

     1 package pro.test;
     2 
     3 import java.io.Reader;
     4 
     5 import org.apache.ibatis.io.Resources;
     6 import org.apache.ibatis.session.SqlSession;
     7 import org.apache.ibatis.session.SqlSessionFactory;
     8 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
     9 
    10 import pro.app.inter.BlogMapper;
    11 import pro.app.model.Blog;
    12 import pro.app.model.BlogVo;
    13 
    14 public class BlogVoTest {
    15     private static SqlSessionFactory sqlSessionFactory;
    16     private static Reader reader; 
    17     static{
    18         try{
    19             reader= Resources.getResourceAsReader("Configuration.xml");
    20             sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    21         }catch(Exception e){
    22             e.printStackTrace();
    23         }
    24     }
    25     public static SqlSessionFactory getSession(){
    26         return sqlSessionFactory;
    27     }
    28     public static void main(String[] args) {
    29         SqlSession session = sqlSessionFactory.openSession();
    30         try {
    31             BlogMapper blogs = session.getMapper(BlogMapper.class);
    32             BlogVo bv=blogs.selectByPrimaryKeyWithUser(1);
    33             System.out.println(bv.getUser().getName());
    34         } finally {
    35             session.close();
    36         }
    37     }
    38 }

    控制台输出了:

    Mybatis

    ok!mybatis帮我们把博客的作者选出来了。现在我们来通过作者选出他所有的文章。

    同样我们在UserMapper.xml里添加一个resultMap

     1   <resultMap id="BaseResultMapWithBlogs" type="pro.app.model.UserVo" >
     2         <id column="id" property="id" jdbcType="INTEGER" />
     3         <result column="name" property="name" jdbcType="VARCHAR" />
     4         <result column="age" property="age" jdbcType="INTEGER" />
     5         <collection property="blogs" ofType="pro.app.model.Blog" column="b_id">
     6             <id column="b_id" property="bId" jdbcType="INTEGER" />
     7             <result column="b_title" property="bTitle" jdbcType="VARCHAR" />
     8             <result column="b_content" property="bContent" jdbcType="VARCHAR" />
     9         </collection>
    10     </resultMap>

    这里的resultMap还多个了一个collection标签,顾名思义这表示一个集合,collection的column表示结果集对应的table的主键。现在再添加一个select标签。

    1     <select id="selectOneWithBlogs" resultMap="BaseResultMapWithBlogs" parameterType="java.lang.Integer">
    2         select * 
    3         from blog b
    4         join user u
    5         on b.user_id=u.id
    6         where u.id = #{id,jdbcType=INTEGER}
    7     </select>

    在UserDAO.java里添加一个selectOneWithBlogs()方法。

     1 package pro.app.inter;
     2 import org.apache.ibatis.annotations.Param;
     3 
     4 import pro.app.model.User;
     5 import pro.app.model.UserVo;
     6 
     7 public interface UserDAO {
     8     public User selectOne(@Param("id")Integer id);
     9     
    10     public void insertOne(User user);
    11     
    12     public void deleteOne(@Param("id")Integer id);
    13     
    14     public void updateOne(User user);
    15     
    16     UserVo selectOneWithBlogs(@Param("id")Integer id);
    17 }

    新建一个测试类,观察结果。

     1 package pro.test;
     2 
     3 import java.io.Reader;
     4 
     5 import org.apache.ibatis.io.Resources;
     6 import org.apache.ibatis.session.SqlSession;
     7 import org.apache.ibatis.session.SqlSessionFactory;
     8 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
     9 
    10 import pro.app.inter.UserDAO;
    11 import pro.app.model.Blog;
    12 import pro.app.model.UserVo;
    13 
    14 public class UserVoTest {
    15     private static SqlSessionFactory sqlSessionFactory;
    16     private static Reader reader; 
    17     static{
    18         try{
    19             reader= Resources.getResourceAsReader("Configuration.xml");
    20             sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    21         }catch(Exception e){
    22             e.printStackTrace();
    23         }
    24     }
    25     public static SqlSessionFactory getSession(){
    26         return sqlSessionFactory;
    27     }
    28     public static void main(String[] args) {
    29         SqlSession session = sqlSessionFactory.openSession();
    30         try {
    31             UserDAO users = session.getMapper(UserDAO.class);
    32             UserVo user=users.selectOneWithBlogs(1);
    33             for(Blog b:user.getBlogs()){
    34                 System.out.println(b.getbTitle());
    35                 System.out.println(b.getbContent());
    36             }
    37         } finally {
    38             session.close();
    39         }
    40     }
    41 }

    控制台输出

    001
    mybatis001
    002
    mybatis002
    003
    mybatis003
    004
    mybatis004
    005
    mybatis005

    bingo!!!用户对应的博客都被选出来了~

    总结

     通过resultMap 实现数据的关联。

     

  • 相关阅读:
    修改服务器时间以后 cookie无法保存
    SqlServer 2017 下载地址及密钥
    ASP.NET CORE 开发路线
    在ASP.NET CORE下生成PDF文档
    Redis 学习笔记2
    Redis 学习笔记1
    notepad++文件对比
    Notepad++主题设置与推荐
    Vivado HLx 2019.1下载、安装与激活
    Tensorflow机器学习入门——cifar10数据集的读取、展示与保存
  • 原文地址:https://www.cnblogs.com/whthomas/p/3762445.html
Copyright © 2011-2022 走看看