Mybatis注解方式就是将SQL语句直接写在接口上,而省略了去XML文件中写查询的SQL语句。这种方法的优点是对于需求比较简单的系统,效率较高。缺点是当SQL语句有变化时都需要重新编译代码。所以一般情况下不建议使用注解方式,不论是自己开发还是团队开发,都不建议使用注解的开发方式。
在Mybatis注解SQL中,最基本的就是@Select、@Insert、@Update、@Delete四种,换句话说就是,增删改查都可以使用注解方式来完成。
@Select
之前如果我们不使用注解的方式来进行select查询的时候,需要改变项目中的三个文件,分别是实体类的接口文件、实体类的mapper文件和测试文件。就拿我们之前的例子来说,现在有一个实体类User,里面写的是该实体类的一些属性和字段。也有它的一个接口文件UserMapper.java,通常里面写一些方法之类的。还有一个映射文件UserMapper.xml的XML文件,XML文件中我们一般写关于查询的SQL语句。最后还有关于接口文件中所写方法的测试文件。
现在我们有了@Select注解之后,我们就不需要去XML文件中书写查询的SQL语句了,而是直接在接口文件中使用@Select注解来直接写查询语句和方法。比如,我们需要查询t_role表中的所有信息,那么使用@Select注解的话,应该是这样的:
在RoleMapper.java接口类文件中直接写:
@Select({"select id,role_name roleName,enabled,create_author createAuthor," +
"create_time createTime from t_role where id = #{id}"})
Role selectById(Long id);
此时,连同SQL语句和查询的方法一起就在.java文件中写完了,不用再去.xml文件中去单独写SQL语句了。
观察一下,就会发现,其实使用注解就是在接口方法的基础上添加需要的注解,并写上相应的SQL语句即可。只不过使用注解方式要注意考虑数据库表的字段和Java属性字段映射的问题,为了避免出错,其实我们可以将Java中的属性字段和数据库表中的字段设置成相同的。
测试文件写在RoleMapperTest.java文件中:
@Test
public void testSelectById() {
SqlSession sqlSession = getSqlSession();
try {
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = roleMapper.selectById(1L);
System.out.println(role);
} finally {
sqlSession.close();
}
}
除此之外,我们还可以使用resultMap方法来实现同样的功能。
@Results({
@Result(property = "id",column = "id",id = true),
@Result(property = "roleName",column = "role_name"),
@Result(property = "enabled",column = "enabled"),
@Result(property = "createAuthor",column = "create_author"),
@Result(property = "createTime",column = "create_time")
})
@Select("select id,role_name,enabled,create_author, create_time from t_role where id = #{id}")
Role selectById2(Long id);
@Insert注解
@Insert注解本身是很简单的,如果没有特殊情况,可以和@Select一样操作。但是,需要注意的是,当不需要返回插入数据的主键时,可以和@Select一样操作,但是如果需要返回自增的主键或返回非自增的主键的时候,就需要使用@Options和@Selectkey注解。
- 不需要返回主键时:
//不需要返回主键的插入
@Insert({"insert into t_role(id,role_name,enabled,create_author,create_time) " +
"values(#{id},#{roleName},#{enabled},#{createAuthor},#{createTime,jdbcType = TIMESTAMP})"})
int addRole(Role role);
@Test
public void testAddRole() {
SqlSession sqlSession = getSqlSession();
try {
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = new Role();
role.setRoleName("测试人员");
role.setEnabled(1);
role.setCreateAuthor(1L);
role.setCreateTime(new Date());
int res = roleMapper.addRole(role);
if(res > 0) {
System.out.println(res);
System.out.println("插入成功!");
}
} finally {
sqlSession.commit();
sqlSession.close();
}
}
- 返回自增主键
新增addRole2()方法:
//返回自增主键
@Insert({"insert into t_role(role_name,enabled,create_author,create_time) " +
"values(#{roleName},#{enabled},#{createAuthor},#{createTime,jdbcType = TIMESTAMP})"})
@Options(useGeneratedKeys = true, keyProperty = "id")
int addRole2(Role role);
@Test
public void testAddRole2() {
SqlSession sqlSession = getSqlSession();
try {
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = new Role();
role.setRoleName("开发人员");
role.setEnabled(1);
role.setCreateAuthor(1L);
role.setCreateTime(new Date());
int res = roleMapper.addRole2(role);
if(res > 0) {
System.out.println(res);
System.out.println("编号为" + role.getId() + "插入成功!");
}
} finally {
sqlSession.commit();
sqlSession.close();
}
}
- 返回非自增主键
新增addRole3()方法:
//返回非自增主键
@Insert({"insert into t_role(role_name,enabled,create_author,create_time) " +
"values(#{roleName},#{enabled},#{createAuthor},#{createTime,jdbcType = TIMESTAMP})"})
@SelectKey(statement = "SELECT LAST_INSERT_ID()",keyProperty = "id",resultType = Long.class,before = false)
int addRole3(Role role);
非自增主键的返回主要针对于同时插入多条数据的情况,返回的是插入的最后一条数据的主键。
@Update注解和@Delete注解
这两个注解方式都挺简单的,测试方法和之前的都是差不多一样的。
//更新
@Update({"update t_role set role_name = #{roleName},enabled = #{enabled},creaate_author = #{createAuthor}," +
"create_time = #{createTime,jdbcType = TIMESTAMP} where id = #{id}"})
int updateById(Role role);
//删除
@Delete("delete from t_role where id = #{id}")
int deleteById(Long id);
@Provider注解
除了增删改查注解可以使用简单的SQL外,MyBatis还提供了4种Provider注解,即@SelectProvider、@InsertProvider、@UpdateProvider和@DeleteProvider,这四种Provider的注解也可以实现查询、插入、更新和删除操作。
以Provilege为例,进行对@Provider注解的使用示例。还是和@Select注解一样,只需要在接口类文件和测试类文件中添加代码即可:
@SelectProvider(type = PrivilegeProvider.class, method = "selectById")
Privilege selectById(Long id);
public class PrivilegeProvider {
public String selectById(final Long id) {
return "select id,privilege_name privilegeName,privilege_url privilegeUrl from t_privilege where id = #{id}";
}
}
@Test
public void testSelectById() {
SqlSession sqlSession = getSqlSession();
try {
PrivilegeMapper privilegeMapper = sqlSession.getMapper(PrivilegeMapper.class);
Privilege privilege = privilegeMapper.selectById(1L);
System.out.println(privilege);
} finally {
sqlSession.close();
}
}
最常用的注解方式也就这些了,因为Mybatis的注解方式并不是主流,再加上注解方式需要手动拼接字符串,需要编写代码重新编译,不方便维护,因此除非在程序简单且数据库表基本不变的情况下使用,否则都不建议使用注解方法,所以不必做过多深入。