员工信息管理系统
SSM-CRUD
这个系统用的是spring、springMVC和mybatis做基本框架,前台用BootStrap进行设计。在创建时由于手动找jar包态麻烦了,影响开发效率,所以我就用Maven 来管理项目结构。
主要的功能就是对员工信息进行添加,修改,分页查询和单个及批量删除
由于查询的时候带上了分页功能,这里就主要说一下查询。
第一:查询
• 1、项目在运行时,index页面直接发送带分页的查询员工列表的ajax请求
主回调函数如下:
$(function(){
//去首页
to_page(1);
});
function to_page(pn){
$.ajax({
url:"${APP_PATH}/emps",
data:"pn="+pn,
type:"GET",
success:function(result){
//console.log(result);
//1、解析json,并显示员工数据
build_emps_table(result);
//2、解析并显示分页信息
build_page_info(result);
//3、解析显示分页条数据
build_page_nav(result);
}
});
}
• 2、前端控制器收到该请求时,先根据url调用映射器,生成处理器对象和拦截器
<!-- springMvc前端控制器,拦截所有请求 -->
<!-- 创建dispatcherServlet-servlet.xml -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- springMvc前端控制器,拦截所有请求 -->
<!-- 创建dispatcherServlet-servlet.xml -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
• 3、然后持久层Mapper通过写灵活的sql片段以及resultMap来与底层对接
<!-- 关联查询结果集 -->
<!-- 查询员工关联相应部门信息 -->
<resultMap id="WithDeptResultMap" type="com.mybag.bean.Employee" >
<id column="emp_id" jdbcType="INTEGER" property="empId" />
<result column="emp_name" jdbcType="VARCHAR" property="empName" />
<result column="gender" jdbcType="CHAR" property="gender" />
<result column="email" jdbcType="VARCHAR" property="email" />
<result column="d_id" jdbcType="INTEGER" property="dId" />
<!-- 关联department信息 指定联合查询出的字段信息封装 -->
<association property="department" javaType="com.mybag.bean.Department">
<id column="dept_id" property="deptId" />
<result column="dept_name" property="deptName" />
</association>
</resultMap>
<!-- sql片段 -->
<sql id="WithDept_Column_List">
e.emp_id, e.emp_name, e.gender, e.email, e.d_id,d.dept_id,d.dept_name
</sql>
<!-- 希望根据条件查询员工的同时,相对应的部门信息也能够被查询出来 -->
<select id="selectByExampleWithDept" resultMap="WithDeptResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="WithDept_Column_List" />
FROM tbl_emp e
left join tbl_dept d on e.`d_id`=d.`dept_id`
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<!-- 按主键查询,相应的外键信息也能够查询出来 -->
<select id="selectByPrimaryKeyWithDept" resultMap="WithDeptResultMap">
select
<include refid="WithDept_Column_List" />
FROM tbl_emp e
left join tbl_dept d on e.`d_id`=d.`dept_id`
where emp_id = #{empId,jdbcType=INTEGER}
</select>
//按条件查询员工信息
//(能关联查询出外键 部门表的信息)
List<Employee> selectByExampleWithDept(EmployeeExample example);
//按主键查询员工信息(同上)
Employee selectByPrimaryKeyWithDept(Integer empId);
也可以通过使用mybatis的****,并使用一些注解配置,半自动化的生成查询的sql.
****用过的朋友们也都知道,主要就是一个方法和一个配置文件,在mybatis官网上很容易就能找到,这里我就不多说了哈,详细的介绍可以看一下我的另一篇文章###
• 4、而后,业务逻辑层用Controller对数据进行处理和解析,这里的工作就要交给sprinMvc去做了
简单的配置文件:
<!-- SpringMvc的配置文件,包含网站跳转文件的配置 -->
<!-- 所有业务逻辑组件扫描 -->
<context:component-scan base-package="com.mybag" use-default-filters="false">
<!-- 其他都不扫描,只扫描控制器controller -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 两个标准配置 -->
<!-- 将springmvc不能处理的请求交给tomcat -->
<mvc:default-servlet-handler />
<!-- 能支持springmvc更高级的一些功能,JRS303校验,ajax请求,映射动态请求 -->
<mvc:annotation-driven />
controller里面还不是太麻烦:
/**
* 为了降低客户端的限制性,将分页数据以json串的形式返回
* 导入jackson包。
* 创建Msg辅助类
* @ResponseBody 自动将返回的对象转换为json字符串
*/
@RequestMapping("/emps")
@ResponseBody
public Msg getEmpsWithJson(@RequestParam(value = "pn", defaultValue = "1") Integer pn) {
//pom.xml引入PageHelper分页插件
//mybatis.xml中进行配置
//传入页码以及每页的大小 即 (从第几页开始查,每页显示多少条数据)
PageHelper.startPage(pn, 5);
//调用方法,拿到员工表的数据
List<Employee> emps = employeeService.getAll();
//PageInfo封装了详细的分页信息,使用它来包装查询出的数据
PageInfo page = new PageInfo(emps, 6);
return Msg.success().add("pageInfo", page);
}
• 5、服务器会将查出的数据,以json字符串的形式返回给浏览器
//解析并显示员工数据
function build_emps_table(result){
$("#emps_table tbody").empty();
var emps = result.extend.pageInfo.list;
$.each(emps,function(index,item){
var checkBoxTd = $("<td><input type='checkbox' class='check_item'/></td>");
var empIdTd = $("<td></td>").append(item.empId);
var empNameTd = $("<td></td>").append(item.empName);
var genderTd = $("<td></td>").append(item.gender=='M'?"男":"女");
var emailTd = $("<td></td>").append(item.email);
var deptNameTd = $("<td></td>").append(item.department.deptName);
var editBtn = $("<button></button>").addClass("btn btn-primary btn-sm edit_btn").append($("<span></span>").addClass("glyphicon glyphicon-pencil")).append("编辑");
//为编辑按钮添加一个自定义的属性,来表示当前员工id
editBtn.attr("edit-id",item.empId);
var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm delete_btn").append($("<span></span>").addClass("glyphicon glyphicon-trash")).append("删除");
//为删除按钮添加一个自定义的属性来表示当前删除的员工id
delBtn.attr("del-id",item.empId);
var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn);
//var delBtn =
//append方法执行完成以后还是返回原来的元素
$("<tr></tr>").append(checkBoxTd)
.append(empIdTd)
.append(empNameTd)
.append(genderTd)
.append(emailTd)
.append(deptNameTd)
.append(btnTd)
.appendTo("#emps_table tbody");
});
}
PS:
因为用户不仅仅是浏览器,有可能是安卓、IOS,处理数据会变得复杂,返回json的话更利于数据解析,可以实现客户端的无关性
最后,分页查询到的结果会在jsp页面使用C标签库获取,分页查询的效果就是这样啦
第二,修改
• 1、点击编辑
• 2、弹出用户修改的模态框(显示用户信息)
• 3、点击更新,完成用户修改
修改功能我写的比较简单,也很容易实现,效果就像下面这样
第三,新增
1、在index.jsp页面点击”新增”,弹出新增对话框
2、去数据库查询部门列表,显示在对话框中
3、用户输入数据,并进行校验(jquery前端校验,ajax用户名重复校验,重要数据(后端校验(JSR303),唯一约束);
4、完成保存
修改的sql
update tbl_emp
set emp_id = #{record.empId,jdbcType=INTEGER},
emp_name = #{record.empName,jdbcType=VARCHAR},
gender = #{record.gender,jdbcType=CHAR},
email = #{record.email,jdbcType=VARCHAR},
d_id = #{record.dId,jdbcType=INTEGER}
前端的校验比较简单,主要还是后台JSR303重要数据的校验
@RequestMapping(value = "/emp", method = RequestMethod.POST)
@ResponseBody
public Msg saveEmp(@Valid Employee employee, BindingResult result) {
if (result.hasErrors()) {
// 校验失败,应该返回失败,在模态框中显示校验失败的错误信息
Map<String, Object> map = new HashMap<>();
List<FieldError> errors = result.getFieldErrors();
for (FieldError fieldError : errors) {
System.out.println("错误的字段名:" + fieldError.getField());
System.out.println("错误信息:" + fieldError.getDefaultMessage());
map.put(fieldError.getField(), fieldError.getDefaultMessage());
}
return Msg.fail().add("errorFields", map);
} else {
employeeService.saveEmp(employee);
return Msg.success();
}
}
添加页面的效果和修改差不多
第四、删除
单条数据的删除:
多条数据批量删除
写的时候还是离不开service, 里边简单的两个方法
/**
* 员工删除
*
* @param id
*/
public void deleteEmp(Integer id) {
// TODO Auto-generated method stub
employeeMapper.deleteByPrimaryKey(id);
}
public void deleteBatch(List<Integer> ids) {
// TODO Auto-generated method stub
EmployeeExample example = new EmployeeExample();
Criteria criteria = example.createCriteria();
// delete from xxx where emp_id in(1,2,3)
criteria.andEmpIdIn(ids);
employeeMapper.deleteByExample(example);
}
控制器中使用Rest风格的URI,直接指明RequestMethod.DELETE,规范http请求
/**
* 单个批量二合一
* 批量删除:1-2-3 单个删除:1
*
* @param id
* @return
*/
@ResponseBody
@RequestMapping(value = "/emp/{ids}", method = RequestMethod.DELETE)
public Msg deleteEmp(@PathVariable("ids") String ids) {
// 批量删除
if (ids.contains("-")) {
List<Integer> del_ids = new ArrayList<>();
String[] str_ids = ids.split("-");
// 组装id的集合
for (String string : str_ids) {
del_ids.add(Integer.parseInt(string));
}
employeeService.deleteBatch(del_ids);
} else {
Integer id = Integer.parseInt(ids);
employeeService.deleteEmp(id);
}
return Msg.success();
}
everything is all right~~~~最后来总结一波~
小小白在努力>_<