MyBatis注解

1. MyBatis常用注解

这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写

Mapper映射文件了。我们先围绕一些基本的CRUD来学习,再学习复杂映射多表操作。

@Insert:实现新增,代替了<insert></insert>
@Delete:实现删除,代替了<delete></delete>
@Update:实现更新,代替了<update></update>
@Select:实现查询,代替了<select></select>
@Result:实现结果集封装,代替了<result></result>
@Results:可以与@Result 一起使用,封装多个结果集,代替了<resultMap></resultMap>
@One:实现一对一结果集封装,代替了<association></association>
@Many:实现一对多结果集封装,代替了<collection></collection>

2. MyBatis注解的增删改查【重点】

2.1 创建UserMapper接口

package com.lagou.mapper;

import com.lagou.domain.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

@CacheNamespace // 配置了二级缓存
public interface UserMapper {

    /*
        查询用户
     */
    @Select("select * from user")
    public List<User> findAll();


    /*
        添加用户
     */
    @Insert("insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})")
    public void save(User user);


    /*
        更新用户
     */
    @Update("update user set username = #{username},birthday=#{birthday} where id = #{id}")
    public void update(User user);


    /*
        删除用户
     */
    @Delete("delete from user where id = #{id}")
    public void delete(Integer id);



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




    /*
        查询所有用户,及关联的订单信息
     */

    @Select("select * from user")
    @Results({
            @Result(property = "id",column = "id",id = true),
            @Result(property = "username",column = "username"),
            @Result(property = "birthday",column = "birthday"),
            @Result(property = "sex",column = "sex"),
            @Result(property = "address",column = "address"),
            @Result(property = "ordersList",javaType = List.class,column = "id",many = @Many(select = "com.lagou.mapper.OrderMapper.findOrderByUid",fetchType = FetchType.LAZY))
    })
    public List<User> findAllWithOrder();




    /*
        查询所有用户及关联的角色信息
     */

    @Select("select * from user")
    @Results({
            @Result(property = "id",column = "id",id = true),
            @Result(property = "username",column = "username"),
            @Result(property = "birthday",column = "birthday"),
            @Result(property = "sex",column = "sex"),
            @Result(property = "address",column = "address"),
            @Result(property = "roleList",javaType = List.class,column = "id",many = @Many(select = "com.lagou.mapper.RoleMapper.findAllByUid")),
    })
    public List<User> findAllWithRole();


}

2.2 编写核心配置文件

<!--我们使用了注解替代的映射文件,所以我们只需要加载使用了注解的Mapper接口即可-->
<mappers>
<!--扫描使用注解的Mapper类-->
<mapper class="com.lagou.mapper.UserMapper"></mapper>
</mappers>

<!--或者指定扫描包含映射关系的接口所在的包也可以-->
<mappers>
<!--扫描使用注解的Mapper类所在的包-->
<package name="com.lagou.mapper"></package>
</mappers>

2.3 测试代码

public class TestUser extends TestBaseMapper {

// 查询
@Test
public void testFindAll() throws Exception {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); List<User> list = userMapper.findAll();
for (User user : list) { System.out.println(user);
}
}

// 添加
@Test
public void testSave() throws Exception {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User();
user.setUsername("于谦");
user.setBirthday(new Date()); user.setSex(" 男 "); user.setAddress("北京德云社"); userMapper.save(user);


}

// 更新
@Test
public void testUpdate() throws Exception {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User();
user.setId(49); user.setUsername("郭德纲"); user.setBirthday(new Date()); user.setSex("男");
user.setAddress("北京德云社");
userMapper.update(user);
}

// 删除
@Test
public void testDelete() throws Exception {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); userMapper.delete(49);
}
}

 

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

之前我们在映射文件中通过配置<resultMap><association><collection>  来实现复杂关系映射。

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

4. 一对一查询

4.1 介绍

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

一对一查询语句


SELECT * FROM orders;
SELECT * FROM `user` WHERE id = #{订单的uid};

4.2 代码实现

1)OrderMapper接口

package com.lagou.mapper;

import com.lagou.domain.Orders;
import com.lagou.domain.User;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

public interface OrderMapper {


    /*
        查询所有订单,同时查询订单所属的用户信息
     */


    @Select("select * from orders")
    @Results({  // 代替的就是resultMap标签 id标签  result标签
          @Result(property = "id",column = "id",id = true),
          @Result(property = "ordertime",column = "ordertime"),
          @Result(property = "total",column = "total"),
          @Result(property = "uid",column = "uid"),
            @Result(property = "user",javaType = User.class,column = "uid",one = @One(select = "com.lagou.mapper.UserMapper.findById",fetchType = FetchType.EAGER))
    })
    public List<Orders> findAllWithUser();

}

2)UserMapper接口

package com.lagou.mapper;

import com.lagou.domain.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

@CacheNamespace // 配置了二级缓存
public interface UserMapper {

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

}

3)测试代码

package com.lagou.test;

import com.lagou.domain.Orders;
import com.lagou.domain.User;
import com.lagou.mapper.OrderMapper;
import com.lagou.mapper.UserMapper;
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.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

public class MybatisTest {


    private SqlSessionFactory sqlSessionFactory;
    private SqlSession sqlSession;


    // 在 @Test方法标注的方法执行之前来执行
    @Before
    public void before() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");

         sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);

         sqlSession = sqlSessionFactory.openSession();
    }


    @After
    public void after(){

        sqlSession.commit();
        sqlSession.close();

    }



   

    /*
        一对一查询(注解方式)
     */
    @Test
    public void testOneToOne(){

        OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);

        List<Orders> allWithUser = mapper.findAllWithUser();

        for (Orders orders : allWithUser) {
            System.out.println(orders);
        }


    }


}

5. 一对多查询

5.1 介绍

需求:查询一个用户,与此同时查询出该用户具有的订单

一对多查询语句

SELECT * FROM `user`;
SELECT * FROM orders where uid = #{用户id};

5.2 代码实现

1)UserMapper接口

package com.lagou.mapper;

import com.lagou.domain.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

@CacheNamespace // 配置了二级缓存
public interface UserMapper {

 

    /*
        查询所有用户,及关联的订单信息
     */

    @Select("select * from user")
    @Results({
            @Result(property = "id",column = "id",id = true),
            @Result(property = "username",column = "username"),
            @Result(property = "birthday",column = "birthday"),
            @Result(property = "sex",column = "sex"),
            @Result(property = "address",column = "address"),
            @Result(property = "ordersList",javaType = List.class,column = "id",many = @Many(select = "com.lagou.mapper.OrderMapper.findOrderByUid",fetchType = FetchType.LAZY))
    })
    public List<User> findAllWithOrder();

}

2)OrderMapper接口

package com.lagou.mapper;

import com.lagou.domain.Orders;
import com.lagou.domain.User;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

public interface OrderMapper {



    /*
        根据传递过来的用户id,查询该用户所具有的订单信息
     */
    @Select("select * from orders where uid = #{uid}")
    public List<Orders> findOrderByUid(Integer uid);




}

3)测试代码

package com.lagou.test;

import com.lagou.domain.Orders;
import com.lagou.domain.User;
import com.lagou.mapper.OrderMapper;
import com.lagou.mapper.UserMapper;
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.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

public class MybatisTest {


    private SqlSessionFactory sqlSessionFactory;
    private SqlSession sqlSession;


    // 在 @Test方法标注的方法执行之前来执行
    @Before
    public void before() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");

         sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);

         sqlSession = sqlSessionFactory.openSession();
    }


    @After
    public void after(){

        sqlSession.commit();
        sqlSession.close();

    }



    /*
       一对多查询(注解方式)
    */
    @Test
    public void testOneToMany(){

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<User> allWithOrder = mapper.findAllWithOrder();

        for (User user : allWithOrder) {
            System.out.println(user);
            System.out.println(user.getOrdersList());
        }


    }


    
}

6. 多对多查询

6.1 介绍

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

多对多查询语句

SELECT * FROM `user`;
SELECT * FROM role r INNER JOIN user_role ur ON r.`id` = ur.`rid` WHERE ur.`uid` = #{用户id};

6.2 代码实现

1)UserMapper接口

package com.lagou.mapper;

import com.lagou.domain.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

@CacheNamespace // 配置了二级缓存
public interface UserMapper {


    /*
        查询所有用户及关联的角色信息
     */

    @Select("select * from user")
    @Results({
            @Result(property = "id",column = "id",id = true),
            @Result(property = "username",column = "username"),
            @Result(property = "birthday",column = "birthday"),
            @Result(property = "sex",column = "sex"),
            @Result(property = "address",column = "address"),
            @Result(property = "roleList",javaType = List.class,column = "id",many = @Many(select = "com.lagou.mapper.RoleMapper.findAllByUid")),
    })
    public List<User> findAllWithRole();


}

2)RoleMapper接口

package com.lagou.mapper;

import com.lagou.domain.Role;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface RoleMapper {


    /*
        根据传递过来的用户id,查询该用户所具有的角色信息
     */
    @Select("SELECT * FROM sys_role r INNER JOIN sys_user_role ur ON ur.roleid = r.id WHERE ur.userid = #{uid}")
    public List<Role> findAllByUid(Integer uid);


}

3) 测试代码

package com.lagou.test;

import com.lagou.domain.Orders;
import com.lagou.domain.User;
import com.lagou.mapper.OrderMapper;
import com.lagou.mapper.UserMapper;
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.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

public class MybatisTest {


    private SqlSessionFactory sqlSessionFactory;
    private SqlSession sqlSession;


    // 在 @Test方法标注的方法执行之前来执行
    @Before
    public void before() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");

         sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);

         sqlSession = sqlSessionFactory.openSession();
    }


    @After
    public void after(){

        sqlSession.commit();
        sqlSession.close();

    }



  
   多对多查询(注解方式)
*/
    @Test
    public void testManyToMany(){

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<User> allWithRole = mapper.findAllWithRole();

        for (User user : allWithRole) {
            System.out.println(user);
            System.out.println(user.getRoleList());
        }

    }


   
}

7. 基于注解的二级缓存

7.1 配置SqlMapConfig.xml文件开启二级缓存的支持

<settings>
<!--
因为cacheEnabled的取值默认就为true,所以这一步可以省略不配置。 为true代表开启二级缓存;为false代表不开启二级缓存。
-->
<setting name="cacheEnabled" value="true"/>
</settings>

7.2 Mapper接口中使用注解配置二级缓存

@CacheNamespace
public interface UserMapper {...}

8. 注解延迟加载

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

9. 小结

节选自拉钩教育JAVA培训系列课程

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值