上一篇博客的传送门:MyBatis 入门到精通(二)
在之前的博客中,我们讲解了 MyBatis 的基本概念、配置文件和基本的环境搭建。下面我们通过七个方法来讲解通过 Mapper 接口方法调用的 XML 形式实现增删改查。
基本的环境搭建我这里不再重复讲解了,忘记的童鞋可以查看 MyBatis 入门到精通(一)的环境搭建部分。我们以 Emp 表结构为蓝本讲解。
全表查询
EmpMapper 接口代码
List<Emp> findAllEmp();
EmpMapper.xml 代码
<select id="findAllEmp" resultType="com.dailyblue.java.mybatis.bean.Emp">
select * from emp where empstate = 1
</select>
App 测试类代码
EmpMapper mapper = session.getMapper(EmpMapper.class);
List<Emp> list = mapper.findAllEmp();
for (Emp e : list) {
System.out.println(e);
}
按照 empno 查询
EmpMapper 接口代码
Emp findEmpByNo(int empNo);
EmpMapper.xml 代码
<select id="findEmpByNo" parameterType="_int" resultType="com.dailyblue.java.mybatis.bean.Emp">
select * from emp where empstate = 1 and empno = #{empNo}
</select>
App 测试类代码
EmpMapper mapper = session.getMapper(EmpMapper.class);
Emp emp = mapper.findEmpByNo(7944);
System.out.println("查询的学生是:" + emp);
#{}和${}之间的区别?
我们通过日志来观察下#{}和${}的效果。
首先是 #{} 的写法:
select * from emp where empstate = 1 and empno = #{empNo}
在控制台的日志信息中会输出如下效果:
其次看看 ${} 的写法:
select * from emp where empstate = 1 and empno = ${empNo}
在控制台的日志信息中会输出如下效果:
总结下来它们的区别:
- #{}是预编译处理,是占位符?方式,调用PreparedStatement来赋值,${}是字符串替换,是拼接方式。
- #{}的变量替换是在DBMS中、变量替换后,#{}对应类型的变量自动加上单引号,${}的变量替换是在DBMS外、变量替换后,${}对应类型的变量不会加上单引号。
- 使用#{}可以有效的防止sql注入,提高系统的安全性。
按照 ename 模糊查询
EmpMapper 接口代码
List<Emp> findEmpByEname(String ename);
EmpMapper.xml 代码
<select id="findEmpByEname" resultType="com.dailyblue.java.mybatis.bean.Emp" parameterType="java.lang.String">
select *
from emp
where empstate = 1
and ename like #{ename}
</select>
思考:这里使用${ename}--->#{ename} 看看效果如何?
App 测试类代码
EmpMapper mapper = session.getMapper(EmpMapper.class);
List<Emp> list = mapper.findEmpByEname("'%关为%'");
for (Emp e : list) {
System.out.println(e);
}
session.close();
添加员工
EmpMapper 接口代码
void saveEmp(Emp emp);
EmpMapper.xml 代码
<insert id="saveEmp" parameterType="com.dailyblue.java.mybatis.bean.Emp">
insert into emp
values (null, #{ename}, #{job}, #{mgr}, now(), #{sal}, #{comm}, #{deptNo}, 1)
</insert>
需要注意的是:#{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 代码
<update id="updateEmp" parameterType="com.dailyblue.java.mybatis.bean.Emp">
update emp
set ename=#{ename},
job=#{job},
mgr=#{mgr},
sal=#{sal}
where empNo = #{empNo}
</update>
App 测试类代码
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 代码
<delete id="deleteEmp" parameterType="_int">
update emp set empstate=0 where empno = #{empNo}
</delete>
App 测试类代码
SqlSession session = ssf.openSession();
EmpMapper mapper = session.getMapper(EmpMapper.class);
mapper.deleteEmp(7788);
session.commit();
session.close();
分页查询
分页查询主要有两种方式
limit 分页
EmpMapper 接口代码
List<Emp> findAllEmpByPage(int start, int size);
EmpMapper.xml 代码
<select id="findAllEmpByPage" resultType="com.dailyblue.java.mybatis.bean.Emp">
select *
from emp
where empstate = 1
limit #{start},#{size}
</select>
App 测试类代码
SqlSession session = ssf.openSession();
EmpMapper mapper = session.getMapper(EmpMapper.class);
List<Emp> list = mapper.findAllEmpByPage(0, 5);
for (Emp e : list) {
System.out.println(e);
}
session.close();
多参数传递问题
MyBatis 的 mapper 方法如果形式参数有多个,会出现如下错误
那是因为 java 中传值时只看类型不看名称,MyBatis 并不知道那个参数赋予那个#{},那么我们就需要制定当前参数到底赋予那个#{}即可。
List<Emp> findAllEmpByPage(@Param("start") int start, @Param("size") int size);
PageHelper 分页插件
引入依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.0</version>
</dependency>
在 config.xml 中配置 PageHelper 插件
<!--分页插件拦截器-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!--reasonable:分页合理化参数,默认值为false。
当该参数设置为 true 时,pageNum<=0 时会查询第一页,
pageNum>pages(超过总数时),会查询最后一页。
默认false 时,直接根据参数进行查询。-->
<property name="reasonable" value="true"/>
</plugin>
</plugins>
调用全查询方法
EmpMapper mapper = session.getMapper(EmpMapper.class);
PageHelper.startPage(1, 5);
List<Emp> list = mapper.findAllEmp();
PageInfo<Emp> 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 入门到精通(四)