Employee Information Management System

The SSM-CRUD
system uses spring, springMVC and mybatis as the basic framework, and the front desk is designed with BootStrap. When creating it, it is troublesome to manually find the jar package state, which affects the development efficiency, so I use Maven to manage the project structure.
The main function is to add, modify, paginate and delete employee information individually and in batches

Since the paging function is brought when querying, here we mainly talk about the query.

First: query

• 1. When the project is running, the index page directly sends an ajax request to query the employee list with paging. The
main callback function is as follows:

$(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. When the front controller receives the request, it first calls the mapper according to the url to generate the handler object and interceptor

<!-- 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. Then the persistence layer Mapper connects with the bottom layer by writing flexible sql fragments and 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);

You can also use the reverse engineering of mybatis and use some annotation configurations to semi-automatically generate the sql of the query.
Friends who have used reverse engineering also know that it is mainly a method and a configuration file, which is easy to find on the official website of mybatis. If you can find it, I won't say much here. For a detailed introduction, you can read my other article###

• 4. Then, the business logic layer uses the Controller to process and parse the data, and the work here will be handed over to sprinMvc.
Simple configuration file :

<!-- 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 />

It's not too troublesome in the 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. The server will return the detected data to the browser in the form of a json string

//解析并显示员工数据
        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:
Because the user is not only a browser, it may be Android, IOS, processing data will become complicated, returning json is more conducive to data parsing, and can achieve client independence

Finally, the results of the paging query will be obtained using the C tag library on the jsp page. This is the effect of the paging query.
write picture description here

Second, modify

• 1. Click to edit
• 2. Pop up a modal box for user modification (display user information)
• 3. Click update to complete user modification The
modification function I wrote is relatively simple and easy to implement, and the effect is as follows
write picture description here

Third, add

1. Click "Add" on the index.jsp page, and a new dialog box will pop up
. 2. Go to the database to query the department list and display it in the dialog box.
3. The user enters data and performs verification (jquery front-end verification, ajax user name) Repeat verification, important data (back-end verification (JSR303), unique constraint);
4. Complete the saved
modified 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}

The front-end verification is relatively simple, mainly the verification of important JSR303 data in the background

    @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();
        }
    }

The effect of adding a page is similar to that of modification. Forgive me for being so lazy, hahaha...
write picture description here

Fourth, delete

Deletion of a single piece of data:
write picture description here
batch deletion of multiple pieces of data
write picture description here

When writing, it is still inseparable from service. There are two simple methods in it.

/**
     * 员工删除
     * 
     * @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);
    }

Use Rest-style URI in the controller, directly specify RequestMethod.DELETE, and standardize http requests

/**
     * 单个批量二合一
     *  批量删除: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~~~~ Finally, a summary~
write picture description here

                                                                                                                 小小白在努力>_<

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324800263&siteId=291194637