zoukankan      html  css  js  c++  java
  • 20Mybatis_订单商品数据模型_一对一查询——resultType和resultMap两种方式以及两种方式的总结

    上一篇文章分析了数据模型,这篇文章就给出一个需求,这个需求是一对一查询,并完成这个需求。

    --------------------------------------------------------------------------------------------------------------------------------------------

    需求:

           查询订单信息,关联查询创建订单的用户信息。

    记住:用Mybatis开发的顺序就是

    1.写sql语句

    2.创建pojo类来完成映射

    3.写Mapper.xml

    4.写Mapper.java接口

    ---------------------------------------------------------------------------------------------------------------------------------------------------

    我们知道Mybatis中mapper.xml中分为resultType和resultMap两种,这两种我们都讲:

    一:先讲resultMap:

    先给出案例结构:

    cn.itcast.mybatis.po包下面的类(items,orderdetail,Orders,User)都是根据数据库的4张表创建的实体类。

    1.我们先来分析一下怎么写sql语句:

    写sql语句时要先根据需求确定查询的主表和查询的关联表:

    根据“查询订单信息,关联查询创建订单的用户信息”  很明显,查询的主表是订单表,查询的关联是用户表。

    关联查询使用内链接?还是外链接?由于orders表中有一个外键(user_id),通过外键关联查询用户表只能查询出一条记录,可以使用内链接。

    sql如下:

    SELECT

      orders.*,

      USER.username,

      USER.sex,

      USER.address

    FROM

      orders,

      USER

    WHERE orders.user_id = user.id

    2.根据select(orders.*,USER.username,USER.sex,USER.address)语句 创建Pojo类

    我们创建的pojo类要满足orders.*,USER.username,USER.sex,USER.address这些映射,很明显单纯依靠数据库的映射(Orders.java和User.java)不能满足,所以要新写一个类OrdersCustom.java。

    如下:

    package cn.itcast.mybatis.po;
    
    import java.util.Date;
    
    public class OrdersCustom  extends Orders{
        private String username;
        private String sex;
        private String address;
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getSex() {
            return sex;
        }
        public void setSex(String sex) {
            this.sex = sex;
        }
        public String getAddress() {
            return address;
        }
        public void setAddress(String address) {
            this.address = address;
        }
        
    
    }

    为什么这个类要继承Orders而不是继承User.java因为根据orders.*,USER.username,USER.sex,USER.address,很明显,要映射的数据是order表中的全部数据以及user

    表中的username,sex,address这些数据,直接继承Order类的话就可以少定义一些属性,只要定义username,sex,address。就可以了。

    3.写Mapper.xml和Mapper.java接口(放在同一个包下面,用接口的方式去加载)

    OrderMapperCustom.xml的代码如下:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!-- nanmespace:命名空间。 作用就是对sql进行分类话管理,理解Sal分离
    
    注意:使用mapper代理方式,namespace有特殊重要的作用
    -->
    
    <mapper namespace="cn.itcast.mybatis.mapper.OrdersMapperCustom">
       
    
            <select id="findOrdersUser"  resultType="cn.itcast.mybatis.po.OrdersCustom">
            SELECT ORDERS.* , 
            user.`username`,
            user.`sex`,
            user.`address` 
            FROM orderS,USER
             WHERE ORDERS.`user_id`=USER.`id`
    
        
        </select>
        
       
    </mapper>

    OrdersMapperCustom.java代码如下:

    package cn.itcast.mybatis.mapper;
    
    import java.util.List;
    
    import cn.itcast.mybatis.po.OrdersCustom;
    
    public interface OrdersMapperCustom {
        public List<OrdersCustom> findOrdersUser();
    
    }

    同时不要忘了在SqlMapConfig.xml。

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        
          
        
        <!-- properties的配置必须写在typeAliases的上面 -->
        <properties resource="db.properties"></properties>
    
    
     
           
     <!-- 和spring整合后 environments配置将废除-->
        <environments default="development">
            <environment id="development">
            <!-- 使用jdbc事务管理-->
                <transactionManager type="JDBC" />
            <!-- 数据库连接池-->
                <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driver}" />
                    <property name="url" value="${jdbc.url}" />
                    <property name="username" value="${jdbc.username}" />
                    <property name="password" value="${jdbc.password}" />
                </dataSource>
            </environment>
        </environments>
    
        
            <mappers>
                
               <!--  用mapper接口的方式加载-->
               <!-- 
               遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致
               且在一个目录中。
               当着这个规范的前提是:使用mapper代理方法。
               
               
               
                -->
                <mapper class="cn.itcast.mybatis.mapper.OrdersMapperCustom"/>
                
                
             </mappers>
        
        
        
    </configuration>

    4.编写测试代码Mybatis_mappertest.java:

    package cn.itcast.mybatis.test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Date;
    import java.util.List;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.junit.Before;
    import org.junit.Test;
    
    import cn.itcast.mybatis.mapper.OrdersMapperCustom;
    import cn.itcast.mybatis.mapper.userMapper;
    import cn.itcast.mybatis.po.User;
    import cn.itcast.mybatis.po.UserCustom;
    import cn.itcast.mybatis.po.UserQueryVo;
    
    public class Mybatis_mappertest {
        
        private SqlSessionFactory sqlSessionFactory;
        @Before
        public void setup() throws IOException
        {   String resource="SqlMapConfig.xml";
            InputStream inputStream= Resources.getResourceAsStream(resource);
            //主要是生成SqlsessionFactory。
            this.sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
        }
        @Test
        public void testMaper()
        {
            SqlSession sqlSession=null;
            
            sqlSession=sqlSessionFactory.openSession();
            //生成代理类
            OrdersMapperCustom orderMapper=sqlSession.getMapper(OrdersMapperCustom.class);
    
            orderMapper.findOrdersUser();
           
            
            
        }
    
    }

    运行结果:一切正常。

    二:再讲resultMap(重点):

    resultMap映射的思想:

    使用resultMap将查询结果中的订单信息映射到Orders对象中,在orders类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中。也就是说查出来的user信息都要映射在orders中新开的一个user属性中。

    还是按照第一sql语句,第二pojo类,第三mapper.xml,mapper.java接口这种顺序来写。

    1.sql语句:和之前的resulrType的sql语句一样:

    SELECT

      orders.*,

      USER.username,

      USER.sex,

      USER.address

    FROM

      orders,

      USER

    WHERE orders.user_id = user.id

    2.写pojo类:在原来的Orders.java中新增一个User属性:

    User类:

    package cn.itcast.mybatis.po;
    
    import java.util.Date;
    //对应数据库中的user表
    public class User {
    private int id;//对应数据库中主键
    private String username;//对应数据库中用户的名称
    private Date birthday;//对应数据库中的生日
    private String sex;//性别
    private String address;//地址
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    
    }

    Orders.java类:

    package cn.itcast.mybatis.po;
    
    import java.util.Date;
    
    public class Orders {
    private Integer id;
    private Integer user_id;
    private String number;
    private Date createtime;
    private String note;
    //新增了一个User属性,为了保存查询得到的关联的User表的信息
    private User user;
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getUser_id() {
        return user_id;
    }
    public void setUser_id(Integer user_id) {
        this.user_id = user_id;
    }
    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }
    public Date getCreatetime() {
        return createtime;
    }
    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }
    public String getNote() {
        return note;
    }
    public void setNote(String note) {
        this.note = note;
    }
    
    
    }

    3.写mapper.xml和mapper.java接口

    OrdersMapperCustom.xml:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!-- nanmespace:命名空间。 作用就是对sql进行分类话管理,理解Sal分离
    
    注意:使用mapper代理方式,namespace有特殊重要的作用
    -->
    
    <mapper namespace="cn.itcast.mybatis.mapper.OrdersMapperCustom">
      
            <!-- 配置映射的订单信息 -->
            <!-- id:指定查询列中的唯 一标识,订单信息的中的唯 一标识,如果有多个列组成唯一标识,配置多个id
              就是说id要能唯一的标识出数据库中的Order表。
                column:订单信息的唯 一标识 列
                property:订单信息的唯 一标识 列所映射到Orders中哪个属性
                
              -->
        
    <resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap">
       <!-- 这一行的作用是要能唯一的识别出order表的,那么很明显是主键id -->
        <id column="id" property="id"/>
        
        <!-- 以下的几行result column就是表中的字段   property就是对应到相应pojo类中的属性-->
        <result column="user_id" property="user_id"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note"  property="note"/>
        
        
        
            <!-- 配置映射的关联的用户信息 -->
            <!-- association:用于映射关联查询单个对象的信息
            property:要将关联查询的用户信息映射到Orders中哪个属性
             -->
        <!-- 下面的代码比较特殊,因为Order表是直接关联到user表,下面这么写的目的是把user表映射到Order类中
         <association property="user"这里的user指的是orders类中的user,对应的是cn.itcast.mybatis.po.User
         
        
         -->
        <association property="user" javaType="cn.itcast.mybatis.po.User">
           <!-- 
           <id column="user_id" property="id"/>这里的是user_id指的是order表中只有这个属性能表示唯一的user表
            -->
            <id column="user_id" property="id"/>
            
            <!-- 接下来的result  property什么的都是为了把user表中的字段能匹配到 
            cn.itcast.mybatis.po.User这个类的属性中
            -->
               <result column="username" property="username"/>
              <result column="sex" property="sex"/>
              <result column="address" property="address"/>
            </association>
        
    </resultMap>
        
        
            <select id="findOrdersUser"  resultType="cn.itcast.mybatis.po.OrdersCustom">
            SELECT ORDERS.* , 
            user.`username`,
            user.`sex`,
            user.`address` 
            FROM orderS,USER
             WHERE ORDERS.`user_id`=USER.`id`
    
        
        </select>
        
          <select id="findOrdersUseResultMap"  resultMap="OrdersUserResultMap">
            SELECT ORDERS.* , 
            user.`username`,
            user.`sex`,
            user.`address` 
            FROM orderS,USER
             WHERE ORDERS.`user_id`=USER.`id`
    
        
        </select>
    </mapper>

    OrdersMapperCustom.java接口

    package cn.itcast.mybatis.mapper;
    
    import java.util.List;
    
    import cn.itcast.mybatis.po.Orders;
    import cn.itcast.mybatis.po.OrdersCustom;
    
    public interface OrdersMapperCustom {
    //这里的的函数名字要和OrdersMapperCustom.xml中的id一模一样
        public List<OrdersCustom> findOrdersUser();
        public List<Orders> findOrdersUseResultMap();
    
    }

    Junit测试代码:

    package cn.itcast.mybatis.test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Date;
    import java.util.List;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.junit.Before;
    import org.junit.Test;
    
    import cn.itcast.mybatis.mapper.OrdersMapperCustom;
    import cn.itcast.mybatis.mapper.userMapper;
    import cn.itcast.mybatis.po.Orders;
    import cn.itcast.mybatis.po.User;
    import cn.itcast.mybatis.po.UserCustom;
    import cn.itcast.mybatis.po.UserQueryVo;
    
    public class Mybatis_mappertest {
        
        private SqlSessionFactory sqlSessionFactory;
        @Before
        public void setup() throws IOException
        {   String resource="SqlMapConfig.xml";
            InputStream inputStream= Resources.getResourceAsStream(resource);
            //主要是生成SqlsessionFactory。
            this.sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
        }
        @Test
        public void testMaper()
        {
            SqlSession sqlSession=null;
            
            sqlSession=sqlSessionFactory.openSession();
            //生成代理类
            OrdersMapperCustom orderMapper=sqlSession.getMapper(OrdersMapperCustom.class);
        //创建包装对象,设置查询条件
            //orderMapper.findOrdersUser();
            
           @SuppressWarnings("unused")
        List<Orders>list=orderMapper.findOrdersUseResultMap();
            
            
        }
    
    }

    运行结果:一切正常。

       resultType和resultMap实现一对一查询小结

    实现一对一查询:

    resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。

    如果没有查询结果的特殊要求建议使用resultType。

    resultMap:需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中。

    resultMap可以实现延迟加载,resultType无法实现延迟加载。

  • 相关阅读:
    linux的性能优化
    linux日志分析
    rsyslog日志服务的配置文件分析
    Unix 入门
    Linux常用快捷键
    Linux常用命令大全
    ueditor 实现ctrl+v粘贴图片并上传、word粘贴带图片
    本地图文直接复制到WordPress编辑器中
    本地图文直接复制到Blog编辑器中
    http大文件上传(切片)
  • 原文地址:https://www.cnblogs.com/shenxiaoquan/p/5785324.html
Copyright © 2011-2022 走看看