MyBatis 第三十二章 MyBatis 注解开发


MyBatis —— 第三十二章 MyBatis 注解开发


1. MyBatis 的常用注解

近几年来注解开发越来越流行,MyBatis 也可以使用注解开发方式,这样我们就可以减少编写 Mapper 映射文件了。我们先围绕一些基本的 CRUD 操作来学习,在学习复杂的多映射操作

  • @Insert 实现新增
  • @Update 实现更新
  • @Delete 实现删除
  • @Select 实现查询
  • @Result 实现结果封装
  • @Results 可以与 @Result 一起使用,封装多个结果集
  • @One 实现一对一结果集封装
  • @Many 实现一对多结果集封装

2. MyBatis 的增删改查

我们完成简单的 user 表的增删改查操作

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>
    <!-- Load the external properties file through the properties tag -->
    <properties resource="jdbc.properties"></properties>
    <!-- Define alias -->
    <typeAliases>
        <typeAlias type="com.gregperlinli.domain.User" alias="user" />
    </typeAliases>
    <!-- Data source environment -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="$&#123;jdbc.driver&#125;"/>
                <property name="url" value="$&#123;jdbc.url&#125;"/>
                <property name="username" value="$&#123;jdbc.username&#125;"/>
                <property name="password" value="$&#123;jdbc.password&#125;"/>
            </dataSource>
        </environment>
    </environments>
    <!-- Load mapping relationship -->
    <mappers>
        <!-- Specify the package where the interface is located -->
        <package name="com.gregperlinli.mapper"/>
    </mappers>
</configuration>

com.yourname.mapper.UserMapper

/**
 * @author gregPerlinLi
 * @since 2021-10-08
 */
public interface UserMapper &#123;
    /**
     * save user
     *
     * @param user user to save
     */
    @Insert(value = "insert into user values(#&#123;id&#125;, #&#123;username&#125;, #&#123;password&#125;, #&#123;birthday&#125;)")
    void save(User user);
    /**
     * Update user
     *
     * @param user user to update
     */
    @Update(value = "update user set username = #&#123;username&#125;, password = #&#123;password&#125; where id = #&#123;id&#125;")
    void update(User user);
    /**
     * Delete user
     *
     * @param id user id to delete
     */
    @Delete(value = "delete from user where id = #&#123;id&#125;")
    void delete(int id);
    /**
     * Find by id
     *
     * @param id id to find
     * @return user
     */
    @Select(value = "select * from user where id = #&#123;id&#125;")
    User findById(int id);
    /**
     * Find all
     * @return All users
     */
    @Select(value = "select * from user")
    List<User> findAll();
&#125;

com.gregperlinli.test.MybatisTest

/**
 * @author gregPerlinLi
 * @since 2021-10-08
 */
public class MybatisTest &#123;
    private UserMapper userMapper;

    @Before
    public void before() throws IOException &#123;
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        userMapper = sqlSession.getMapper(UserMapper.class);
    &#125;
    @Test
    public void testSave() &#123;
        User user = new User();
        user.setUsername("Tom");
        user.setPassword("abc");
        user.setId(10);
        userMapper.save(user);
    &#125;
    @Test
    public void testUpdate() &#123;
        User user = new User();
        user.setId(10);
        user.setUsername("Lucy");
        user.setPassword("123");
        userMapper.update(user);
    &#125;
    @Test
    public void testDelete() &#123;
        userMapper.delete(10);
    &#125;
    @Test
    public void testFindById() &#123;
        User user = userMapper.findById(2);
        System.out.println(user);
    &#125;
    @Test
    public void testFindAll() &#123;
        List<User> userList = userMapper.findAll();
        userList.forEach(System.out::println);
    &#125;
&#125;

3. MyBatis 的注解实现复杂映射开发

实现复杂关系映射之前我们可以在映射文件中配置 <resultMap> 来实现,使用注解开发后,我们可以使用 @Results注解,@Result 注解,@One 注解,@Many 注解组合完成复杂关系的配置

注解 说明
@Results 代替的是标签 <resultMap>,该注解中可以使用单个 @Result 注解,也可以使用 @Result 注解,也可以使用 @Result 集合。使用格式:@Results({@Result(), @Result()})@Results(@Result())
@Result 代替了 <id> 标签和 <result> 标签
@Result 中属性介绍:
column:数据库的列名
property:需要装配的属性名
one:需要使用的 @One 注解(@Result(one = @One)
many:需要使用的 @Many 注解(@Result(many = @Many)
@One 代替了 <assocation> 标签,是夺标查询的关键,在注解中用来指定子查询返回单一对象。
@One 注解属性介绍:
select:指定用来多表查询的 sqlmapper
使用格式:@Result(column = "", property = "", one = @One(select = ""))
@Many 代替了 <collection> 标签,是多表查询的关键,在注解中用来指定查询返回对象集合。
使用格式:@Result(property = "", column = "", many = @Many(select = ""))

4. 一对一查询

4.1. 一对一查询的模型

用户表和订单表的关系为:一个用户有多个订单,一个订单只从属于一个用户

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

OneToOneQuery

4.2. 示例代码

com.yourname.mapper.OrderMapper

/**
 * @author gregPerlinLi
 * @since 2021-10-13
 */
public interface OrderMapper &#123;
    /**
     * Find all order
     * @return Order list
     */
    @Select(value = "select * from orders")
    @Results(value = &#123;
            @Result(column = "id", property = "id"),
            @Result(column = "order_time", property = "orderTime"),
            @Result(column = "total", property = "total"),
            @Result(
                    property = "user", // The name of the property to encapsulate
                    column = "uid",    // According to which field to query the data of the user table
                    javaType = User.class,  // Entity type to encapsulate
                    // The select property represents the method used to query which interface to obtain data
                    one = @One(select = "com.gregperlinli.mapper.UserMapper.findById")
            )
    &#125;)
    List<Order> findAll();
&#125;

com.yourname.test.MybatisTest

/**
 * @author gregPerlinLi
 * @since 2021-10-13
 */
public class MybatisTest &#123;
    private OrderMapper orderMapper;
  
    @Before
    public void before() throws IOException &#123;
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        orderMapper = sqlSession.getMapper(OrderMapper.class);
    &#125;
    @Test
    public void testFindAll() &#123;
        List<Order> userList = orderMapper.findAll();
        userList.forEach(System.out::println);
    &#125;
&#125;

5. 一对多查询

5.1. 一对多查询的模型

用户表和订单的关系为:一个用户有多个订单,一个订单只从属于一个用户

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

OneToMultiQuery

5.2. 示例代码

com.yourname.domain.Order

/**
 * @author gregPerlinLi
 * @since 2021-10-13
 */
public class Order &#123;
    private int id;
    private Date orderTime;
    private double total;
    private int uid;

    /**
     * Which user does the current order belong to
     */
    private User user;
    public int getId() &#123;
        return id;
    &#125;
    public void setId(int id) &#123;
        this.id = id;
    &#125;
    public Date getOrderTime() &#123;
        return orderTime;
    &#125;
    public void setOrderTime(Date orderTime) &#123;
        this.orderTime = orderTime;
    &#125;
    public double getTotal() &#123;
        return total;
    &#125;
    public void setTotal(double total) &#123;
        this.total = total;
    &#125;
    public int getUid() &#123;
        return uid;
    &#125;
    public void setUid(int uid) &#123;
        this.uid = uid;
    &#125;
    public User getUser() &#123;
        return user;
    &#125;
    public void setUser(User user) &#123;
        this.user = user;
    &#125;
    @Override
    public String toString() &#123;
        return "Order&#123;" +
                "id=" + id +
                ", orderTime=" + orderTime +
                ", total=" + total +
                ", uid=" + uid +
                ", user=" + user +
                '&#125;';
    &#125;
&#125;

com.yourname.mapper.UserMapper

/**
 * @author gregPerlinLi
 * @since 2021-10-08
 */
public interface UserMapper &#123;
    /**
     * Find all user and order
     *
     * @return All user with order
     */
    @Select("select * from user")
    @Results(value = &#123;
            @Result(id = true, column = "id", property = "id"),
            @Result(column = "username", property = "username"),
            @Result(column = "password", property = "password"),
            @Result(
                    property = "orderList",
                    column = "id",
                    javaType = List.class,  // What needs to be returned here is a List, not an Order
                    many = @Many(select = "com.gregperlinli.mapper.OrderMapper.findByUid")
            )
    &#125;)
    List<User> findUserAndOrder();
&#125;

com.yourname.mapper.OrderMapper

/**
 * @author gregPerlinLi
 * @since 2021-10-13
 */
public interface OrderMapper &#123;

    /**
     * Find order by uid
     * @param uid uid to find
     * @return Order list
     */
    @Select(value = "select * from orders where uid = #&#123;uid&#125;")
    public List<Order> findByUid(int uid);
&#125;

com.yourname.test.MybatisTest

/**
 * @author gregPerlinLi
 * @since 2021-10-13
 */
public class MybatisTest &#123;
    private UserMapper userMapper;

    @Before
    public void before() throws IOException &#123;
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        userMapper = sqlSession.getMapper(UserMapper.class);
    &#125;
    @Test
    public void testFindAll() &#123;
        List<User> userList = userMapper.findUserAndOrder();
        userList.forEach(System.out::println);
    &#125;
&#125;

6. 多对多查询

6.1. 多对多查询的模型

用户表和角色表的关系为:一个用户有多个角色,一个角色被多个用户使用

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

MultiToMultiQuery

6.2. 示例代码

com.yourname.domain.User

/**
 * @author gregPerlinLi
 * @since 2021-10-08
 */
public class User &#123;
    private int id;
    private String username;
    private String password;
    /**
     * What roles does the current user have
     */
    private List<Role> roleList;
  
    public int getId() &#123;
        return id;
    &#125;
    public void setId(int id) &#123;
        this.id = id;
    &#125;
    public String getUsername() &#123;
        return username;
    &#125;
    public void setUsername(String username) &#123;
        this.username = username;
    &#125;
    public String getPassword() &#123;
        return password;
    &#125;
    public void setPassword(String password) &#123;
        this.password = password;
    &#125;
    public List<Order> getOrderList() &#123;
        return orderList;
    &#125;
    public void setOrderList(List<Order> orderList) &#123;
        this.orderList = orderList;
    &#125;
    public List<Role> getRoleList() &#123;
        return roleList;
    &#125;
    public void setRoleList(List<Role> roleList) &#123;
        this.roleList = roleList;
    &#125;
    @Override
    public String toString() &#123;
        return "User&#123;" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", roleList=" + roleList +
                '&#125;';
    &#125;
&#125;

com.yourname.domain.Role

/**
 * @author gregPerlinLi
 * @since 2021-10-13
 */
public class Role &#123;
    private int id;
    private String roleName;
    private String roleDesc;

    public int getId() &#123;
        return id;
    &#125;
    public void setId(int id) &#123;
        this.id = id;
    &#125;
    public String getRoleName() &#123;
        return roleName;
    &#125;
    public void setRoleName(String roleName) &#123;
        this.roleName = roleName;
    &#125;
    public String getRoleDesc() &#123;
        return roleDesc;
    &#125;
    public void setRoleDesc(String roleDesc) &#123;
        this.roleDesc = roleDesc;
    &#125;
    @Override
    public String toString() &#123;
        return "Role&#123;" +
                "id=" + id +
                ", roleName='" + roleName + '\'' +
                ", roleDesc='" + roleDesc + '\'' +
                '&#125;';
    &#125;
&#125;

com.yourname.mapper.RoleMapper

/**
 * @author gregPerlinLi
 * @since 2021-10-13
 */
public interface RoleMapper &#123;
    /**
     * Find role by user id
     *
     * @param uid user id to find
     * @return role list by user id
     */
    @Select(value = "select * from user_role ur, role r where ur.role_id = r.id and ur.user_id = #&#123;uid&#125;")
    List<Role> findByUid(int uid);
&#125;

com.yourname.mapper.UserMapeer

/**
 * @author gregPerlinLi
 * @since 2021-10-08
 */
public interface UserMapper &#123;
    /**
     * Find all user with roles
     *
     * @return User list with roles
     */
    @Select(value = "select * from user")
    @Results(value = &#123;
            @Result(id = true, column = "id", property = "id"),
            @Result(column = "username", property = "username"),
            @Result(column = "password", property = "password"),
            @Result(
                    property = "roleList",
                    column = "id",
                    javaType = List.class,
                    many = @Many(select = "com.gregperlinli.mapper.RoleMapper.findByUid")
            )
    &#125;)
    List<User> findUserAndRoleAll();
&#125;


文章作者: gregPerlinLi
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 gregPerlinLi !
  目录