MyBatis从入门到精通(第9章):Spring集成MyBatis(下)
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-width: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
MyBatis从入门到精通(第9章):Spring集成MyBatis(下)的更多相关文章
- MyBatis从入门到精通(第5章):5.4 Example 介绍
jdk1.8.MyBatis3.4.6.MySQL数据库5.6.45.Eclipse Version: 2019-12 M2 (4.14.0) MyBatis从入门到精通(第5章):MyBatis代码 ...
- MyBatis从入门到精通(第9章):Spring集成MyBatis(中)
MyBatis从入门到精通(第9章):Spring集成MyBatis(中) 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法.应该将应用自身的设计和具体 ...
- MyBatis从入门到精通(第9章):Spring集成MyBatis(上)
MyBatis从入门到精通(第9章):Spring集成MyBatis(上) Spring是一个为了解决企业级Web应用开发过程中面临的复杂性,而被创建的一个非常流行的轻量级框架. mybatis-sp ...
- MyBatis从入门到精通(第5章):MyBatis代码生成器
jdk1.8.MyBatis3.4.6.MySQL数据库5.6.45.Eclipse Version: 2019-12 M2 (4.14.0) MyBatis从入门到精通(第5章):MyBatis代码 ...
- MyBatis从入门到精通(第6章):MyBatis 高级查询->6.1.1高级结果映射之一对一映射
jdk1.8.MyBatis3.4.6.MySQL数据库5.6.45.IntelliJ IDEA 2019.2.4 本章主要包含的内容为 MyBatis 的高级结果映射,主要处理数据库一对一.一对多的 ...
- MyBatis从入门到精通(第3章):MyBatis注解方式的基本使用
MyBatis 注解方式就是将 SQL 语句直接写在DAO层的接口上. 在黑马录制的2018年双元视频课:\08 SSM整合案例[企业权限管理系统]\07.订单操作 有使用MyBatis注解进行多表 ...
- MyBatis从入门到精通(第6章):MyBatis 高级查询->6.1.2高级结果映射之一对多映射
jdk1.8.MyBatis3.4.6.MySQL数据库5.6.45.IntelliJ IDEA 2019.3.1 本章主要包含的内容为 MyBatis 的高级结果映射,主要处理数据库一对一.一对多的 ...
- MyBatis从入门到精通(第4章):MyBatis动态SQL【foreach、bind、OGNL用法】
(第4章):MyBatis动态SQL[foreach.bind.OGNL用法] 4.4 foreach 用法 SQL 语句中有时会使用 IN 关键字,例如 id in (1,2,3).可以使用 ${i ...
- MyBatis从入门到精通(第4章):MyBatis动态SQL【if、choose 和 where、set、trim】
(第4章):MyBatis动态SQL[if.choose 和 where.set.trim] MyBatis 的强大特性之一便是它的动态 SQL.MyBatis 3.4.6版本采用了功能强大的OGNL ...
随机推荐
- Spark 2.x Troubleshooting Guide
IBM在spark summit上分享的内容,包括编译spark源码,运行spark时候常见问题(缺包.OOM.GC问题.hdfs数据分布不均匀等),spark任务堆/thread dump 目录 编 ...
- [题解] LuoguP6071 [MdOI2020] Treequery
传送门 感觉这是一个写的很舒服的题? 树上路径的交什么的就很想树上差分?发现根本没法做...它还要求在线.... 好先来看\(Subtask\)吧\(qwq\)... Subtask 1 \(l=r\ ...
- 二、【未来】React环境安装:npx
搭建React的开发环境的第二种方法(新-未来推荐): https://reactjs.org/docs/create-a-new-react-app.html 一. npx简介: 1. npm v5 ...
- dp学习笔记(各种dp,比较杂)
HDU1176 中文题意不多解释了. 建一个二维dp数组,dp[ i ][ j ]表示第 i 秒落在 j 处一个馅饼.我们需要倒着DP,为什么呢,从 0秒,x=5处出发,假如沿数组正着往下走,终点到哪 ...
- mui下拉刷新 上拉加载
a页面是父页面 b页面是子页面 在b页 html+ js+ 下拉和上拉执行的函数就不贴了 .在这个过程中还遇到了个问题就是刷新的图标偏上 需要改变其高度,需要在a页面里面去改变刷新图标的样式 本文 ...
- Innodb特性以及实现原理
Innodb五大特性 1.insert buffer2.double write3.自适应哈希索引4.异步io5.邻接页刷新 1.insert buffer(change buffer) 作用:将非聚 ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 数据类型
使用编程语言进行编程时,需要用到各种变量来存储各种信息.变量保留的是它所存储的值的内存位置.这意味着,当创建一个变量时,就会在内存中保留一些空间. 可能需要存储各种数据类型(比如字符型.宽字符型.整型 ...
- PAT Advanced 1076 Forwards on Weibo (30) [图的遍历,BFS,DFS]
题目 Weibo is known as the Chinese version of Twitter. One user on Weibo may have many followers, and ...
- openstack trove mongodb配置项
systemLog.verbosity 组件的默认日志消息详细程度级别. 详细程度级别决定MongoDB输出的信息和调试消息量. 详细级别可以在0到5之间: 0是MongoDB的默认日志详细程度级别, ...
- SpringCloud学习之Stream消息驱动【自定义通道】(十一)
如果不清楚本篇内容的,请务必先去看完上一篇再看本篇,否则阅读起来可能会有部分障碍和困难: 上一篇文章<SpringCloud学习之Stream消息驱动[默认通道](十)>我们简单用自定义通 ...