MyBatis从入门到精通(第9章):Spring集成MyBatis(下)
springmvc执行流程原理
- mybatis-spring 可以帮助我们将MyBatis代码无缝整合到Spring中。使用这个类库中的类,Spring将会加载必要的MyBatis工厂类和Session类。
- MyBatis Spring Adapter项目地址为: https://github.com/mybatis/spring
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.3</version> </dependency>
9.4.3 开发业务层(Service层)
虽然针对接口编程对小的项目来说并不重要,但是这里为了形式上的需要仍然提供了Service接口。
在 src/main/java 中新建 cn.bjut.mybatis.web.service 包,然后添加 DictService接口,代码如下。
package cn.bjut.mybatis.web.service; import cn.bjut.mybatis.web.model.SysDict; import java.util.List; /** * @author kangmianfeng */ public interface DictService { SysDict findById(Long id); List<SysDict> findBySysDict(SysDict sysDict, Integer offset, Integer limit); boolean saveOrUpdate(SysDict sysDict); boolean deleteById(Long id); }
Service层的 saveOrUpdate 方法对应DAO层的 Mapper 中的insert和updateById方法,其他3个方法和DAO层的方法一 一对应。
在 cn.bjut.mybatis.web.service 包下创建 impl包,然后新建 DictService接口的实现类 DictServiceImpl,代码如下。
package cn.bjut.mybatis.web.service.Impl; import cn.bjut.mybatis.web.mapper.DictMapper; import cn.bjut.mybatis.web.model.SysDict; import cn.bjut.mybatis.web.service.DictService; import org.apache.ibatis.session.RowBounds; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * @author kangmianfeng */ @Service public class DictServiceImpl implements DictService { @Autowired private DictMapper dictMapper; @Override public SysDict findById(Long id) { return dictMapper.selectByPrimaryKey(id); } public List<SysDict> findBySysDict(SysDict sysDict, Integer offset, Integer limit) { RowBounds rowBounds = RowBounds.DEFAULT; if(offset != null && limit != null){ rowBounds = new RowBounds(offset, limit); } return dictMapper.selectBySysDict(sysDict, rowBounds); } @Override public boolean saveOrUpdate(SysDict sysDict) { if(sysDict.getId() == null){ return dictMapper.insert(sysDict) == 1; } else { return dictMapper.updateById(sysDict) == 1; } } @Override public boolean deleteById(Long id) { if(id == null){ throw new NullPointerException("id"); } return dictMapper.deleteById(id) == 1; } }
Service的实现类中需要添加 @Service注解,在9.2节集成Spring时配置过“自动扫描包”,包名是 cn.bjut.mybatis.web.service.impl ,
DictServiceImpl实现类所在的包就是符合这个包名规则的,加上注解后,Spring在初始化时就会扫描到这个类,然后由Spring管理这个类。
因为配置了自动扫描Mapper接口,所以在 Service层 可以直接通过以下代码 注入Mapper 。
@Autowired
private DictMapper dictMapper;
9.4.4 开发控制层(Controller层)
在 cn.bjut.mybatis.web.controller 包下,新建 DictController类,代码如下。
package cn.bjut.mybatis.web.controller; import cn.bjut.mybatis.web.model.SysDict; import cn.bjut.mybatis.web.service.DictService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import java.util.List; /** * @author kangmianfeng */ @Controller @RequestMapping("/dicts") public class DictController { @Autowired private DictService dictService; /** * 显示字典数据列表 * * @param sysDict * @param offset * @param limit * @return */ @RequestMapping public ModelAndView dicts(SysDict sysDict, Integer offset, Integer limit) { ModelAndView mv = new ModelAndView("dicts"); List<SysDict> dicts = dictService.findBySysDict(sysDict, offset, limit); mv.addObject("dicts", dicts); return mv; } /** * 新增或修改字典信息页面,使用 get 跳转到页面 * * @param id * @return */ @RequestMapping(value = "add", method = RequestMethod.GET) public ModelAndView add(Long id) { ModelAndView mv = new ModelAndView("dict_add"); SysDict sysDict; if(id == null){ //如果 id 不存在,就是新增数据,创建一个空对象即可 sysDict = new SysDict(); } else { //如果 id 存在,就是修改数据,把原有的数据查询出来 sysDict = dictService.findById(id); } mv.addObject("model", sysDict); return mv; } /** * 新增或修改字典信息,通过表单 post 提交数据 * * @param sysDict * @return */ @RequestMapping(value = "add", method = RequestMethod.POST) public ModelAndView save(SysDict sysDict) { ModelAndView mv = new ModelAndView(); try { dictService.saveOrUpdate(sysDict); mv.setViewName("redirect:/dicts"); } catch (Exception e){ mv.setViewName("dict_add"); mv.addObject("msg", e.getMessage()); mv.addObject("model", sysDict); } return mv; } /** * 通过 id 删除字典信息 * * @param id * @return */ @RequestMapping(value = "delete", method = RequestMethod.POST) @ResponseBody public ModelMap delete(@RequestParam Long id) { ModelMap modelMap = new ModelMap(); try { boolean success = dictService.deleteById(id); modelMap.put("success", success); } catch (Exception e) { modelMap.put("success", false); modelMap.put("msg", e.getMessage()); } return modelMap; } }
上面这段代码中使用了两个视图,分别为dicts和dict_add。在下一节中,我们将继续编写视图层代码。
9.4.5 开发视图层(View层)
按照9.2节中的视图配置,需要在 src/main/webapp下面的WEB-INF中 创建jsp目录,然后在jsp中创建 dicts.jsp和dict_add.jsp ,
dicts.jsp代码如下。
<%@ page language="java" contentType="text/html; charset=UTF8" pageEncoding="UTF8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <c:set var="path" value="${pageContext.request.contextPath}"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF8"> <title>字典信息</title> <script src="${path}/static/jquery-3.1.1.min.js"></script> </head> <body> <table> <tr> <th colspan="4">字典管理</th> </tr> <tr> <th>类别名</th> <th>字典名</th> <th>字典值</th> <th> 操作 [<a href="${path}/dicts/add">新增</a>]</th> </tr> <c:forEach items="${dicts}" var="dict"> <tr id="dict-${dict.id}"> <td>${dict.code}</td> <td>${dict.name}</td> <td>${dict.value}</td> <td> [<a href="${path}/dicts/add?id=${dict.id}">编辑</a>] [<a href="javascript:;" onclick="deleteById(${dict.id}, '${dict.name}')">删除</a>] </td> </tr> </c:forEach> </table> <script> function deleteById(id, label){ var r = confirm('您确定要删除“' + label + '”吗?'); if(r){ $.ajax({ url: '${path}/dicts/delete', data: { id: id }, dataType: 'json', type: 'POST', success: function(data){ if(data.success){ $('#dict-' + id).remove(); } else { alert(data.msg); } } }) } } </script> </body> </html>
dict_add.jsp代码如下。
<%@ page language="java" contentType="text/html; charset=UTF8" pageEncoding="UTF8" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <c:set var="path" value="${pageContext.request.contextPath}"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF8"> <title>字典维护</title> </head> <body> <form action="${path}/dicts/add" method="post"> <input type="hidden" name="id" value="${model.id}"> <table> <c:if test="${msg != null}"> <tr> <th colspan="2" style="color:red;max-400px;">${msg}</th> </tr> </c:if> <tr> <th colspan="2">字典维护</th> </tr> <tr> <th>类别名</th> <td><input type="text" name="code" value="${model.code}"></td> </tr> <tr> <th>字典名</th> <td><input type="text" name="name" value="${model.name}"></td> </tr> <tr> <th>字典值</th> <td><input type="text" name="value" value="${model.value}"></td> </tr> <tr> <th colspan="2"> <input type="submit" value="保存"> <input type="button" onclick="backToList()" value="取消"> </th> </tr> </table> </form> <script> function backToList(){ location.href = '${path}/dicts'; } </script> </body> </html>
dicts.jsp 代码中使用了 jquery-3.1.1.min.js ,大家可以从地址 https://code.jquery.com/jquery-3.1.1.min.js 中下载jQuery, 然后放在 webapp/static/ 目录里面。
9.4.6 部署和运行应用
将项目部署到Tomcat下,然后启动服务。服务器启动完成后,在浏览器中输入 http://localhost:8080/mybatis-spring/dicts 并访问,
简单的字典管理操作界面便实现了。
熟练掌握基础功能开发后,结合前面几章学习的MyBatis的各种技巧后,我们就能实现各种各样的功能了。
注意:由于我们使用的是代理 Dao 的模式,Dao 具体实现类由 MyBatis 使用动态代理方式创建,所以此时mybatis 配置文件不能删。
当我们整合 spring 和 mybatis 时,mybatis 创建的 Mapper.xml 文件名必须和 Dao接口 文件名一致 。
====================
end