上一篇博客的传送门:MyBatis 入门到精通(二)
在之前的博客中,我们讲解了 MyBatis 的基本概念、配置文件和基本的环境搭建。下面我们通过七个方法来讲解通过 Mapper 接口方法调用的 XML 形式实现增删改查。
基本的环境搭建我这里不再重复讲解了,忘记的童鞋可以查看 MyBatis 入门到精通(一)的环境搭建部分。我们以 Emp 表结构为蓝本讲解。
全表查询 EmpMapper 接口代码ListEmpMapper.xml 代码findAllEmp();
App 测试类代码select * from emp where empstate = 1
EmpMapper mapper = session.getMapper(EmpMapper.class); List按照 empno 查询 EmpMapper 接口代码list = mapper.findAllEmp(); for (Emp e : list) { System.out.println(e); }
Emp findEmpByNo(int empNo);EmpMapper.xml 代码 App 测试类代码
EmpMapper mapper = session.getMapper(EmpMapper.class);
Emp emp = mapper.findEmpByNo(7944);
System.out.println("查询的学生是:" + emp);
#{}和${}之间的区别?
按照 ename 模糊查询 EmpMapper 接口代码我们通过日志来观察下#{}和${}的效果。
首先是 #{} 的写法:
select * from emp where empstate = 1 and empno = #{empNo}在控制台的日志信息中会输出如下效果:
其次看看 ${} 的写法:
select * from emp where empstate = 1 and empno = ${empNo}在控制台的日志信息中会输出如下效果:
总结下来它们的区别:
- #{}是预编译处理,是占位符?方式,调用PreparedStatement来赋值,${}是字符串替换,是拼接方式。
- #{}的变量替换是在DBMS中、变量替换后,#{}对应类型的变量自动加上单引号,${}的变量替换是在DBMS外、变量替换后,${}对应类型的变量不会加上单引号。
- 使用#{}可以有效的防止sql注入,提高系统的安全性。
ListEmpMapper.xml 代码findEmpByEname(String ename);
select * from emp where empstate = 1 and ename like #{ename}
思考:这里使用${ename}--->#{ename} 看看效果如何?
App 测试类代码EmpMapper mapper = session.getMapper(EmpMapper.class); List添加员工 EmpMapper 接口代码list = mapper.findEmpByEname("'%关为%'"); for (Emp e : list) { System.out.println(e); } session.close();
void saveEmp(Emp emp);EmpMapper.xml 代码
insert into emp values (null, #{ename}, #{job}, #{mgr}, now(), #{sal}, #{comm}, #{deptNo}, 1)
需要注意的是:#{property} 中的名称对应 Emp 类中的属性,并提供 getter() 方法。
App 测试类代码Emp emp = new Emp(7948, "关为", "奥特曼", 7788, null, 19800.0, 12888.0, 20, 1); SqlSession session = ssf.openSession(); EmpMapper mapper = session.getMapper(EmpMapper.class); mapper.saveEmp(emp); session.commit(); session.close();MyBatis 对于事务的处理
需要注意的是 MyBatis 对于事务默认并不会自动提交, 执行完毕 save、update 或者 delete 方法时并没有实际录入数据库。
手动提交
每次执行完 save、update 或者 delete 方法后调用
session.commit(); // 提交 session.rollback(); // 回滚
设置事务自动提交
在打开 session 设置当前 session 自动提交事务
SqlSession session = ssf.openSession(true);修改员工 EmpMapper 接口代码
void updateEmp(Emp emp);EmpMapper.xml 代码
App 测试类代码update emp set ename=#{ename}, job=#{job}, mgr=#{mgr}, sal=#{sal} where empNo = #{empNo}
SqlSession session = ssf.openSession(); EmpMapper mapper = session.getMapper(EmpMapper.class); mapper.updateEmp(emp); session.commit(); session.close();删除员工
需要注意的是,删除实际上不会执行 delete 语句,而是将状态设置为不可见(0),查询时查询非零数据。
EmpMapper 接口代码void deleteEmp(int empNo);EmpMapper.xml 代码
App 测试类代码update emp set empstate=0 where empno = #{empNo}
SqlSession session = ssf.openSession(); EmpMapper mapper = session.getMapper(EmpMapper.class); mapper.deleteEmp(7788); session.commit(); session.close();分页查询
分页查询主要有两种方式
limit 分页EmpMapper 接口代码
ListfindAllEmpByPage(int start, int size);
EmpMapper.xml 代码
App 测试类代码
SqlSession session = ssf.openSession(); EmpMapper mapper = session.getMapper(EmpMapper.class); List多参数传递问题list = mapper.findAllEmpByPage(0, 5); for (Emp e : list) { System.out.println(e); } session.close();
MyBatis 的 mapper 方法如果形式参数有多个,会出现如下错误
那是因为 java 中传值时只看类型不看名称,MyBatis 并不知道那个参数赋予那个#{},那么我们就需要制定当前参数到底赋予那个#{}即可。
ListPageHelper 分页插件findAllEmpByPage(@Param("start") int start, @Param("size") int size);
引入依赖
com.github.pagehelper pagehelper5.3.0
在 config.xml 中配置 PageHelper 插件
调用全查询方法
EmpMapper mapper = session.getMapper(EmpMapper.class); PageHelper.startPage(1, 5); Listlist = mapper.findAllEmp(); PageInfo pageInfo = new PageInfo<>(list); System.out.println("总条数:" + pageInfo.getTotal()); System.out.println("当前页查询记录:" + pageInfo.getList().size()); System.out.println("当前页码:" + pageInfo.getPageNum()); System.out.println("每页显示数量:" + pageInfo.getPageSize()); System.out.println("总页数:" + pageInfo.getPages()); session.close();
本篇博客我们了解到了单表的 CRUD 操作,下来我们学习高级关联和集合映射的话题--MyBatis 入门到精通(四)



