008 使用MyBatis,easyUI实现CRUD操作样例-CUD
视频发布在youtube上面了
https://youtu.be/EaT-EpD-1fM
优酷上面的链接
http://v.youku.com/v_show/id_XMjgwODcyNzg5Ng==.html?f=49760672
接着007的项目操作。
数据库的主键改为自增,主键的相关处理这里不是重点。
添加信息
HTTP POST 请求/users 带着一个user对象JSON格式创建一个新的user
- 显示添加页面Get请求 Uri: user
- 提交添加信息POST请求 Uri: user
body里面添加addUser对话框
...
<!-- create user dialog -->
<div id="dlg" class="easyui-dialog"
data-options="iconCls:'icon-save',resizable:true,modal:true"
style="width: 400px; height: 280px; padding: 10px 20px" closed="true"
buttons="#dlg-buttons">
<div class="ftitle">用户信息</div>
<form id="fm" method="post">
<div class="fitem">
<label for="name">用户名:</label> <input name="name"
class="easyui-validatebox" type="text" data-options="required:true">
</div>
<div class="fitem">
<label for="age">年 龄:</label> <input name="age"
class="easyui-numberbox" type="text"
data-options="required:true,validType:'number'">
</div>
<div class="fitem">
<label for="gender">性 别:</label> <input id="state1" name="gender"
value="男" type="radio" checked="true" />男 <input id="state2"
name="gender" value="女" type="radio" />女
</div>
<div class="fitem">
<label for="email">Email:</label> <input name="email"
class="easyui-validatebox" type="text"
data-options="required:true,validType:'email'">
</div>
<div class="fitem">
<label for="teacherId">教 师:</label> <input id="cc"
class="easyui-combobox" name="teacherId"
data-options="valueField:'id',textField:'name',panelHeight:80,editable:false,method:'get',url:'${pageContext.request.contextPath}/getTeacherComboData'">
</div>
</form>
</div>
<div id="dlg-buttons">
<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-ok'"
onclick="save()">Save</a> <a href="#" class="easyui-linkbutton"
data-options="iconCls:'icon-cancel'"
onclick="javascript:$('#dlg').dialog('close')">Cancel</a>
</div>
</body>
然后添加ITeacherService接口,给Controller使用。
public Teacher getTeacherById(long id);
public List<Teacher> getTeachers();
修改teacherMapper添加Dao操作
/**
* Select all teachers
* @return
*/
List<Teacher> selectTeachers();
修改TeacherMapper.xml增加getTeachers映射
<select id="selectTeachers" resultMap="BaseResultMap">
select * from teacher
</select>
添加实现类ITeacherServiceImpl
@Service("teacherService")
@Transactional
public class ITeacherServiceImpl implements ITeacherService
{
@Autowired
TeacherMapper teacherMapper;
@Override
public List<Teacher> getTeachers()
{
return teacherMapper.selectTeachers();
}
@Override
public Teacher getTeacherById(long id)
{
return teacherMapper.selectByPrimaryKey(id);
}
}
添加TeacherController实现easyUI需要的数据接口
@Controller
public class TeacherController
{
private static final Logger logger = LogManager.getLogger(TeacherController.class.getName());
@Autowired
ITeacherService teacherService;
@ResponseBody
@RequestMapping(value = "/getTeacherComboData", method = RequestMethod.GET)
public List<Teacher> teachers(HttpServletRequest request, HttpServletResponse response)
{
List<Teacher> teachers = teacherService.getTeachers();
logger.info("getUsers api jsonObj:" + JSON.toJSONString(teachers));
return teachers;
}
}
/src/main/webapp/commons/js目录下新建commons.js获取项目路径,网上找的代码,注释信息保留了。
/*!
* imalex@163.com - v0.1 (2015-08-29 18:00:00 +0800)
* Copyright 2015
*/
var ctx=getBasePath();
function getBasePath(){
var obj=window.location;
var contextPath=obj.pathname.split("/")[1];
var basePath=obj.protocol+"//"+obj.host+"/"+contextPath;
return basePath;
}
// 格式化日期
Date.prototype.Format = function (fmt) {
var o = {
"y+": this.getFullYear(),
"M+": this.getMonth() + 1, // 月份
"d+": this.getDate(), // 日
"h+": this.getHours(), // 小时
"m+": this.getMinutes(), // 分
"s+": this.getSeconds(), // 秒
"q+": Math.floor((this.getMonth() + 3) / 3), // 季度
"S+": this.getMilliseconds() // 毫秒
};
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)){
if(k == "y+"){
fmt = fmt.replace(RegExp.$1, ("" + o[k]).substr(4 - RegExp.$1.length));
}
else if(k=="S+"){
var lens = RegExp.$1.length;
lens = lens==1?3:lens;
fmt = fmt.replace(RegExp.$1, ("00" + o[k]).substr(("" + o[k]).length - 1,lens));
}
else{
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
}
return fmt;
}
新建目录/src/main/webapp/commons/js/user
在user目录下新建userOper.js脚本处理增加,删除,修改操作
/*!
* imalex@163.com - v0.1 (2015-08-29 18:00:00 +0800)
* Copyright 2015
*/
$(function() {
});
function insert() {
$('#dlg').dialog('open').dialog('setTitle', '新建用户');
$('#fm').form('clear');
url = ctx + '/users';
type = insert;
}
function edit() {
var row = $('#dg').datagrid('getSelected');
if (row) {
$('#dlg').dialog('open').dialog('setTitle', '编辑用户信息');
$('#fm').form('load', row);
//setCheckedValue(document.forms['fm'].elements['gender'], row['gender']);
url = 'users/' + row.id;
type = edit;
}
}
function save() {
$('#fm').form('submit', {
url : url,
type:type,
onSubmit : function(param) {
if (type == edit) {
//use put
param._method ='PUT';
}
param.createTime = new Date().Format("yyyy-MM-dd hh:mm:ss");
param.loginTime = param.createTime;
var ret = $(this).form('validate');
return ret;
},
success : function(result) {
var result = eval('(' + result + ')');
if (result.errorMsg) {
$.messager.show({
title : 'Error',
msg : result.errorMsg
});
} else {
$('#dlg').dialog('close'); // close the dialog
$('#dg').datagrid('reload'); // reload the user data
}
}
});
}
function del() {
var row = $('#dg').datagrid('getSelected');
if (row) {
$.messager.confirm('确认', '请确认删除已选择用户?', function(r) {
if (r) {
$.post('users/' + row.id, {
_method : 'DELETE'
}, function(result) {
if (result.status != null) {
$('#dg').datagrid('reload'); // reload the user data
} else {
$.messager.show({ // show error message
title : 'Error',
msg : result.errorMsg
});
}
}, 'json');
}
});
}
}
新建目录/src/main/webapp/commons/css,下面新建user.css用于格式化新建用户对话框的各个元素
<style type="text/css">
#fm {
margin: 0;
padding: 10px 30px;
}
.ftitle {
font-size: 14px;
font-weight: bold;
color: #666;
padding: 5px 0;
margin-bottom: 10px;
border-bottom: 1px solid #ccc;
}
.fitem {
margin-bottom: 5px;
}
.fitem label {
display: inline-block;
width: 80px;
}
</style>
引入自定义的脚本和css样式
...
<!-- 自定义的js脚本 -->
<script type="text/javascript" src="commons/js/commons.js"></script>
<script type="text/javascript" src="commons/js/user/userOper.js"></script>
<link rel="stylesheet" href="commons/css/user.css">
</head>
IUserService和实现类增加插入用户的接口和实现代码
public int insertUser(User usr);
@Override
public int insertUser(User usr)
{
return userMapper.insert(usr);
}
UserController增加POST响应代码处理增加用户操作,这里使用POJO对象绑定请求参数值,spring会按照参数名和属性名自动匹配填充。
@Autowired
ITeacherService teacherService;
@RequestMapping(value = "/users", method = RequestMethod.POST)
@ResponseBody
public Object addUsersProc(User user)
{
// 处理新id生成
// 处理teacher类对象
user.setTeacher(teacherService.getTeacherById(user.getTeacherId()));
int iRet = userService.insertUser(user);
long newId = user.getId();
Map<String, Object> map = new HashMap<String, Object>();
if (iRet == 0)
{
logger.info("addUsersProc: " + JSON.toJSON("新建失败:" + JSON.toJSONStringWithDateFormat(user, "yyyy-MM-dd HH:mm:ss")));
map.put("status", "新建失败");
map.put("retCode", -1);
} else
{
logger.info("addUsersProc: " + JSON.toJSON("新建用户:" + JSON.toJSONStringWithDateFormat(user, "yyyy-MM-dd HH:mm:ss")));
map.put("status", "新建成功");
map.put("retCode", 0);
}
return map;
}
UserMapper.xml里面insert要添加一些配置,才会返回自增的ID,使用实体类的xx.GetId()来获取。
<insert id="insert" parameterType="com.study.model.User" useGeneratedKeys="true" keyProperty="id">
...
条件表单是字符串类型,实体类里面的日期是Date类型,涉及到了类型转换的处理。否则会遇到spring mvc form提交数据报400错误。
提交form表单报这个错误,有可能是你的controller接收数据类型与前台传递类型不符。例如前台传递String 后台用Date接受,就会报这个错误。
新建一个包com.study.converters
新建一个类DateTimeConverter实现spring的springframework.core.convert接口
@Component
public class DateTimeConverter implements Converter<String, Date>
{
@Override
public Date convert(String source)
{
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try
{
date = df.parse(source);
} catch (ParseException e)
{
e.printStackTrace();
}
return date;
}
}
配置springmvc.xml使converter生效
<!-- 配置自动扫描的包 -->
<context:component-scan
base-package="com.study.controller,com.study.service,com.study.converters"></context:component-scan>
...
<!-- 对于mvc没有映射过的请求,交给容器默认handler来处理,例如:js,css等静态资源 -->
<mvc:default-servlet-handler />
<mvc:annotation-driven conversion-service="conversionService">
...
</mvc:annotation-driven>
<!-- 配置转换服务 <mvc:annotation-driven conversion-service="conversionService"> -->
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<!-- 自定义的转换类,首字母小写 -->
<ref bean="dateTimeConverter" />
</set>
</property>
</bean>
还有关于前台传数据到后台中文的乱码问题需要处理一下,在web.xml文件中添加配置,filter是有顺序的,这个最好放在最前面
<!-- 解决中文乱码问题,将参数编码为utf-8 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
现在执行添加用户,应该能看到记录数有所增加。
删除信息
HTTP DELETE 请求/users/1 删除id=1的user
添加UserService接口和实现
public int deleteById(String id);
@Override
public int deleteById(String id)
{
return userMapper.deleteByPrimaryKey(Long.parseLong(id));
}
UserController里面添加响应代码
@RequestMapping(value = "/users/{id}", method = RequestMethod.DELETE)
@ResponseBody
public Object deleteUserProc(@PathVariable("id") String id)
{
int iRet = userService.deleteById(id);
Map<String, Object> map = new HashMap<String, Object>();
if (iRet == 0)
{
logger.error("deleteUserProc: 删除失败");
map.put("status", "删除失败");
map.put("retCode", -1);
} else
{
logger.info("deleteUserProc: 删除成功");
map.put("status", "删除成功");
map.put("retCode", 0);
}
return map;
}
因为HiddenHttpMethodFilter的参数是
public static final String DEFAULT_METHOD_PARAM = “_method”;
所以说要把post请求转换成其他请求,提交的参数名就必须指定_method
而参数值必须是要转换的请求形式,这里是DELETE
修改信息
/users/1 PUT 更新资源 id=1
修改service增加更新接口
public int updateById(User user);
@Override
public int updateById(User user)
{
return userMapper.updateByPrimaryKey(user);
}
UserController里面增加响应处理
@RequestMapping(value = "/users/{id}", method = RequestMethod.PUT)
@ResponseBody
public Object updateUserProc(@PathVariable("id") long id,
User user)
{
int iRet = userService.updateById(user);
Map<String, Object> map = new HashMap<String, Object>();
if (iRet == 0)
{
logger.error("updateUserProc: 更新失败");
map.put("status", "更新失败");
map.put("retCode", -1);
} else
{
logger.info("updateUserProc: 更新成功");
map.put("status", "更新成功");
map.put("retCode", 0);
}
return map;
}
现在可以操作了。RESTFul风格的CRUD功能基本上就实现完毕了。