MyBatis系列(六)——MyBatis的注解开发
前言
在前面的系列文章中,我们已经知道了使用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配置文件的方式进行多表操作的开发类似,使用注解开发需要注意的问题是结果集的封装,这里的话我们需要学会使用四个注解:Results
、Result
、One
、Many
。我们先来看一下这几个注解的含义:
接下来我们就来演示一下如何使用上述的注解进行开发
(一)表关系一对一开发
步骤一:定义实体类
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
代码,使用Results
和Result
方法封装结果集。
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
中常用的注解(insert
、insert
、@update
、@delete
、@select
、@Results
、@Result
、@One
、@Many
、)已经介绍完了,其实使用起来并不难,也确实能在一定程度上简化我们的开发,但是对于一些更加复杂的业务场景来说的话,可能注解相对来说就不太方便处理了。具体怎么使用,还是要根据实际的开发情况而定。