主界面演示
功能点
技术点
(1)右键工程,点击 Add Framework Suppor
(2)选择 Web Application
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.chengroupId>
<artifactId>ssm-crudartifactId>
<version>1.0-SNAPSHOTversion>
<dependencies>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>5.0.0version>
dependency>
<dependency>
<groupId>org.mybatis.generatorgroupId>
<artifactId>mybatis-generator-coreartifactId>
<version>1.3.5version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>4.3.7.RELEASEversion>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.8.8version>
dependency>
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-validatorartifactId>
<version>5.4.1.Finalversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>4.3.7.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>4.3.7.RELEASEversion>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aspectsartifactId>
<version>4.3.7.RELEASEversion>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.4.2version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>1.3.1version>
dependency>
<dependency>
<groupId>com.mchangegroupId>
<artifactId>c3p0artifactId>
<version>0.9.2version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.21version>
dependency>
<dependency>
<groupId>jstlgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.0.1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jsp-apiartifactId>
<version>2.0version>
<scope>providedscope>
dependency>
dependencies>
project>
(1)前往 bootstrap 官网下载
下载地址: https://v3.bootcss.com,选择用于生产环境的 Bootstrap
(2)解压后将文件夹添加到工程中 /static
**web.xml,主要用于配置 Filter、Listener、Servlet **
springmvc 配置文件,主要控制网站逻辑的跳转
spring 配置文件,主要配置与业务逻辑相关的文件
mybatis 配置文件,主要用于配置 MyBatis
(1)配置 web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:applicationContext.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<servlet>
<servlet-name>dispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<filter>
<filter-name>characterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>utf-8param-value>
init-param>
<init-param>
<param-name>forceRequestEncodingparam-name>
<param-value>trueparam-value>
init-param>
<init-param>
<param-name>forceResponseEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>characterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<filter>
<filter-name>hiddenHttpMethodFilterfilter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilterfilter-class>
filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<filter>
<filter-name>httpPutFormContentFilterfilter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilterfilter-class>
filter>
<filter-mapping>
<filter-name>httpPutFormContentFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
web-app>
在 src/main/resources/ 下加入 applicationContext.xml, 防止 idea 报错
(2)配置 springmvc 配置文件
在 WEB-INF 下加入 dispatcherServlet-servlet.xml
在 src/main/java 创建包结构
**配置 dispatcherServlet-servlet.xml **
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.study" use-default-filters="false">
<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 name="suffix" value=".jsp"/>
bean>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
beans>
(3) 配置 spring 配置文件
配置 dbconfig.properties ,配置数据库连接信息
在 src/main/resources 下加入 dbconfig.properties
dbconfig.properties
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/ssm_crud_study?useUnicode=true&characterEncoding=utf8
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.user=root
jdbc.password=root
在 src/main/resources 下创建 mybatis-config.xml、mapper文件夹
配置 applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.chen">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
context:component-scan>
<context:property-placeholder location="classpath:dbconfig.properties"/>
<bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
bean>
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="dataSource" ref="pooledDataSource"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
bean>
<bean id="sessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryBean"/>
<constructor-arg name="executorType" value="BATCH"/>
bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionTemplateBeanName" value="sessionTemplate"/>
<property name="basePackage" value="com.study"/>
bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="pooledDataSource"/>
bean>
<aop:config>
<aop:pointcut id="txPoint" expression="execution(* com.chen.crud.service..*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"/>
<tx:method name="get*" read-only="true"/>
tx:attributes>
tx:advice>
beans>
此处目前会报错,是因为此时 mapper 文件夹目录下没有 .xml 文件,目前可忽略
(4)配置 mybatis 文件
mybatis-config.xml
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
settings>
<typeAliases>
<package name="com.study.crud.bean"/>
typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">plugin>
plugins>
configuration>
CREATE DATABASE ssm_crud_study;
CREATE TABLE `ssm_crud_study`.`tbl_emp` (
`emp_id` INT NOT NULL AUTO_INCREMENT,
`emp_name` VARCHAR(255) NOT NULL,
`gender` CHAR(1) NULL,
`email` VARCHAR(255) NULL,
`d_id` INT NULL,
PRIMARY KEY (`emp_id`));
CREATE TABLE `ssm_crud_study`.`tbl_dept` (
`dept_id` INT NOT NULL,
`dept_name` VARCHAR(255) NOT NULL,
PRIMARY KEY (`dept_id`));
ALTER TABLE `ssm_crud_study`.`tbl_emp`
ADD INDEX `dept_id_idx` (`d_id` ASC) VISIBLE;
;
ALTER TABLE `ssm_crud_study`.`tbl_emp`
ADD CONSTRAINT `dept_id`
FOREIGN KEY (`d_id`)
REFERENCES `ssm_crud_study`.`tbl_dept` (`dept_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
在工程中添加 mbg.xml
配置 mbg.xml
<generatorConfiguration>
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressAllComments" value="true" />
commentGenerator>
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/ssm_crud_study?useUnicode=true&characterEncoding=utf8"
userId="root"
password="root">
jdbcConnection>
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
javaTypeResolver>
<javaModelGenerator targetPackage="com.study.crud.bean" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
javaModelGenerator>
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
<property name="enableSubPackages" value="true" />
sqlMapGenerator>
<javaClientGenerator type="XMLMAPPER" targetPackage="com.study.crud.dao" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
javaClientGenerator>
<table tableName="tbl_emp" domainObjectName="Employee">
table>
<table tableName="tbl_dept" domainObjectName="Department">table>
context>
generatorConfiguration>
在 src/test/java 中创建 MBGTest 用于生成 bean、mapper
public class MBGTest {
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("mbg.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
}
运行结果:自动生成 bean、mapper
在数据库中添加数据
INSERT INTO `ssm_crud_study`.`tbl_dept` (`dept_id`, `dept_name`) VALUES ('1', '开发部');
INSERT INTO `ssm_crud_study`.`tbl_dept` (`dept_id`, `dept_name`) VALUES ('2', '测试部');
INSERT INTO `ssm_crud_study`.`tbl_emp` (`emp_id`, `emp_name`, `gender`, `email`, `d_id`) VALUES ('1', 'Jerry', 'M', '[email protected]', '1');
在 src/test/java 创建 MapperTest
首先测验能否连接到获得 mapper 实例
测试能否获取数据库中信息
向数据库中插入 1000 条数据
// 使用 Spring Test
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class MapperTest {
@Autowired
DepartmentMapper departmentMapper;
// 可以执行批量操作的 sqlSession
@Autowired
SqlSession sqlSession;
@Test
public void testCRUD() {
// System.out.println(departmentMapper);
// Department department = departmentMapper.selectByPrimaryKey(1);
// System.out.println("dept_id=" + department.getDeptId() + ",dept_name=" + department.getDeptName());
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
for (int i = 0; i < 1000; i++) {
// 使用 UUID 工具类,随机生成用户名
String empName = UUID.randomUUID().toString().substring(0, 5);
// 需要在 Employee 中添加有参构造,!!!添加有参构造后必须添加无参构造 !!!
mapper.insertSelective(new Employee(null, empName, "M", empName + "@qq.com", 1));
}
}
}
流程
index.jsp 添加标签 jsp:forward
跳转到 /emps
在 com.study.crud.controller
中添加 EmployeeController
,并编写映射请求
在 /WEB-INF/viwes/ 下添加 list.jsp
启动服务器,查看是否跳转成功
我们查询员工时,希望能够查询出部门的信息,所以需要在 EmployeeMapper
中添加新的查询方法,并在 Employee
中添加 Department 属性,和 get、set 方法
在 EmployeeMapper.xml
中添加 SQL
<resultMap id="WithDeptResultMap" type="com.study.crud.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" />
<association property="department" javaType="com.study.crud.bean.Department">
<id column="dept_id" property="deptId"/>
<result column="dept_name" property="deptName"/>
association>
resultMap>
<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>
在 EmployeeService
中添加 getAll()
方法
在 EmployeeController.getEmps()
中引入分页插件
在 src/test/ 下添加测试,测试分页插件
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {"classpath:applicationContext.xml", "file:web/WEB-INF/dispatcherServlet-servlet.xml"})
public class MVCTest {
// 传入 Spring MVC 的 ioc
@Autowired
WebApplicationContext context;
// 虚拟 mvc 请求,获取到处理结果
MockMvc mockMvc;
@Before
public void initMockMvc() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Test
public void testPage() throws Exception {
// 模拟请求拿到返回值
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/emps").param("pn", "5")).andReturn();
// 请求成功以后,请求域中会有 pageInfo
MockHttpServletRequest request = result.getRequest();
PageInfo page = (PageInfo) request.getAttribute("pageInfo");
System.out.println("当前页码:" + page.getPageNum());
System.out.println("总页码:" + page.getPages());
System.out.println("总记录数:" + page.getTotal());
System.out.println("在页面需要连续显示的页码");
int[] nums = page.getNavigatepageNums();
for (int num : nums)
System.out.print(" " + num);
System.out.println();
List<Employee> emps = page.getList();
for (Employee emp : emps)
System.out.println("ID:" + emp.getEmpId() + "==>Name:" + emp.getEmpName());
}
}
测试结果
在 /static 下加入 jquery
在 list.jsp 中引入 bootstrap、jquery
前往 Bootstrap 官网,查看文档
根据文档创建 新建
删除
按钮
查看效果
给按钮添加样式
查看样式
根据文档可以写出表格界面
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
员工列表
<% pageContext.setAttribute("APP_PATH", request.getContextPath()); %>
<%--
不以 / 开始的相对路径,找资源,以当前资源的路径为基准,经常容易出问题
以 / 开始的相对路径,找资源,以服务器的路径为标准 (http://localhost:8080),需要加上项目名
http://localhost:8080/crud
--%>
<%-- 引入 jquery --%>
<%-- 引入样式 --%>
SSM-CRUD
#
lastName
email
gender
deptName
操作
${emp.empId}
${emp.empName}
${emp.email}
${emp.gender == 'M' ? '男' : '女'}
${emp.department.deptName}
查看效果
编写分页条
当前第 ${pageInfo.pageNum} 页,共有 ${pageInfo.pages} 页,总计 ${pageInfo.total} 条记录
查看效果
至此已经完成了基本的界面开发,但是目前的设计有着很大的缺陷,每次换页都需要重新加载整个网页。
由此引入 AJAX
AJAX = 异步 JavaScript 和 XML。
AJAX 是一种用于创建快速动态网页的技术。
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。
有很多使用 AJAX 的应用程序案例:新浪微博、Google 地图、开心网等等。
基于 ajax 查询员工数据
(1)去除 index.jsp 中的
标签,将 list.jsp 中的内容复制到 index.jsp 中
(2)删除 index.jsp 页面中带有从 EmployeeController.getEmps()
得到的 pageInfo
相关的标签
得到如下
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
员工列表
<% pageContext.setAttribute("APP_PATH", request.getContextPath()); %>
<%--
不以 / 开始的相对路径,找资源,以当前资源的路径为基准,经常容易出问题
以 / 开始的相对路径,找资源,以服务器的路径为标准 (http://localhost:8080),需要加上项目名
http://localhost:8080/crud
--%>
<%-- 引入 jquery --%>
<%-- 引入样式 --%>
SSM-CRUD
#
lastName
email
gender
deptName
操作
(3) EmployeeController
中添加返回 json 的映射请求
在浏览器中查看返回的 json 字符串
(4) 编写消息类
我们需要将返回的类封装到一个消息类中,以便获取更多的信息
在 com.study.crud.bean 中创建 Msg
public class Msg {
public static final int CODE_SUCCESS = 100;
public static final int CODE_FAIL = 200;
// 状态码
private int code;
// 提示信息
private String msg;
// 返回给浏览器的数据
private Map<String, Object> extend = new HashMap<String, Object>();
public static Msg success() {
Msg msg = new Msg();
msg.setCode(CODE_SUCCESS);
msg.setMsg("处理成功");
return msg;
}
public static Msg fail() {
Msg msg = new Msg();
msg.setCode(CODE_FAIL);
msg.setMsg("处理失败");
return msg;
}
// 向 Msg 中添加数据
public Msg add(String key, Object value) {
this.extend.put(key, value);
return this;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Map<String, Object> getExtend() {
return extend;
}
public void setExtend(Map<String, Object> extend) {
this.extend = extend;
}
}
改写 getEmpsWithJson()
查看改写后的映射请求返回的数据
(4) **编写 js **
添加 id 值
添加 js
<script type="text/javascript">
var lastPage, currentPage, totalRecord;
// 1、页面加载完成以后,直接去发送一个 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、解析并显示员工数据
build_emps_table(result);
// 2、解析并显示分页信息
build_page_info(result);
// 3、解析显示分页条数据
build_page_nav(result);
}
});
}
function build_emps_table(result) {
// 清空表格
$("#emps_table tbody").empty();
var emps = result.extend.pageInfo.list;
$.each(emps, function (index, item) {
var checkBoxTd = $(" ");
var empIdTd = $(" ").append(item.empId);
var empNameTd = $(" ").append(item.empName);
var gender = item.gender == 'M' ? '男' : '女';
var genderTd = $(" ").append(gender);
var emailTd = $(" ").append(item.email);
var deptNameTd = $(" ").append(item.department.deptName);
/**
*
*/
var editBtn = $("").addClass("btn btn-primary btn-sm edit_btn")
.append($("")).addClass("glyphicon glyphicon-pencil").append("编辑");
editBtn.attr("edit-id", item.empId);
var deleteBtn = $("").addClass("btn btn-danger btn-sm delete_btn")
.append($("")).addClass("glyphicon glyphicon-trash").append("删除");
deleteBtn.attr("del-id", item.empId);
var btnTd = $(" ").append(editBtn).append(" ").append(deleteBtn);
// append 方法执行完成以后还是返回原来的元素 所以可以链式操作
$(" ").append(checkBoxTd)
.append(empIdTd)
.append(empNameTd)
.append(genderTd)
.append(emailTd)
.append(deptNameTd)
.append(btnTd)
.appendTo("#emps_table tbody");
})
}
function build_page_info(result) {
$("#page_info_area").empty();
var pageInfo = result.extend.pageInfo;
$("#page_info_area").append("当前 " + pageInfo.pageNum + " 页,"
+ "总 " + pageInfo.pages + " 页,"
+ "总 " + pageInfo.total + " 条记录"
);
lastPage = pageInfo.pages;
totalRecord= pageInfo.total;
currentPage = pageInfo.pageNum;
}
function build_page_nav(result) {
$("#page_nav_area").empty();
var pageInfo = result.extend.pageInfo;
var ul = $("
").addClass("pagination");
var firstPageLi = $("").append($("").append("首页"));
var prePageLi = $("").append($("").append("«"));
if (pageInfo.hasPreviousPage == false) {
firstPageLi.addClass("disabled");
prePageLi.addClass("disabled");
} else {
firstPageLi.click(function () {
to_page(1);
});
prePageLi.click(function () {
to_page(pageInfo.pageNum - 1);
});
}
ul.append(firstPageLi).append(prePageLi);
$.each(result.extend.pageInfo.navigatepageNums, function (index, item) {
var numLi = $("").append($("").append(item));
if (pageInfo.pageNum == item) {
numLi.addClass("active");
}
numLi.click(function () {
to_page(item);
});
ul.append(numLi);
});
var nextPageLi = $("").append($("").append("»"));
var lastPageLi = $("").append($("").append("尾页"));
if (pageInfo.hasNextPage == false) {
nextPageLi.addClass("disabled");
lastPageLi.addClass("disabled");
} else {
nextPageLi.click(function () {
to_page(pageInfo.pageNum + 1);
});
lastPageLi.click(function () {
to_page(pageInfo.pages);
});
}
ul.append(nextPageLi).append(lastPageLi);
var navEle = $("").append(ul);
navEle.appendTo("#page_nav_area");
}
</script>
查看结果
(1)新增员工信息
添加 员工添加的模态框
新建按钮处添加 id
编写 js
//清空表单样式及内容
function reset_form(ele) {
$(ele)[0].reset();
//清空表单样式
$(ele).find("*").removeClass("has-error has-success");
$(ele).find(".help-block").text("");
}
function getDepts(ele) {
// 清空之前下拉列表的值
$(ele).empty();
$.ajax({
url: "${APP_PATH}/depts",
type: "get",
success:function (result) {
//{"code":100,"msg":"处理成功!",
//"extend":{"depts":[{"deptId":1,"deptName":"开发部"},{"deptId":2,"deptName":"测试部"}]}}
//console.log(result);
//显示部门信息在下拉列表中
//$("#empAddModal select").append("")
$.each(result.extend.depts,function(){
var optionEle = $("").append(this.deptName).attr("value",this.deptId);
optionEle.appendTo(ele);
});
}
});
}
// 点击新增按钮弹出模态框。
$("#emp_add_modal_btn").click(function () {
//清除表单数据(表单完整重置(表单的数据,表单的样式))
reset_form("#empAddModal form");
//s$("")[0].reset();
//发送ajax请求,查出部门信息,显示在下拉列表中
getDepts("#empAddModal select");
//弹出模态框
$("#empAddModal").modal({
backdrop:"static"
});
});
查看 添加模态框
创建 DepartmentController
映射 getDepts 请求
@Controller
public class DepartmentController {
@Autowired
DepartmentService departmentService;
@RequestMapping("/depts")
@ResponseBody
public Msg getDeptsWithJson() {
List<Department> depts = departmentService.getDepts();
return Msg.success().add("depts", depts);
}
}
@Service
public class DepartmentService {
@Autowired
DepartmentMapper departmentMapper;
public List<Department> getDepts() {
return departmentMapper.selectByExample(null);
}
}
查看是否显示部门信息
(2)数据校验
**js校验 **
// 检验表单数据
function validate_add_form() {
var empName = $("#empName_add_input").val();
var regName = /(^[a-zA-Z0-9]{6,16}$)|(^[\u2E80-\u9FFF]{2,5})/;
if (!regName.test(empName)) {
show_validate_msg("#empName_add_input", "error", "用户名可以是 2-5 位中文或者 6-16 位英文和数字的组合");
return false;
} else {
show_validate_msg("#empName_add_input", "success", "");
}
var email = $("#email_add_input").val();
var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
if (!regEmail.test(email)) {
show_validate_msg("#email_add_input", "error", "邮箱格式不正确");
return false;
} else {
show_validate_msg("#email_add_input", "success", "");
}
return true;
}
// 显示校验结果的提示信息
function show_validate_msg(ele, status, msg) {
$(ele).parent().removeClass("has-success has-error");
$(ele).next("span").text("");
if ("success" == status) {
$(ele).parent().addClass("has-success");
$(ele).next("span").text(msg);
} else {
$(ele).parent().addClass("has-error");
$(ele).next("span").text(msg);
}
}
// 校验用户名是否可用
$("#empName_add_input").change(function () {
var empName = this.value;
$.ajax({
url:"${APP_PATH}/checkuser",
data:"empName="+empName,
type:"post",
success:function (result) {
if (result.code == 100) {
show_validate_msg("#empName_add_input", "success", "用户名可用");
$("emp_save_btn").attr("ajax-va", "success");
} else {
show_validate_msg("#empName_add_input", "error", result.extend.va_msg);
$("emp_save_btn").attr("ajax-va", "error");
}
}
});
});
在 EmployeeController
中添加检验用户名映射请求
// EmployeeController
@RequestMapping("/checkuser")
@ResponseBody
public Msg checkuser(@RequestParam("empName") String empName) {
String regx = "(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5})";
if (!empName.matches(regx)) {
return Msg.fail().add("va_msg", "用户名必须是 6-16 位数字和字母的组合或者 2-5 位中文");
}
boolean b = employeeService.checkUser(empName);
if (b) {
return Msg.success();
} else {
return Msg.fail().add("va_msg", "用户名已存在");
}
}
在 EmployeeService
中添加检验方法
public boolean checkUser(String empName) {
EmployeeExample example = new EmployeeExample();
EmployeeExample.Criteria criteria = example.createCriteria();
criteria.andEmpNameEqualTo(empName);
long count = employeeMapper.countByExample(example);
return count == 0;
}
查看校验结果
(3) 保存员工
添加 js
// 点击保存,保存员工
$("#emp_save_btn").click(function () {
// 1、模态框中填写的数据提交给服务器进行保存
// 1、先对要提交给服务器的数据进行校验
if (!validate_add_form()) {
return false;
}
// 1、判断之前的 ajax 用户名校验是否成功
if ($(this).attr("ajax-va") == "error") {
return false;
}
// 2、发送 ajax 请求保存员工
$.ajax({
url:"${APP_PATH}/emp",
type:"post",
data:$("#empAddModal form").serialize(),
success:function(result) {
if (result.code == 100) {
// 员工保存成功
// 1、关闭模态框
$("#empAddModal").modal("hide");
// 2、来到最后一页,显示刚才保存的数据
if (totalRecord % 5 == 0) {
lastPage++;
currentPage = lastPage;
}
totalRecord++;
to_page(lastPage);
} else {
// 显示失败信息
if (undefined != result.extend.errorFields.email) {
// 显示邮箱错误信息
show_validate_msg("#email_add_input", "error", result.extend.errorFields.email);
}
if (undefined != result.extend.errorFields.empName) {
// 显示员工名字的错误信息
show_validate_msg("#empName_add_input", "error", result.extend.errorFields.empName);
}
}
}
});
});
在 Employee
中使用JSR303 数据校验
在 EmployeeController
中添加保存员工的映射请求
@RequestMapping(value = "/emp", method = RequestMethod.POST)
@ResponseBody
public Msg saveEmp(@Valid Employee employee, BindingResult result) {
if (result.hasErrors()) {
Map<String, Object> map = new HashMap<String, Object>();
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();
}
}
在 EmployeeService
中添加保存员工的方法
public void saveEmp(Employee employee) {
employeeMapper.insertSelective(employee);
}
(4) 修改员工信息
添加员工修改模态框
添加 js
// 1、如果在编辑和删除按钮创建之前绑定 click 是绑定不上的
// 1)可以在创建按钮的时候绑定
// 2)绑定点击 .live()
$(document).on("click", ".edit_btn", function () {
// 1、查处部门信息,并显示部门列表
getDepts("#empUpdateModal select");
// 2、查处员工信息,显示员工信息
getEmp($(this).attr("edit-id"));
// 3、把员工的 id 传递给模态框的更新按钮
$("#emp_update_btn").attr("edit-id", $(this).attr("edit-id"));
$("#empUpdateModal").modal({
backdrop: "static"
});
});
function getEmp(id) {
$.ajax({
url:"${APP_PATH}/emp/" + id,
type:"get",
success:function (result) {
var empData = result.extend.emp;
$("#empName_update_static").text(empData.empName);
$("#email_update_input").val(empData.email);
$("#empUpdateModal input[name=gender]").val([empData.gender]);
$("#empUpdateModal select").val([empData.dId]);
}
});
}
// 点击更新,更新员工信息
$("#emp_update_btn").click(function () {
// 验证邮箱是否合法
// 1、校验邮箱信息
var email = $("#email_update_input").val();
var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
if (!regEmail.test(email)) {
show_validate_msg("#email_update_input", "error", "邮箱格式不正确");
return false;
} else {
show_validate_msg("#email_update_input", "success", "");
}
// 2、发送 ajax 请求保存更新的员工数据
$.ajax({
url:"${APP_PATH}/emp/" + $(this).attr("edit-id"),
type:"put",
data:$("#empUpdateModal form").serialize(),
success:function (result) {
$("#empUpdateModal").modal("hide");
to_page(currentPage);
}
});
});
在 EmployeeController
中添加按 id 获取员工的映射请求 和 更新员工的请求
@RequestMapping(value = "/emp/{id}", method = RequestMethod.GET)
@ResponseBody
public Msg getEmp(@PathVariable("id") Integer id) {
Employee employee = employeeService.getEmp(id);
return Msg.success().add("emp", employee);
}
@RequestMapping(value = "/emp/{empId}", method = RequestMethod.PUT)
@ResponseBody
public Msg updateEmp(Employee employee, HttpServletRequest request) {
employeeService.updateEmp(employee);
return Msg.success();
}
在 EmployeeService
中添加 getEmp 方法和 update 方法
public Employee getEmp(Integer id) {
return employeeMapper.selectByPrimaryKeyWithDept(id);
}
public void updateEmp(Employee employee) {
employeeMapper.updateByPrimaryKeySelective(employee);
}
查看效果
(5) 添加全选功能
添加全选按钮
添加 js
// 完成全选、全不选功能
$("#check_all").click(function () {
$(".check_item").prop("checked", $(this).prop("checked"));
});
$(document).on("click", ".check_item", function () {
var flag = $(".check_item:checked").length == $(".check_item").length;
$("#check_all").prop("checked", flag);
});
添加删除功能
给删除按键添加 id
添加 js
// 单个删除
$(document).on("click", ".delete_btn", function () {
var empName = $(this).parents("tr").find("td:eq(2)").text();
var empId = $(this).attr("del-id");
// 弹出是否确认删除对话框
if (confirm("确认删除【" + empName + "】吗?")) {
$.ajax({
url:"${APP_PATH}/emp/" + empId,
type:"delete",
success:function (result) {
alert(result.msg);
to_page(1);
}
});
}
});
// 点击全部删除、就批量删除
$("#emp_delete_all_btn").click(function () {
var empNames = "";
var del_ids = "";
$.each($(".check_item:checked"), function () {
empNames += $(this).parents("tr").find("td:eq(2)").text() + ",";
del_ids += $(this).parents("tr").find("td:eq(1)").text() + "-";
});
empNames = empNames.substring(0, empNames.length - 1);
del_ids = del_ids.substring(0, del_ids.length - 1);
if (confirm("确认删除【" + empNames + "】吗?")) {
$.ajax({
url:"${APP_PATH}/emp/" + del_ids,
type:"delete",
success:function (result) {
alert(result.msg);
to_page(1);
}
});
}
});
在 EmployeeController
中添加删除方法
@RequestMapping(value = "/emp/{ids}", method = RequestMethod.DELETE)
@ResponseBody
public Msg deleteEmp(@PathVariable("ids") String ids) {
// 批量删除
if (ids.contains("-")) {
List<Integer> del_ids = new ArrayList<Integer>();
String[] str_ids = ids.split("-");
for (String str : str_ids) {
del_ids.add(Integer.parseInt(str));
}
employeeService.deleteBatch(del_ids);
} else {
Integer id = Integer.parseInt(ids);
employeeService.deleteEmp(id);
}
return Msg.success();
}
在 EmployeeService
中添加单个删除和多个删除的方法
public void deleteBatch(List<Integer> del_ids) {
EmployeeExample example = new EmployeeExample();
EmployeeExample.Criteria criteria = example.createCriteria();
criteria.andEmpIdIn(del_ids);
employeeMapper.deleteByExample(example);
}
public void deleteEmp(Integer id) {
employeeMapper.deleteByPrimaryKey(id);
}
查看效果