这篇文章讲述的注解如下:
@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
中的#{ }
替换为?
,然后调用PreparedStatement
的set
方法来赋值,传入字符串后,会在值两边加上单引号。
而使用${}
在动态解析时候,会传入参数字符串
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 的各种详细参数以及用法。
这里说一下高阶用法