007 使用MyBatis,easyUI实现CRUD操作样例-R操作(重构)
视频发布在youtube上面了
https://youtu.be/F44LqKdADwE
优酷上面的链接
http://v.youku.com/v_show/id_XMjgwMTQwMzE1Mg==.html?f=49760672
接着006的项目操作。做完007之后,更新了一下模板,当前版本0.0.2
本次先记录获取用户列表部分。这次更新时间间隔比较久,因为接触了新东西,easyUI,jquery,java script,花了些时间。
还有对mybatis的了解更进了一步,学到了更复杂的SQL语句的映射方法。
提供SQL脚本,使用存储过程生成数据
delete from user
DROP PROCEDURE dowhile;
DELIMITER //
DROP PROCEDURE IF EXISTS dowhile //
CREATE PROCEDURE dowhile()
BEGIN
DECLARE age INT DEFAULT 25;
DECLARE i INT DEFAULT 1;
DECLARE teacherId INT DEFAULT 1;
DECLARE gender CHAR(1) charset 'utf8';
WHILE i<=500000 DO
SET age = FLOOR(20+RAND()*15);
SET teacherId = ROUND(RAND()) + 1;
SET gender = SUBSTRING("男女",FLOOR(1+2*RAND()),1);
INSERT INTO USER(id,name,age,email,gender,createTime,loginTime,teacherId) VALUES (i,CONCAT('user',i),age,'user@126.com',gender,current_timestamp(),current_timestamp(),teacherId);
SET i=i+1;
END WHILE;
END;
//
call dowhile();
修改完数据库之后,要修改一下测试类里面的断言判断,改成user1
assertTrue(user.getName().equals("student1"));
HTTP GET 请求/users 返回users列表
HTTP GET 请求/users/1 返回id=1的user信息
HTTP POST 请求/users 带着一个user对象JSON格式创建一个新的user
HTTP PUT 请求/users/1 带着一个user对象JSON格式更新id=1的user信息
HTTP DELETE 请求/users/1 删除id=1的user
这里使用fastjson来处理json相关信息,在springmvc.xml里面添加
<!-- 对于mvc没有映射过的请求,交给容器默认handler来处理,例如:js,css等静态资源 -->
<mvc:default-servlet-handler />
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json"/>
<!--设置fastjson特性-->
<property name="features">
<array>
<!--设置null值也要输出,fastjson默认是关闭的-->
<value>WriteMapNullValue</value>
<!--设置使用文本方式输出日期,fastjson默认是long-->
<value>WriteDateUseDateFormat</value>
</array>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
查询所有信息
涉及到mybatis 1对1联表查询,多对多的复杂查询后面在做练习。
user表中定义的是一个teacherID的外键。
修改user实体类,增加教师对象
/**
* 实现1对1的查询支持
*/
private Teacher teacher;
修改UserMapper和TeacherMapper增加分页查询接口,获取记录个数的接口
/**
* return seleted users by paginition
*
* @return
*/
List<User> selectUsersPaginition(HashMap<String, Integer> offsetLimit);
/**
* return records count
*
* @return
*/
long getCount();
修改对应的mapping里面的UserMapper.xml增加selectUsers等操作,这里的id就是mapper里面新增接口的名字,这里使用了最简单的方式。在学习的过程中了解到还有通用的支持多个数据库的分页插件的方式。暂时先不研究那个了。后期有需要再看。下面是链接
https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md
这里要说明一下,因为数据库表里面user只有teacherId这个外键,所以要在这里特殊处理一下才能获取到类成员对象的属性值。
还遇到一个问题,就是user和teacher表的字段名是相同的,造成映射的时候区分不出来。最好的方法就是建表的时候避免相同的字段名,那么对于已有表可以修改映射文件。
<resultMap id="BaseResultMapRename" type="com.study.model.User">
<id column="uId" jdbcType="BIGINT" property="id" />
<result column="uName" jdbcType="VARCHAR" property="name" />
<result column="uAge" jdbcType="INTEGER" property="age" />
<result column="uEmail" jdbcType="VARCHAR" property="email" />
<result column="uCreateTime" jdbcType="TIMESTAMP" property="createTime" />
<result column="uLoginTime" jdbcType="TIMESTAMP" property="loginTime" />
<result column="uTeacherId" jdbcType="BIGINT" property="teacherId" />
<result column="uGender" jdbcType="VARCHAR" property="gender" />
</resultMap>
<sql id="Base_Column_ListRename">
u.id as uId, u.name as uName, u.age as uAge, u.email as uEmail,
u.createTime as uCreateTime, u.loginTime as uLoginTime, u.teacherId as
uTeacherId, u.gender as uGender
</sql>
<select id="selectUsers" resultMap="UnionResultMap">
select
<include refid="Base_Column_ListRename" />
,
<include refid="com.study.dao.TeacherMapper.Base_Column_ListRename" />
from user u, teacher t
where u.teacherId = t.id order by u.id
</select>
<resultMap id="UnionResultMap" type="com.study.model.User"
extends="BaseResultMapRename">
<association property="teacher" column="teacherId"
javaType="com.study.model.Teacher" resultMap="com.study.dao.TeacherMapper.BaseResultMapRename">
</association>
</resultMap>
<select id="selectUsersPaginition" parameterType="HashMap"
resultMap="UnionResultMap">
select
<include refid="Base_Column_ListRename" />
,
<include refid="com.study.dao.TeacherMapper.Base_Column_ListRename" />
from user u, teacher t
where u.teacherId = t.id order by u.id limit #{offset},#{pagesize}
</select>
<select id="getCount" resultType="long">
select count(*) from user
</select>
teacherMapper.xml里面添加
<resultMap id="BaseResultMapRename" type="com.study.model.Teacher">
<id column="tId" jdbcType="BIGINT" property="id" />
<result column="tName" jdbcType="VARCHAR" property="name" />
<result column="tAge" jdbcType="INTEGER" property="age" />
<result column="tGender" jdbcType="VARCHAR" property="gender" />
<result column="tCreateTime" jdbcType="TIMESTAMP" property="createTime" />
<result column="tLoginTime" jdbcType="TIMESTAMP" property="loginTime" />
<result column="tEmail" jdbcType="VARCHAR" property="email" />
</resultMap>
<sql id="Base_Column_ListRename">
t.id as tId, t.name as tName, t.age as tAge, t.gender as tGender, t.createTime as tCreateTime, t.loginTime as tLoginTime, t.email as tEmail
</sql>
修改IUserService和IUserServiceImpl增加该接口和实现,Teacher也是一样的操作
这里要注意引入的List的包是util里面的
import java.util.List;
public List<User> getUsersPagenition(int page, int rows);
public long getCount();
@Override
public List<User> getUsersPagenition(int page, int rows)
{
HashMap<String, Integer> offsetLimit = new HashMap<String, Integer>();
//page mysql start from 0, param page start from 1
offsetLimit.put("offset", (page - 1) * rows);
offsetLimit.put("pagesize", rows);
return userMapper.selectUsersPaginition(offsetLimit);
}
@Override
public long getCount()
{
return userMapper.getCount();
}
在测试类里面添加代码
@Test
public void TestGetCount()
{
long recordCount = userService.getCount();
logger.info("TestGetCount: " + recordCount);
}
@Test
public void TestGetUsersPaginition()
{
List<User> users = userService.getUsersPagenition(1, 13);
logger.info("TestGetUsersPaginition: " + JSON.toJSONStringWithDateFormat(users,"yyyy-MM-dd HH:mm:ss"));
}
执行后应该可以看到返回的用户信息列表
在index.html里面增加一个超链接,获取所有用户信息的Get请求users
<a href="users">Get Users</a>
<br />
<br />
在Controller类里面,因为要访问数据库,所以需要添加service,同时也把日志类加上,创建Controller,返回users,对应view目录下面的users.jsp
private static final Logger logger = LogManager.getLogger(UserController.class.getName());
@Autowired
IUserService userService;
@RequestMapping(value = "/users", method = RequestMethod.GET)
public String getUsersProc()
{
logger.info("getUsersProc");
return "users";
}
创建一个返回json数据的服务接口getUsers,给easyui调用,这里使用分页查询
jQuery EasyUI向后台请求datagrid(数据表格)时会传递两个参数:
可以根据这两个参数对数据库进行分页查询。
// datagrid请求数据参数:
page:"1", //当前页
rows:"10" //数据条数
@ResponseBody
@RequestMapping(value = "/getUsers", method = RequestMethod.GET)
public JSONObject users(HttpServletRequest request, HttpServletResponse response)
{
int page = ServletRequestUtils.getIntParameter(request, "page", 1);// 默认值为1
int rows = ServletRequestUtils.getIntParameter(request, "rows", 0);
long rowCount = userService.getCount();
List<User> users = userService.getUsersPagenition(page, rows);
JSONObject jsonObject = new JSONObject();
jsonObject.put("rows", users);
jsonObject.put("total", rowCount);
logger.info("getUsers api: page:" + page + " rows:" + rows + "jsonObj:" + jsonObject.toJSONString());
return jsonObject;
}
编辑users.jsp,使用easyui显示数据
在/src/main/webapp目录下面建立/commons/jsExt目录用来放js外部引用的包
把easyui整个目录拷贝过来,然后清理一下不用的目录demo*,src目录,这里使用的是jquery-easyui-1.5.2版本
在users.jsp里面添加引用
...
<!-- 下面两个必须引用 -->
<script type="text/javascript"
src="commons/jsExt/jquery-easyui-1.5.2/jquery.min.js"></script>
<script type="text/javascript"
src="commons/jsExt/jquery-easyui-1.5.2/jquery.easyui.min.js"></script>
<!-- 国际化文件 -->
<script type="text/javascript"
src="commons/jsExt/jquery-easyui-1.5.2/locale/easyui-lang-zh_CN.js"></script>
<!-- 默认样式 -->
<link rel="stylesheet"
href="commons/jsExt/jquery-easyui-1.5.2/themes/default/easyui.css">
<!-- 图标 -->
<link rel="stylesheet"
href="commons/jsExt/jquery-easyui-1.5.2/themes/icon.css">
</head>
body里面添加数据表格控件,这里高度使用100%的时候只有表头显示出来了,不知道为什么,所以使用绝对值定义。
<body>
<div class="easyui-layout" style="margin: 20px 20px 20px 20px;">
<table id="dg" class="easyui-datagrid" title="用户列表"
style="width: 100%; height: 400px;"
data-options="rownumbers:true,striped:true,fitColumns:true,singleSelect:true,autoRowHeight:true,pagination:true,
pageSize:10,url:'${pageContext.request.contextPath}/getUsers',method:'get',toolbar:'#toolbar'">
<thead>
<tr>
<th data-options="field:'id',width:100">ID</th>
<th data-options="field:'name',width:100">name</th>
<th data-options="field:'age',width:100">Age</th>
<th data-options="field:'gender',width:60">Gender</th>
<th data-options="field:'email',width:150">Email</th>
<th data-options="field:'createTime',width:150">Create Time</th>
<th data-options="field:'loginTime',width:150">Login Time</th>
<th data-options="field:'teacher',width:100" formatter="teacherFormatter">Teacher Name</th>
</tr>
</thead>
</table>
<div id="toolbar">
<a href="#" class="easyui-linkbutton"
data-options="iconCls:'icon-add'" onclick="insert()">添加</a> <a
href="#" class="easyui-linkbutton"
data-options="iconCls:'icon-edit'" onclick="edit()">编辑</a> <a
href="#" class="easyui-linkbutton"
data-options="iconCls:'icon-remove'" onclick="del()">删除</a>
</div>
</div>
</body>
这里有个需要注意的地方,就是teacher是一个类对象,使用了formatter来格式化输出teacher的名字。在commons目录下面建立一个js目录,建立teacherFormatter.js文件
function teacherFormatter(val,row)
{
return row.teacher.name;
}
然后别忘了要添加刚刚创立的js文件
...
<!-- 自定义js -->
<script type="text/javascript" src="commons/js/teacherFormatter.js"></script>
</head>
添加到tomcat之后,打开chrome访问http://localhost:8190/template/
command+alt+i打开开发者工具
点击Get Users就会打开用户列表页面。
如果有需要交流的,或者有更好的实现方法的同学,欢迎通过电子邮件来互通有无,共同进步。
ascomtohom@126.com