一 思路
1 组件
页面显示:JSP
接受用户请求:Servlet
和数据库交互:MyBatis
2 基础准备
① 创建 web 项目,导入需要依赖的 jar 包,放入 web/WEB-INF/lib目录中
② 创建数据库表
CREATE TABLE employee(
`id` bigint(11) NOT NULL auto_increment,
`name` varchar(50) default NULL,
`salary` double(10,2) default NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `employee` VALUES (1,'大黄', 8848.00);
INSERT INTO `employee` VALUES (2,'a黄', 8848.00);
INSERT INTO `employee` VALUES (3,'b黄', 8848.00);
INSERT INTO `employee` VALUES (4,'c黄', 8848.00);
INSERT INTO `employee` VALUES (5,'d黄', 8848.00);
INSERT INTO `employee` VALUES (6,'e黄', 8848.00);
INSERT INTO `employee` VALUES (7,'f黄', 8848.00);
INSERT INTO `employee` VALUES (8,'g黄', 8848.00);
INSERT INTO `employee` VALUES (9,'h黄', 8848.00);
③ 创建表对应的实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
private Long id;
private String name;
private double salary;
}
④ MyBatis 配置文件实现
db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///play_web
jdbc.user=root
jdbc.password=root
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties"></properties>
<typeAliases>
<package name="com.domain"/>
</typeAliases>
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mappers/EmployeeMapper.xml"></mapper>
</mappers>
</configuration>
⑤ 抽取工具类
MybatisUtil
package com.util;
public class MybatisUtil {
private static SqlSessionFactory factory=null;
static {
try {
InputStream rs = Resources.getResourceAsStream("mybatis-config.xml");
factory = new SqlSessionFactoryBuilder().build(rs);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
return factory.openSession(true);
}
}
StringUtil – 判空
public class StringUtil {
//判断输入的表单参数是否为空
public static boolean hasLength(String s){
return s!=null && s.trim().length()!=0;
}}
⑥ 根据实体类创建 dao 包以及接口
Dao
package com.dao;
import com.domain.Employee;
import java.util.List;
public interface EmployeeDao {
// 增
int add(Employee employee);
// 删
int delete(Long id);
// 改
int update(Employee employee);
// 查全部
List<Employee> list();
// 根据id查
Employee queryOne(Long id);
}
impl
package com.dao.impl;
import com.dao.EmployeeDao;
import com.domain.Employee;
import com.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class EmployeeDaoImpl implements EmployeeDao {
/*定义成员变量*/
private SqlSession sqlSession= MybatisUtil.getSqlSession();
@Override
public int add(Employee employee) {
int row = sqlSession.insert("com.mapper.EmployeeMapper.add", employee);
return row;
}
@Override
public int delete(Long id) {
int row= sqlSession.delete("com.mapper.EmployeeMapper.delete",id);
return row;
}
@Override
public int update(Employee employee) {
int row= sqlSession.update("com.mapper.EmployeeMapper.update",employee);
return row;
}
@Override
public List<Employee> list() {
List<Employee> list = sqlSession.selectList("com.mapper.EmployeeMapper.list");
return list;
}
@Override
public Employee queryOne(Long id) {
Employee employee= sqlSession.selectOne("com.mapper.EmployeeMapper.selectOne", id);
return employee;
}
}
mapper
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mapper.EmployeeMapper">
<!--增加商品-->
<insert id="add">
insert into employee (name,salary)
values(#{name},#{salary})
</insert>
<!--修改-->
<update id="update">
update employee set name=#{name},salary=#{salary} WHERE id=#{id}
</update>
<!--删除-->
<delete id="delete">
delete from employee WHERE id=#{id}
</delete>
<!--根据id查询-->
<select id="queryOne" resultType="employee">
SELECT * from employee WHERE id=#{id}
</select>
<!--查询所有-->
<select id="list" resultType="employee">
SELECT * from employee
</select>
</mapper>
⑦ 日志文件 – log4j.properties
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.domain=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
⑧ 生成测试类 EmployeeDaoImplTest,查看后台功能是否实现
package com.dao.impl;
import com.dao.EmployeeDao;
import com.domain.Employee;
import org.junit.Test;
import java.util.List;
public class EmployeeDaoImplTest {
@Test
public void add() {
}
@Test
public void delete() {
}
@Test
public void update() {
}
@Test
public void list() {
EmployeeDao employeeDao=new EmployeeDaoImpl();
List<Employee> list = employeeDao.list();
System.out.println(list);
}
@Test
public void queryOne() {
}
}
二 前台实现
1 请求分发器
使用一个 Servlet 类来处理一张表的所有请求操作,即通过增加一个参数,用参数值来区分一个Servlet 中来区分不同的操作crud
package com.web.servlet;
import com.dao.EmployeeDao;
import com.dao.impl.EmployeeDaoImpl;
import com.domain.Employee;
import com.util.StringUtil;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet("/employee")
public class EmployeeServlet extends HttpServlet {
// 创建Dao对象
private EmployeeDao employeeDao=new EmployeeDaoImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置编码格式
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
// 获取请求分发的参数
String cmd=req.getParameter("cmd");
if("delete".equals(cmd)){
// 调用删除
delete(req,resp);
}else if("input".equals(cmd)){
// 跳转增加
input(req,resp);
}else if("saveOrUpdate".equals(cmd)){
// 跳转修改
saveOrUpdate(req,resp);
}else {
// 查所有
list(req,resp);
}
}
/*查询所有*/
private void list(HttpServletRequest req, HttpServletResponse resp) {
try {
// 调用Dao查所有方法
List<Employee> list=employeeDao.list();
// 将查询结果存储到请求作用域
req.setAttribute("list",list);
// 转发到列表页面
req.getRequestDispatcher("/WEB-INF/views/employee/list.jsp").forward(req,resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/*增加修改保存*/
private void saveOrUpdate(HttpServletRequest req, HttpServletResponse resp) {
//封装员工对象
Employee employee=new Employee();
/*将参数的获取及封装对象过程抽取成一个方法*/
req2employee(req,employee);
/*根据请求中是否携带id判断执行增加或者修改操作*/
String id = req.getParameter("id");
if (StringUtil.hasLength(id)){
employee.setId(Long.valueOf(id));
//执行修改
employeeDao.update(employee);
}else{
//调用dao方法执行增加保存操作
employeeDao.add(employee);
}
try {
//跳转到查询
resp.sendRedirect("/employee");
} catch (IOException e) {
e.printStackTrace();
}
}
/*封装的获取请求参数的方法*/
private void req2employee(HttpServletRequest req, Employee employee) {
//获取请求中表单参数
String name = req.getParameter("name");
//验证输入的表单参数不能为空
if (StringUtil.hasLength(name)){
//设置员工的名称
employee.setName(name);
}
String salary = req.getParameter("salary");
if (StringUtil.hasLength(salary)){
employee.setSalary(Double.valueOf(salary));
}
}
/*跳转到编辑页面*/
private void input(HttpServletRequest req, HttpServletResponse resp) {
//根据请求中是否携带id判断是增加或者修改操作
String id = req.getParameter("id");
if (StringUtil.hasLength(id)){//请求中携带了id执行修改
//根据id查询商品
Employee employee = employeeDao.queryOne(Long.valueOf(id));
//将查询的商品存储到作用域
req.setAttribute("employee",employee);
}
try {
//跳转到WEB-INF下面的页面:input.jsp
req.getRequestDispatcher("/WEB-INF/views/employee/input.jsp").forward(req,resp);
} catch (Exception e) {
e.printStackTrace();
}
}
/*删除*/
private void delete(HttpServletRequest req, HttpServletResponse resp) {
try {
//获取目标id
String id = req.getParameter("id");
//调用删除方法
int row = employeeDao.delete(Long.valueOf(id));
//删除完毕跳转到查询
resp.sendRedirect("/employee");
} catch (IOException e) {
e.printStackTrace();
}
}
}
2 前端crud实现
① input.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>员工信息编辑页面</title>
</head>
<body>
<h3>员工信息编辑</h3>
<form action="/employee?cmd=saveOrUpdate" method="post">
<input type="hidden" name="id" value="${employee.id}">
<p>姓名:<input type="text" name="name" value="${employee.name}"></p>
<%--step="0.01"表示接受小数点后两位--%>
<p>工资:<input type="number" step="0.01" name="salary" value="${employee.salary}"></p>
<p><input type="submit" value="保存"></p>
</form>
</body>
</html>
② list.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入核心标签库--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>员工信息页面</title>
</head>
<body>
<center>
<h3>员工列表</h3>
<p><a href="/employee?cmd=input">增加员工</a></p>
<table border="1px" cellpadding="0" cellspacing="0"width="800px">
<tr>
<th>序号</th>
<th>姓名</th>
<th>工资</th>
<th>操作</th>
</tr>
<%--动态展示商品列表数据--%>
<c:forEach items="${list}" varStatus="vs" var="employee">
<tr class="trClass">
<td>${vs.count}</td>
<td>${employee.name}</td>
<td>${employee.salary}</td>
<td>
<a href="/employee?cmd=input&id=${employee.id}">修改员工信息</a>
<%-- <a href="/product?cmd=delete&id=${product.id}">删除商品</a>--%>
<a href="#" onclick="deleteTr(${employee.id})">删除员工信息</a>
</td>
</tr>
</c:forEach>
</table>
</center>
<%--鼠标移动到当前行,实现背景颜色高亮显示--%>
<script>
//获取所有的行元素:不包含表头
var trs = document.getElementsByClassName("trClass");
//遍历行元素集合
for(var i=0;i<trs.length;i++){
//鼠标移入:当前行高亮,背景变成灰色
trs[i].onmouseover=function (){
this.style.backgroundColor="gray";
}
//鼠标移出:恢复原来背景颜色
trs[i].onmouseout=function (){
this.style.backgroundColor="";
}
}
</script>
<%--删除确认表--%>
<script>
function deleteTr(id){
//确认删除
var b= window.confirm("确认删除选中的员工信息吗?");
if(b){//确定删除,执行后台删除操作
window.location="/employee?cmd=delete&id="+id;
}
}
</script>
</body>
</html>
③ index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>员工信息管理</title>
</head>
<body>
<a href="/employee">员工信息管理</a>
</body>
</html>
三 小结
1 目录结构图
2 注意
不需要数据共享的跳转直接使用重定向即可