17_高级映射:一对一查询(使用resultType)

Posted HigginCui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了17_高级映射:一对一查询(使用resultType)相关的知识,希望对你有一定的参考价值。

【数据库模型】

【各个表】

[ 用户表user ]

  购买商品的用户信息。

[ 订单表 ]

  用户所创建的订单  

[ 订单明细表 ]

  订单的详细信息,即购买商品的信息

[ 商品表 ]

  商品的具体信息

【有关系的表之间的业务关系】

分析表与表之间的业务关系时,需要建立在某个业务意义的基础之上去分析。

[ user 与 orders ]

user ---> orders :一个用户可以创建多个订单, 一对多

orders ---> user :一个订单只能由一个用户创建,一对一

[ orders与orderdetail ]

orders ---> orderdetail :一个订单可以包括多个订单明细。(一个订单可以购买多个商品,每个商品的购买信息存在orderdetail信息),一对多

orderdetail ---> orders :一个订单明细只能包含在一个订单之中,一对一

[ orderdetail 与 items]

orderdetail ---> items :一个订单明细只对应一个商品信息,一对一

items ---> orderdetail :一个商品可以包含多个订单明细,一对多

【 没关系的表之间的业务关系】

[orders 与 items]

orders 和 items 之间可以通过orderdetail表建立关系

 

【建表语句】

/*Table structure for table `items` */

CREATE TABLE `items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL COMMENT \'商品名称\',
  `price` float(10,1) NOT NULL COMMENT \'商品定价\',
  `detail` text COMMENT \'商品描述\',
  `pic` varchar(64) DEFAULT NULL COMMENT \'商品图片\',
  `createtime` datetime NOT NULL COMMENT \'生产日期\',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

/*Table structure for table `orderdetail` */

CREATE TABLE `orderdetail` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `orders_id` int(11) NOT NULL COMMENT \'订单id\',
  `items_id` int(11) NOT NULL COMMENT \'商品id\',
  `items_num` int(11) DEFAULT NULL COMMENT \'商品购买数量\',
  PRIMARY KEY (`id`),
  KEY `FK_orderdetail_1` (`orders_id`),
  KEY `FK_orderdetail_2` (`items_id`),
  CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

/*Table structure for table `orders` */

CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT \'下单用户id\',
  `number` varchar(32) NOT NULL COMMENT \'订单号\',
  `createtime` datetime NOT NULL COMMENT \'创建订单时间\',
  `note` varchar(100) DEFAULT NULL COMMENT \'备注\',
  PRIMARY KEY (`id`),
  KEY `FK_orders_1` (`user_id`),
  CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

/*Table structure for table `user` */

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) NOT NULL COMMENT \'用户名称\',
  `birthday` date DEFAULT NULL COMMENT \'生日\',
  `sex` char(1) DEFAULT NULL COMMENT \'性别\',
  `address` varchar(256) DEFAULT NULL COMMENT \'地址\',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;

【插入测试数据】(先插入没有外键约束的数据)

INSERT INTO `items` VALUES (1, \'台式机\', 3000.0, \'该电脑质量非常好!!!!\', NULL, \'2015-2-3 13:22:53\');
INSERT INTO `items` VALUES (2, \'笔记本\', 6000.0, \'笔记本性能好,质量好!!!!!\', NULL, \'2015-2-9 13:22:57\');
INSERT INTO `items` VALUES (3, \'背包\', 200.0, \'名牌背包,容量大质量好!!!!\', NULL, \'2015-2-6 13:23:02\');

INSERT INTO `user` VALUES (1, \'王五\', \'2016-1-5\', \'2\', \'天津\');
INSERT INTO `user` VALUES (10, \'张三\', \'2014-7-10\', \'1\', \'北京市\');
INSERT INTO `user` VALUES (16, \'张小明\', \'2016-2-9\', \'1\', \'浙江杭州\');
INSERT INTO `user` VALUES (22, \'陈小明\', \'2016-9-25\', \'1\', \'福建厦门\');
INSERT INTO `user` VALUES (24, \'张三丰\', \'2016-9-17\', \'1\', \'湖北武汉\');
INSERT INTO `user` VALUES (25, \'陈小明\', \'2016-2-17\', \'1\', \'上海\');
INSERT INTO `user` VALUES (26, \'王五\', \'2010-7-6\', \'2\', \'深圳\');


INSERT INTO `orders` VALUES (3, 1, \'1000010\', \'2016-8-16 13:22:35\', NULL);
INSERT INTO `orders` VALUES (4, 1, \'1000011\', \'2016-6-23 13:22:41\', NULL);
INSERT INTO `orders` VALUES (5, 10, \'1000012\', \'2016-9-22 16:13:23\', NULL);


INSERT INTO `orderdetail` VALUES (1, 3, 1, 1);
INSERT INTO `orderdetail` VALUES (2, 3, 2, 3);
INSERT INTO `orderdetail` VALUES (3, 4, 3, 4);
INSERT INTO `orderdetail` VALUES (4, 4, 2, 3);

 

 

【需求】

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

【工程截图】

【Orders.java】

package cn.higgin.mybatis.po;

import java.util.Date;

public class Orders {
    
    private Integer id;
    private Integer userId;
    private String number;
    private Date createtime;
    private String note;
    //忽略get/set方法.....
}

【OrdersCustom.java】创建pojo,将SQL要查询的结果全部映射到pojo中,pojo中必须包括所有查询列名。

(原始的Orders.java中不包含User中的字段,所以创建了OrdersCustom.java,继承Orders.java并且补充对应所需的User中的字段)

package cn.higgin.mybatis.po;

/**
 * 通过此类映射订单和用户查询结果,让此类继承包括字段较多的pojo类
 */
public class OrdersCustom extends Orders{
    //添加用户的信息
    private String username;
    private String sex;
    private String address;
    //忽略get/set方法......
}

【OrdersMapperCustom.java  接口】

package cn.higgin.mybatis.mapper;

import java.util.List;

import cn.higgin.mybatis.po.OrdersCustom;

public interface OrdersMapperCustom {
    
    //查询订单关联查询用户信息
    public List<OrdersCustom> findOrdersUser() throws Exception;
}

【OrdersMapperCustome.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">

<mapper namespace="cn.higgin.mybatis.mapper.OrdersMapperCustom">
    
    <select id="findOrdersUser" resultType="cn.higgin.mybatis.po.OrdersCustom">
        SELECT
            orders.*,
            USER.username,
            USER.sex,
            USER.address
            FROM
            orders,USER
        WHERE orders.user_id=user.id
    </select> 
</mapper>

 

【配置文件db.properties】

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=

【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 resource="db.properties">
        <!-- properties中还可以配置一些属性名和属性值 -->
        <!-- <properties name="jdbc.driver" value=""/> -->
    </properties>
    
    
    <!-- 别名定义 -->
    <typeAliases>
        <!-- 批量别名定义
            指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名 -->
        <package name="cn.higgin.mybatis.po" />
    </typeAliases>
    
    
    <!-- 和spring整合后 environments配置将废除-->
    <environments default="development">
        <environment id="development">
        <!-- 使用jdbc事务管理,事务控制由mybatis-->
            <transactionManager type="JDBC" />
        <!-- 数据库连接池,由mybatis管理-->
            <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 resource="sqlmap/User.xml"/> -->
        
        <!--通过resource方法一次加载一个映射文件 -->
        <!-- <mapper resource="mapper/UserMapper.xml"/> -->
        
        <!-- 通过mapper接口加载单个 映射文件
        遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
        上边规范的前提是:使用的是mapper代理方法
         -->
        <!-- <mapper class="cn.higgin.mybatis.mapper.UserMapper"/> -->
        
        <!-- 批量加载mapper
        指定mapper接口的包名,mybatis自动扫描包下边所有mapper接口进行加载
        遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
        上边规范的前提是:使用的是mapper代理方法
         -->
        <package name="cn.higgin.mybatis.mapper"/>

    </mappers>
    
</configuration>

【测试 OrdersMapperCustom.java】

package cn.higgin.mybatis.mapper;

import java.io.InputStream;
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.higgin.mybatis.po.OrdersCustom;

public class OrdersMapperCustomTest {
    private SqlSessionFactory sqlSessionFactory;

    // 此方法是在执行testFindUserById之前执行
    @Before
    public void setUp() throws Exception {
        // 创建sqlSessionFactory

        // mybatis配置文件
        String resource = "SqlMapConfig.xml";
        // 得到配置文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);

        // 创建会话工厂,传入mybatis的配置文件信息
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testFindOrdersUser() throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //创建代理对象
        OrdersMapperCustom ordersMapperCustom=sqlSession.getMapper(OrdersMapperCustom.class);
        
        //调用mapper的方法
        List<OrdersCustom> list=ordersMapperCustom.findOrdersUser();
        
        System.out.println(list.size());
        
        sqlSession.close();
        
    }

}

【debug运行结果】

与数据库中查询出来的结果一致,故正确。

【小结】

定义专门的Po类作为输出类型,其中定义了sql查询结构集中所需的所有字段。该方法使用较为普遍。

以上是关于17_高级映射:一对一查询(使用resultType)的主要内容,如果未能解决你的问题,请参考以下文章

mybatis入门截图四(订单商品数据模型 一对一,一对多,多对多)

19_高级映射:一对多查询(使用resultMap)

mybatis_映射查询

mybatis (高级映射 缓存 延迟加载)

MyBatis高级篇 - 关联查询(一对一)

Mybatis框架学习03