zoukankan      html  css  js  c++  java
  • Mybatis 联合查询XML与注解对比

    由于是练习,故只做了感兴趣的一部分测试。

    测试类容
    XML配置转注解方式

    实体类
    为了测试请忽略设计是否合理…
    User.java

    @Alias("User")
    public class User {
        private Integer id;
        private String username;
        private String password;
        private Timestamp birthday;
        private Boolean sex;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    UserInfo.java

    @Alias("UserInfo")
    public class UserInfo {
        private Integer id;
        private User user;
        private String name;
    }
    1
    2
    3
    4
    5
    6
    UserMessage.java

    @Alias("UserMessage")
    public class UserMessage {
        private Integer userId;
        private UserInfo userInfo;
        private List<Message> messages;
    }
    1
    2
    3
    4
    5
    6
    Message.java

    @Alias("Message")
    public class Message {
        private Integer id;
        private Integer userId;
        private String content;
        private Timestamp time;
    }
    1
    2
    3
    4
    5
    6
    7
    三表之间的关联为 userId

    XML配置方式
    XML配置

    <select id="selectUserInfoAndMessages" resultMap="UserMessages">
        select
        ui.id as uiid,
        ui.name as name,
        ui.user_id as info_user_id,
        u.id as user_id,
        u.username
        as username,
        u.password as password,
        u.birthday as birthday,
        u.sex as
        sex,
        um.id as umid,
        um.user_id as um_user_id,
        um.content as content,
        um.time as um_time
        from user_info ui
        left outer join user u on u.id = ui.user_id
        left outer join user_message um
        on u.id = um.user_id
        where u.id = #{id}
    </select>
    <resultMap type="UserMessage" id="UserMessages">
        <id property="userId" column="user_id" />
        <association property="userInfo" column="info_user_id"
            javaType="UserInfo">
            <id property="id" column="uiid" />
            <result property="name" column="name" />
            <association property="user" column="user_id" javaType="User">
                <id property="id" column="user_id" />
                <result property="username" column="username" />
                <result property="password" column="password" />
                <result property="birthday" column="birthday" />
                <result property="sex" column="sex" />
            </association>
        </association>
        <collection property="messages" javaType="ArrayList"
            ofType="Message">
            <id property="id" column="umid" />
            <result property="userId" column="user_id" />
            <result property="content" column="content" />
            <result property="time" column="um_time" />
        </collection>
    </resultMap>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    查询方法

    public List<UserMessage> testSelectUserInfoAndMessages(Integer userId) {
        try (SqlSession session = sessionFactory.openSession()) {
            //映射器方式调用
            //return session.getMapper(UserMapper.class).selectUserInfoAndMessage(userId);
            return session.selectList("mybatis.dao.mappers.UserMapper.selectUserInfoAndMessages", userId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    执行过程

    ==>  Preparing: select ui.id as uiid, ui.name as name, ui.user_id as info_user_id, u.id as user_id, u.username as username, u.password as password, u.birthday as birthday, u.sex as sex, um.id as umid, um.user_id as um_user_id, um.content as content, um.time as um_time from user_info ui left outer join user u on u.id = ui.user_id left outer join user_message um on u.id = um.user_id where u.id = ?
    ==> Parameters: 9(Integer)
    <==    Columns: uiid, name, info_user_id, user_id, username, password, birthday, sex, umid, um_user_id, content, um_time
    <==        Row: 5, 江流, 9, 9, test中文2, 1234567, 2018-07-17 17:04:09.0, 0, 1, 9, 信息1, 2018-07-18 11:36:58.0
    <==        Row: 5, 江流, 9, 9, test中文2, 1234567, 2018-07-17 17:04:09.0, 0, 2, 9, 信息2, 2018-07-18 11:37:05.0
    <==      Total: 2
    1
    2
    3
    4
    5
    6
    结果

    [UserMessage [userId=9, userInfo=UserInfo [id=5, user=User [id=9, username=test中文2, password=1234567, birthday=2018-07-17 17:04:09.0, sex=false], name=江流], messages=[Message [id=1, userId=9, content=信息1, time=2018-07-18 11:36:58.0], Message [id=2, userId=9, content=信息2, time=2018-07-18 11:37:05.0]]]]
    1
    此种方式只查询了一次,结果集被过滤了重复项目,最终集合中只有一个UserMessage对象。

    注解方式
    注解方法

    @Select("select * from user where id = #{userId}")
    @Results(value = {
            @Result(property="userId" , column="id"),
            @Result(property="userInfo" , column="id", one = @One(select="mybatis.dao.mappers.UserMapper.getUserInfoByAnnotation")),
            @Result(property="messages" , column = "id" , many= @Many(select="mybatis.dao.mappers.UserMapper.getUserMessagesByAnnotation"))
    })
    public List<UserMessage> selectUserInfoAndMessagesByAnnotation(Integer userId);//查询用户信息和用户消息

    @Select("select * from user_info where user_id = #{userId}")
    @Results(value={
            @Result(property="id" , column="id"),
            @Result(property="name" , column = "name"),
            @Result(property="user" , column = "user_id" , one = @One(select="mybatis.dao.mappers.UserMapper.getUserByAnnotation"))
    })
    public UserInfo getUserInfoByAnnotation(Integer userId);//查询用户信息

    @Select("select * from user where id = #{userId}")
    public User getUserByAnnotation(Integer userId);//查询用户

    @Select("select * from user_message where user_id = #{userId}")
    public List<Message> getUserMessagesByAnnotation(Integer userId);//查询用户消息集合
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    查询方法

    public List<UserMessage> testSelectUserMessagesByAnnotation(Integer userId) {
        try (SqlSession session = sessionFactory.openSession()) {
            return session.getMapper(UserMapper.class).selectUserInfoAndMessagesByAnnotation(userId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    执行过程

    ==>  Preparing: select * from user where id = ?
    ==> Parameters: 9(Integer)
    <==    Columns: id, username, password, sex, birthday
    <==        Row: 9, test中文2, 1234567, 0, 2018-07-17 17:04:09.0
    ====>  Preparing: select * from user_info where user_id = ?
    ====> Parameters: 9(Integer)
    <====    Columns: id, user_id, name
    <====        Row: 5, 9, 江流
    ======>  Preparing: select * from user where id = ?
    ======> Parameters: 9(Integer)
    <======    Columns: id, username, password, sex, birthday
    <======        Row: 9, test中文2, 1234567, 0, 2018-07-17 17:04:09.0
    <======      Total: 1
    <====      Total: 1
    ====>  Preparing: select * from user_message where user_id = ?
    ====> Parameters: 9(Integer)
    <====    Columns: id, user_id, content, time
    <====        Row: 1, 9, 信息1, 2018-07-18 11:36:58.0
    <====        Row: 2, 9, 信息2, 2018-07-18 11:37:05.0
    <====      Total: 2
    <==      Total: 1
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    可以看出执行了几次查询语句。

    结果

    [UserMessage [userId=9, userInfo=UserInfo [id=5, user=User [id=9, username=test中文2, password=1234567, birthday=2018-07-17 17:04:09.0, sex=false], name=江流], messages=[Message [id=1, userId=9, content=信息1, time=2018-07-18 11:36:58.0], Message [id=2, userId=9, content=信息2, time=2018-07-18 11:37:05.0]]]]
    1
    总结
    XML执行联合查询效率是要高一些的
    注解方式方法倒是可以独立使用,虽然XML也可以用select属性
    混合使用更好
    套用官方的话

    1

    因为最初设计时,MyBatis 是一个 XML 驱动的框架。配置信息是基于 XML 的,而且映射语句也是定义在 XML 中的。而到了 MyBatis 3,就有新选择了。MyBatis 3 构建在全面且强大的基于 Java 语言的配置 API 之上。这个配置 API 是基于 XML 的 MyBatis 配置的基础,也是新的基于注解配置的基础。注解提供了一种简单的方式来实现简单映射语句,而不会引入大量的开销。

    2

    注意 不幸的是,Java 注解的的表达力和灵活性十分有限。尽管很多时间都花在调查、设计和试验上,最强大的 MyBatis 映射并不能用注解来构建——并不是在开玩笑,的确是这样。比方说,C#属性就没有这些限制,因此 MyBatis.NET 将会比 XML 有更丰富的选择。也就是说,基于 Java 注解的配置离不开它的特性。

    END

    附 数据表SQL

    CREATE TABLE `user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(25) DEFAULT NULL,
      `password` varchar(25) DEFAULT NULL,
      `sex` bit(1) DEFAULT b'1',
      `birthday` datetime DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;

    CREATE TABLE `user_info` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `user_id` int(11) DEFAULT NULL,
      `name` varchar(25) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `user_id` (`user_id`),
      CONSTRAINT `user_info_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

    CREATE TABLE `user_message` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `user_id` int(11) DEFAULT NULL,
      `content` varchar(255) DEFAULT NULL,
      `time` datetime DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `message_ibfk_1` (`user_id`),
      CONSTRAINT `user_message_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
    ---------------------
    作者:很倔也很天真
    来源:CSDN
    原文:https://blog.csdn.net/wang845252276/article/details/81120504
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    删除使用RMAN命令备份的文件
    查看.Net Framework版本的方法(zz)
    c# Foreach last (zz)
    Visual Studio 2008 QFE (zz)
    打印机的接口
    牛人的PENTAX单反之路
    我新进的宾得K10D机器和镜头
    买车险要有足额第三者责任险
    谈谈P家的SUPERTAKUAMR
    硬盘接口总结
  • 原文地址:https://www.cnblogs.com/b6952/p/11088597.html
Copyright © 2011-2022 走看看