MyBatis系列(六)——MyBatis的注解开发

2021-04-05  本文已影响0人  moutory

前言

在前面的系列文章中,我们已经知道了使用MyBatis作为持久层框架,通过xml配置文件操作数据进行开发的步骤。不过使用xml配置文件略微有些繁琐,在开发中我们可能还会使用注解来替代mapper映射文件的书写。熟悉MyBaits常用的注解使用,对于工作中阅读别人代码或者自己写代码时会有不错的帮助。本篇文章中将对MyBaits的常见注解使用进行介绍,主要分为单表和多表操作,也希望可以给各位读者一个参考。

想要了解更多MyBaits系列文章,可以从下面的传送门阅读:

MyBatis系列(一)——MyBatis的介绍和CRUD
MyBatis系列(二)——MyBatis的动态代理和映射文件动态配置
MyBatis系列(三)——MyBatis的类型处理器和PageHelper分页插件
MyBatis系列(四 )——MyBatis的多表操作


一、使用注解进行单表的增删改查

这里的话使用到的注解主要有四个:@insert@delete@update@select,看名字我们很容易可以猜测出对应的是增删改查四个操作。具体的用法我们可以看一下下面的步骤:

步骤一:定义Mapper接口:
public interface UserMapper {
    // 查询所有用户
    @Select("select * from user u")
    List<User> getAllUser() throws Exception;
    // 添加一个新用户
    @Insert("insert into user values( #{uid}, #{username}, #{password}, #{birth})")
    boolean insertUser(User user)  throws Exception;
    // 删除一个用户
    @Delete("delete from user where uid= #{id}")
    boolean deleteUser(Integer uid) throws Exception;
    // 更新用户信息
    @Update("update user u set u.username = #{username} , u.password = #{password} where u.uid = #{uid}")
    boolean updateUser(User user) throws Exception;
}
步骤二:在核心配置文件中配置接口扫描
    <mappers>
        <package name="com.qiqv.dao"></package>
    </mappers>

上面这一步也可以改成类的方式注入,不过没有上面这种包扫描这么方便

    <mappers>
        <mapper class="com.qiqv.dao.UserMapper"></mapper>
    </mappers>
步骤三:在测试文件中进行测试:
public class MyBatisAnnotationTest {

    private UserMapper mapper;
    @Before
    public void beforeExecuteSql() throws Exception{
        InputStream is = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlFactory.openSession(true);
        mapper = sqlSession.getMapper(UserMapper.class);
    }

    @Test
    public void getAllUserTest() throws Exception {
        mapper.getAllUser().forEach(System.out::println);
    }

    @Test
    public void addUserTest() throws Exception {
        User user = new User(null,"小乐","9879847",null);
        mapper.insertUser(user);
    }

    @Test
    public void updateUserTest() throws Exception {
        User user = new User(3,"吴彦祖","11100",null);
        mapper.updateUser(user);
    }

    @Test
    public void deleteUserTest() throws Exception {
        mapper.deleteUser(13);
    }
}

我们可以发现,使用了注解之后,其实代码量是少了不少的,主要体现在我们不需要再手动配置映射文件,直接在注解上写入对应的sql语句就行。

二、使用注解进行多表开发

和使用xml配置文件的方式进行多表操作的开发类似,使用注解开发需要注意的问题是结果集的封装,这里的话我们需要学会使用四个注解:ResultsResultOneMany。我们先来看一下这几个注解的含义:

注解含义

接下来我们就来演示一下如何使用上述的注解进行开发

(一)表关系一对一开发
步骤一:定义实体类
public class Order {

    private Integer oid;

    private Date createtime;

    private Double total;

    // 一个订单对应一个用户,所以这里不写userId,而是用User这个完整对象
    private User user;
}
public class User {

    private Integer uid;

    private String username;

    private String password;

    private Date birth;
}
步骤二:定义mapper接口

注解的动作基本都在接口上,我们在@select注解上写上相关的select代码,使用ResultsResult方法封装结果集。

public interface OrderMapper {
    // 根据oid查询订单信息
    @Select("select * from orders o ,user u where o.uid=u.uid and o.oid=#{id}")
    @Results({
        @Result(column = "oid",property = "oid"),
        @Result(column = "createtime",property = "createtime"),
        @Result(column = "total",property = "total"),
        @Result(column = "uid",property = "user.uid"),
        @Result(column = "username",property = "user.username"),
        @Result(column = "password",property = "user.password"),
        @Result(column = "birth",property = "user.birth"),
    })
    Order getOrderById(Integer oid);
}

除了上面这种对象.属性名的方法外,我们还可以换一种方式封装

public interface UserMapper {
    @Select("select * from user where uid = #{id}")
    User findUserById(Integer uid);
}

public interface OrderMapper {
    // 根据oid查询订单信息
    @Select("select * from orders o where o.oid=#{id}")
    @Results({
        @Result(column = "oid",property = "oid"),
        @Result(column = "createtime",property = "createtime"),
        @Result(column = "total",property = "total"),
        @Result(
                property = "user",  // 表示Order对象中的user属性名
                column = "uid",     // 表示使用哪个字段作为查询的条件,可以理解为下面select方法的入参
                javaType = User.class, //要封装的实体类型
                one = @One(select = "com.qiqv.dao.UserMapper.findUserById")
        )
    })
    Order getOrderById(Integer oid);
}
步骤三:在核心配置文件中开启包扫描(已经开启过了这一步可以不用管)
    <mappers>
        <package name="com.qiqv.dao"></package>
    </mappers>
步骤四:在代码中进行测试
    @Test
    public void getOrderById() throws Exception {
        System.out.println(mapper.getOrderById(1));
    }
(二)表关系一对多开发

这里演示的案例是,根据用户id查询出用户下的所有订单

步骤一:定义相关实体类
public class User {

    private Integer uid;
    private String username;
    private String password;
    private Date birth;
    private List<Order> orders;
}
public class Order {
    private Integer oid;
    private Date createtime;
    private Double total;
    // 一个订单对应一个用户,所以这里不写userId,而是用User这个完整对象
    private User user;
}
步骤二:定义mapper接口
public interface OrderMapper {

    @Select("select * from orders where uid = #{id}")
    List<Order> getOrdersByUid(Integer uid);
}

public interface UserMapper {
    @Select("select * from user u where u.uid = #{id}")
    @Results({
            @Result(column = "uid",property = "uid"),
            @Result(column = "username",property = "username"),
            @Result(column = "password",property = "password"),
            @Result(column = "birth",property = "birth"),
            @Result(
                column = "uid",
                property = "orders",
                javaType = List.class,
                many = @Many(select = "com.qiqv.dao.OrderMapper.getOrdersByUid")
            )
    })
    User getAllUserOrderByUid(Integer uid) throws Exception;

这里需要注意一点,由于User对象封装的是Order集合,所以javaType属性我们要选择List

步骤三:配置mapper接口扫描(如果已经配过了就不用再配)
    <mappers>
        <package name="com.qiqv.dao"></package>
    </mappers>
步骤四:在代码中进行测试
public class MyBatisAnnotationTest {

    private UserMapper mapper;
    @Before
    public void beforeExecuteSql() throws Exception{
        InputStream is = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlFactory.openSession(true);
        mapper = sqlSession.getMapper(UserMapper.class);
    }

    @Test
    public void getAllUserOrderByUid() throws Exception {
        System.out.println(mapper.getAllUserOrderByUid(1));
    }
}

由于表多对多关系在使用上和一对多并没有太大的差别,只是我们需要在两个实体对象和Mapper对象中都分别加入对应的List集合属性和方法即可。这里就不再做介绍。

至此,对于MyBatis中常用的注解(insertinsert@update@delete@select@Results@Result@One@Many、)已经介绍完了,其实使用起来并不难,也确实能在一定程度上简化我们的开发,但是对于一些更加复杂的业务场景来说的话,可能注解相对来说就不太方便处理了。具体怎么使用,还是要根据实际的开发情况而定。

上一篇 下一篇

猜你喜欢

热点阅读