0%

mybatis | 基础注解

这篇文章讲述的注解如下:

  • @Select
  • @Result
  • @Insert
  • @Update
  • @delete

spring boot 使用 mybatis 一共有两种方式


参考资料



使用


  • @Select 是查询类的注解,所有的查询均使用这个
  • @Insert 插入数据库使用,直接传入实体类会自动解析属性到对应的值
  • @Update 负责修改,也可以直接传入对象
  • @delete 负责删除
  • @Result 修饰返回的结果集,关联实体类属性和数据库字段一一对应,如果实体类属性和数据库属性名保持一致,就不需要这个属性来修饰。

该注解是 spring boot + mybatis 结合在一起使用的注解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public interface UserMapper {

@Select("SELECT * FROM users")
@Results({
@Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
@Result(property = "nickName", column = "nick_name")
})
List<UserEntity> getAll();

@Select("SELECT * FROM users WHERE id = #{id}")
@Results({
@Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
@Result(property = "nickName", column = "nick_name")
})
UserEntity getOne(Long id);

@Insert("INSERT INTO users(userName,passWord,user_sex) VALUES(#{userName}, #{passWord}, #{userSex})")
void insert(UserEntity user);

@Update("UPDATE users SET userName=#{userName},nick_name=#{nickName} WHERE id =#{id}")
void update(UserEntity user);

@Delete("DELETE FROM users WHERE id =#{id}")
void delete(Long id);
}

注意,使用 # 符号和 $ 符号的不同:

  • #{} 这种取值是编译好SQL语句再取值
  • ${} 这种是取值以后再去编译SQL语句

我们经常使用的是#{},一般解说是因为这种方式可以防止SQL注入,简单的说#{}这种方式SQL语句是经过预编译的,它是把#{}中间的参数转义成字符串,举个例子:

select * from student where student_name = #{name} 

预编译后,会动态解析成一个参数标记符?:

select * from student where student_name = ?

MyBatis在处理#{ }时,它会将sql中的#{ }替换为,然后调用PreparedStatementset方法来赋值,传入字符串后,会在值两边加上单引号。

而使用${}在动态解析时候,会传入参数字符串

select * from student where student_name = 'lyrics'

#{}方式能够很大程度防止sql注入。

$方式无法防止Sql注入。

$方式一般用于传入数据库对象,例如传入表名.

一般能用#的就别用$.

举个activiti工作流的例子:

select * from ${prefix} ACT_HI_PROCINST where PROC_INST_ID_ = #{processInstanceId}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

@Autowired
private UserMapper userMapper;

@Test
public void testInsert() throws Exception {
userMapper.insert(new User("aa1", "a123456", UserSexEnum.MAN));
userMapper.insert(new User("bb1", "b123456", UserSexEnum.WOMAN));
userMapper.insert(new User("cc1", "b123456", UserSexEnum.WOMAN));

Assert.assertEquals(3, userMapper.getAll().size());
}

@Test
public void testQuery() throws Exception {
List<User> users = userMapper.getAll();
System.out.println(users.toString());
}


@Test
public void testUpdate() throws Exception {
User user = userMapper.getOne(30l);
System.out.println(user.toString());
user.setNickName("neo");
userMapper.update(user);
Assert.assertTrue(("neo".equals(userMapper.getOne(30l).getNickName())));
}
}

Results

1
2
3
4
5
6
7
@Select({"select id, name, class_id from my_student"})
@Results({
@Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true),
@Result(column="name", property="name", jdbcType=JdbcType.VARCHAR),
@Result(column="class_id", property="classId", jdbcType=JdbcType.INTEGER)
})
List<Student> selectAll();

@Results的基本用法。当数据库字段名与实体类对应的属性名不一致时,可以使用@Results映射来将其对应起来。column为数据库字段名,porperty为实体类属性名,jdbcType为数据库字段数据类型,id为是否为主键。

如上所示的数据库字段名 class_id 与实体类属性名 classId,就通过这种方式建立了映射关系。名字相同的可以省略。

@ResultMap

@ResultMap 的用法。当这段 @Results 代码需要在多个方法用到时,为了提高代码复用性,我们可以为这个 @Results 注解设置id,然后使用@ResultMap注解来复用这段代码。

1
2
3
4
5
6
7
8
9
10
@Select({"select id, name, class_id from my_student"})
@Results(id="studentMap", value={
@Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true),
@Result(column="class_id", property="classId", jdbcType=JdbcType.INTEGER)
})
List<Student> selectAll();

@Select({"select id, name, class_id from my_student where id = #{id}"})
@ResultMap(value="studentMap")
Student selectById(integer id);

Result

上面的资料有 @Result 的各种详细参数以及用法。

这里说一下高阶用法

  • @one
  • @many
请我喝杯咖啡吧~