开启mybatis sql日志打印
可以在日志中看到sql中执行的语句
在配置文件中加上下面这几条语句
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
logging.level.com.example.demo=debug
查询操作
根据用户id查询用户
UserMapper:
UserInfo getUserById(@Param("user_id") Integer id);
UserMapper.xml:
<select id="getUserById" resultType="com.example.demo.entity.UserInfo">
select * from userinfo where id=${user_id}
</select>
我们可以使用单元测试来测试查询到的信息是否正确
单元测试有如下特点:
- 快速生成一个方法,来测试一个功能模块
- 只有所有单元测试通过才会打包,防止程序出现bug
- 用单元测试的事务可以回滚到未测试状态,不会污染数据库的数据
可以看到,spring中自带单元测试的依赖,我们不用再引用junit了
只需要在要测试的类中右键,选择generate,test,即可创建单元测试
勾选需要添加的单元测试方法
然后就会在test包下生成对应的测试类
添加@SpringBootTest注解可以让当前测试类运行在springBoot环境中
添加@Transactional注解,可以创建事务,运行完测试类后会回滚到初始状态,不会污染数据
@SpringBootTest
@Transactional
class UserMapperTest {
@Autowired
UserMapper userMapper;
@Test
void getUserById(){
UserInfo userInfo = userMapper.getUserById(1);
System.out.println(userInfo);
Assertions.assertEquals("admin",userInfo.getUsername());
}
}
可以看到,查询到对应的userinfo对象,并且控制台中有详细的sql语句
也可以使用#通配符
<select id="getUserById" resultType="com.example.demo.entity.UserInfo">
select * from userinfo where id=#{user_id}
</select>
可以发现,使用$是直接用1替换id,而使用#则是先使用占位符?,再在后面的语句中用1替换
查询所有用户
UserMapper:
List<UserInfo> getAll();
UserMapper.xml:
<select id="getAll" resultType="com.example.demo.entity.UserInfo">
select * from userinfo
</select>
UserMapperTest:
@Test
void getAll() {
List<UserInfo> list = userMapper.getAll();
Assertions.assertEquals(1, list.size());
}
根据用户名查询用户
UserMapper:
List<UserInfo> getUserByName(String username);
UserMapper.xml:
<select id="getUserByName" resultType="com.example.demo.entity.UserInfo">
select * from userinfo where username=#{username}
</select>
UserMapperTest:
@Test
void getUserByName() {
List<UserInfo> list = userMapper.getUserByName("admin");
System.out.println(list.size());
}
这时查找是成功的:
如果使用$,则会不成功
<select id="getUserByName" resultType="com.example.demo.entity.UserInfo">
select * from userinfo where username=${username}
</select>
可以看到,sql语句中直接将username替换成admin,而没有加上"",因此导致了查询操作不成功
#和$的区别
同样是占位符,#是预编译处理,也就是先将sql中的#{}内容替换成?然后在使用PreparedStatement的set方法来赋值操作
因此在替换时,admin会自动加上""
而$则是直接替换操作,因此admin没有加上""
而直接替换也有好处,例如我们要按顺序查找数据时,就不需要""了,因此需要使用$
<select id="getAllBySort" resultType="com.example.demo.entity.UserInfo">
select * from userinfo order by id ${sort}
</select>
增添操作
UserMapper:
Integer add(UserInfo userInfo);
UserMapper.xml:
除了查找操作,其他的几种操作都不需要指定返回类型了,并且可以直接使用对象中的属性来进行插入操作
<insert id="add">
insert into userinfo(username,password,createtime,updatetime)
values(#{username},#{password},#{createTime},#{updateTime})
</insert>
UserMapperTest:
@Test
void add() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("san");
userInfo.setPassword("123");
userInfo.setCreateTime(LocalDateTime.now());
userInfo.setUpdateTime(LocalDateTime.now());
int result = userMapper.add(userInfo);
System.out.println(result);
Assertions.assertEquals(1, result);
}
添加自增id
在xml中将useGeneratedKeys设置为true,表示mybatis中使用数据库内部生成的主键
而keyProperty的值,可以指定唯一识别对象的属性,也就是说mybatis会使用getGeneratedKeys的返回值来设置值
<insert id="addGetId" useGeneratedKeys="true" keyProperty="id">
insert into userinfo(username,password,createtime,updatetime)
values(#{username},#{password},#{createTime},#{updateTime})
</insert>
修改操作
UserMapper:
int upUserName(UserInfo userInfo);
UserMapper.xml:
<update id="upUserName">
update userinfo set username=#{username} where id=#{id}
</update>
UserMapperTest:
@Test
void upUserName() {
UserInfo userInfo = new UserInfo();
userInfo.setId(2);
userInfo.setUsername("si");
int result = userMapper.upUserName(userInfo);
System.out.println(result);
Assertions.assertEquals(1,result);
}
删除操作
UserMapper:
int delById(@Param("id") Integer id);
UserMapper.xml:
<delete id="delById">
delete from userinfo where id=#{id}
</delete>
UserMapperTest
@Test
void delById() {
Integer id = 2;
int result = userMapper.delById(id);
System.out.println(result);
Assertions.assertEquals(1,result);
}