• 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查询结构集中所需的所有字段。该方法使用较为普遍。

  • 相关阅读:
    数据库空间使用情况
    创建database link
    oracle导出指定几张表的数据以逗号等为分隔符
    Oracle手工创建实例
    通过shell脚本调用oracle存储过程并加入定时任务
    oracle导出与导入脚本
    在存储过程中为表添加月分区与日分区
    oracle添加分区
    ORACLE_SID与SID区别
    AUTHID DEFINER与AUTHID CURRENT_USER
  • 原文地址:https://www.cnblogs.com/HigginCui/p/5848849.html
Copyright © 2020-2023  润新知