15.使用MyBatis注解实现复杂映射查询数据

15.使用注解实现复杂映射查询数据

1.使用注解实现复杂映射开发

  • 之前我们在映射文件中通过配置 、、 来实现复杂关系映射。

  • 使用注解开发后,我们可以使用 @Results、@Result,@One、@Many 注解组合完成复杂关系的配置。

  • 下图为注解重点,请记住:

    image-20220224211625626

1.1一对一查询—两表查询

  • 需求:查询一个订单,与此同时查询出该订单所属的用户

  • 一对一查询语句:

    //嵌套查询
    SELECT * FROM orders;
    SELECT * FROM `user` WHERE id = #{订单的uid};
    
1.1.1代码实现

(1)OrderMapper接口

  • @One代替了标签,使用时需要Result(one = @One(select = “namespace.id”) 表示。
  • javaType:表示返回的对象类型。
 /**
     * 一对一查询:
     * 查询订单所对应的用户
     */
    @Select(" select * from orders ")
    @Results({
            //id = true 表示该字段为主键 类似于 <id property="id" column="id"></id>
            @Result( id = true, property ="id", column = "id" ),
            @Result(  property ="id", column = "id" ),
            @Result(  property ="orderTime", column = "orderTime" ),
            @Result(  property ="total", column = "total" ),
            @Result(  property ="uid", column = "uid" ),
                //Result(one = @One(select = "namespace.id") 代替了<assocation>标签
                @Result(one = @One(select = "com.weihong.mapper.UserMapper.findUserById") ,property = "user" , javaType = com.weihong.domain.User.class , column = "uid")
    })
    List<Orders> findAllWithUser();
  • 上面语句等价于使用xml映射文件的sql,如下代码所示:
   <resultMap id="userOrdersMapper" type="orders">
        <id property="id" column="id"></id>
        <result property="orderTime" column="orderTime"></result>
        <result property="total" column="total"></result>
        <result property="uid" column="uid"></result>
        <association property="user" javaType="com.lagou.domain.User"         		 select="com.lagou.mapper.UserMapper.findUserOrderByNested" column="uid">
        </association>
    </resultMap>
    <select id="findUserOrders" resultMap="userOrdersMapper">
            select * from orders
    </select>

(2)UserMapper接口

   /**
     * 根据id找用户
     * @param id
     * @return
     */
    @Select(" select * from `user` where id = #{userId} ")
   User findUserById(@Param("userId") Integer id);

(3)测试代码

    @Test
    public void test2(){
        OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
        List<Orders> orders = ordersMapper.findAllWithUser();
        for (Orders order : orders) {
            System.out.println(order);
        }
    }

(4)测试结果

image-20220224212414329

1.2一对多查询—》两表查询

  • 需求:查询一个用户,与此同时查询出该用户具有的订单
SELECT * FROM `user`;
SELECT * FROM orders where uid = #{用户id};
1.2.1代码实现

(1)UserMapper接口

特别注意:

  1. 此时查询为一对多查询,使用collection来关联查询,对应注解为@Many属性。
  2. 一个用户可能有多个订单,所以返回类型为List类型。javaType = List.class(这是与一对一查询不同的)
 /**
     * 查找用户所对应的订单:一对多
     * 一个用户对应多个订单
     * @return
     */
    @Select("select * from `user` ")
    @Results({
            @Result(id = true, property = "id" , column="id"),
            @Result(property = "birthday" , column = "birthday"),
            @Result(property = "sex" , column = "sex"),
            @Result(property = "address" , column = "address"),
                @Result(column = "id" ,many = @Many(select = "com.weihong.mapper.OrdersMapper.findByUid"), property = "ordersList" ,  javaType = List.class )
    })
    List<User> findAllWithOrder();

(2)OrderMapper接口

 /**
     * 根据用户id查找订单信息
     * @param uid
     * @return
     */
    @Select("select * from orders where uid = #{uid} ")
    List<Orders> findByUid(@Param("uid") Integer uid);

(3)测试类

 @Test
    public void test3(){
        UserMapper usermapper = sqlSession.getMapper(UserMapper.class);
        List<User> allUser = usermapper.findAllWithOrder();
        for (User user : allUser) {
            System.out.println(user);
        }
    }

(4)测试结果

image-20220226115753263

1.3多对多查询

  • 需求:查询所有用户,同时查询出该用户的所有角色

  • 多对多查询语句

    select * from sys_role r left join sys_user_role ur on r.id = ur.roleid where ur.userid in (
    select id from `user`
    )
    
1.3代码实现

(1)UserMapper接口

    /**
     * 查询用户所对应的角色信息:
     * 多对多查询:
     * 借用到关联表
     * 先查询用户表的用户id,后和角色信息表及中间表做关联查询
     */

    @Select("select * from `user` ")
    @Results({
            @Result(id = true, property = "id", column = "id"),
            @Result(property = "birthday", column = "birthday"),
            @Result(property = "sex", column = "sex"),
            @Result(property = "address", column = "address"),
              @Result(column = "id" , many = @Many ( select = "com.weihong.mapper.RoleMapper.getUserRoleInfo" , fetchType = FetchType.EAGER ) , property = "roleList" ,javaType = List.class)
    })
    List<User> findUserofRole();

(2)RoleMapper接口

    @Select(" select * from sys_role r left join sys_user_role ur on r.id = ur.roleid where ur.userid = #{id}")
    List<Role> getUserRoleInfo(Integer id);

(3)测试类

    @Test
    public void test4(){
        UserMapper usermapper = sqlSession.getMapper(UserMapper.class);
        List<User> allUser = usermapper.findUserofRole();
        for (User user : allUser) {
            System.out.println(user);
        }
    }

(4)测试结果

image-20220226125450407

2.注解延迟加载

不管是一对一还是一对多 ,在注解配置中都有fetchType的属性

  • fetchType = FetchType.LAZY 表示懒加载
  • fetchType = FetchType.EAGER 表示立即加载
  • fetchType = FetchType.DEFAULT 表示使用全局配置

3.小结

  • 注解开发和xml配置优劣分析
    1.注解开发和xml配置相比,从开发效率来说,注解编写更简单,效率更高。
    2.从可维护性来说,注解如果要修改,必须修改源码,会导致维护成本增加。xml维护性更强。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员阿红

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值