使用springboot开发一个ems小项目
开发流程
需求分析:分析用户主要需求 提取出项目核心功能 根据核心功能构建页面原型
库表设计(概要设计):1. 分析整个系统有哪些表 2. 分析出表之间关联关系 3. 确定字段
详细设计(流程图,伪代码):用来验证库表准确性
功能实现(编码):环境搭建 具体功能实现
功能测试
部署
上线
维护
系统中含有哪些模块?
~~~~~~ 用户模块
~~~~~~ 员工模块
每个模块功能有哪些?
a. 用户模块
~~~~~~ 登录
~~~~~~ 注册
~~~~~~ 验证码
b.员工模块
~~~~~~ 查询
~~~~~~ 删除
~~~~~~ 更新
~~~~~~ 添加
系统需要2张表: 用户表 user 员工表 employee
表与表之间关系: user employee 独立两张表
确定字段:
~~~~~~ user: id、username、password、realname、gender
~~~~~~ employee: id、name、birthday、salary、gender
数据库: ems-jsp
详细设计 省略
技术选型:springboot + mybatis + jsp + mysql
环境搭建:springboot + jsp + mybatis
项目名:ems-jsp
引入依赖
<dependency>
<groupId>org.apache.tomcat.embedgroupId>
<artifactId>tomcat-embed-jasperartifactId>
dependency>
application.yml配置文件中配置jsp(同时配置项目名、端口)
server:
port: 8989 # 指定端口
servlet:
context-path: /ems-jsp # 指定项目名
jsp:
init-parameters:
development: true # 开启jsp模板开发模式,jsp实时更新,解决页面的调试(热部署)
# 配置jsp模板
spring:
mvc:
view:
suffix: /
prefix: .jsp
springboot在展示jsp时需要进行配置
引入依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<optional>trueoptional>
dependency>
还有一些设置在上一篇博客介绍了,因为已经设置过了,所以这里不需要设置了,如果没有设置的话建议阅读一下我的上一篇博客,里面有关于热部署的详细配置。
引入依赖
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.2.4version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.38version>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.1.4version>
dependency>
在application.yml中配置mybatis相关的(同时配置日志)
# 配置jsp模板
spring:
mvc:
view:
suffix: /
prefix: .jsp
# 从这里开始是配置mybatis相关的
datasource: # 配置数据源
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/ems-jsp?characterEncoding=UTF-8 # 指定url
username: root
password: root
# 配置mybatis相关的
mybatis:
mapper-locations: classpath:com/baizhi/mapper/*.xml # mapper配置文件的位置
type-aliases-package: com.baizhi.eneity # 给资源类起别名
# 配置日志使用
logging:
level:
root: info
com.baizhi: debug # 指定包日志
在入口类上加上@MapperScan(“com.baizhi.dao”)注解扫描dao包下的所有接口
@SpringBootApplication
@MapperScan("com.baizhi.dao")
public class EmsJspApplication {
public static void main(String[] args) {
SpringApplication.run(EmsJspApplication.class, args);
}
}
pom.xml中所有的依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.apache.tomcat.embedgroupId>
<artifactId>tomcat-embed-jasperartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.2.4version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.38version>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.1.4version>
dependency>
<dependency>
<groupId>jstlgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
application.yml配置文件中所有的内容
server:
port: 8989 # 指定端口
servlet:
context-path: /ems-jsp # 指定项目名
jsp:
init-parameters:
development: true # 开启jsp模板开发模式,jsp实时更新
# 配置jsp模板
spring:
mvc:
view:
suffix: /
prefix: .jsp
# 从这里开始是配置mybatis相关的
datasource: # 配置数据源
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/ems-jsp?characterEncoding=UTF-8 # 指定url
username: root
password: root
# 配置mybatis相关的
mybatis:
mapper-locations: classpath:com/baizhi/mapper/*.xml # mapper配置文件的位置
type-aliases-package: com.baizhi.eneity # 给资源类起别名
# 配置日志使用
logging:
level:
root: info
com.baizhi: debug # 指定包日志
在main包下创建webapp包,webapp包和java包、resources包是同一个级别
先把css包、img包、js包、addEmp.html等前端页面粘贴到webapp包下
当点击验证码的换一张或页面加载的时候这张图片应该向后台发一个请求,这个请求应该请求后端的controller,在controller接收到请求之后应该做这几件事:
将验证码工具类放入utils包下
验证码工具类VerifyCodeUtils
package com.baizhi.utils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;
/**
*@创建人 cx
*@创建时间 2018/11/27 17:36
*@描述 验证码生成
*/
public class VerifyCodeUtils{
//使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
private static Random random = new Random();
/**
* 使用系统默认字符源生成验证码
* @param verifySize 验证码长度
* @return
*/
public static String generateVerifyCode(int verifySize){
return generateVerifyCode(verifySize, VERIFY_CODES);
}
/**
* 使用指定源生成验证码
* @param verifySize 验证码长度
* @param sources 验证码字符源
* @return
*/
public static String generateVerifyCode(int verifySize, String sources){
if(sources == null || sources.length() == 0){
sources = VERIFY_CODES;
}
int codesLen = sources.length();
Random rand = new Random(System.currentTimeMillis());
StringBuilder verifyCode = new StringBuilder(verifySize);
for(int i = 0; i < verifySize; i++){
verifyCode.append(sources.charAt(rand.nextInt(codesLen-1)));
}
return verifyCode.toString();
}
/**
* 生成随机验证码文件,并返回验证码值
* @param w
* @param h
* @param outputFile
* @param verifySize
* @return
* @throws IOException
*/
public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException{
String verifyCode = generateVerifyCode(verifySize);
outputImage(w, h, outputFile, verifyCode);
return verifyCode;
}
/**
* 输出随机验证码图片流,并返回验证码值
* @param w
* @param h
* @param os
* @param verifySize
* @return
* @throws IOException
*/
public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException{
String verifyCode = generateVerifyCode(verifySize);
outputImage(w, h, os, verifyCode);
return verifyCode;
}
/**
* 生成指定验证码图像文件
* @param w
* @param h
* @param outputFile
* @param code
* @throws IOException
*/
public static void outputImage(int w, int h, File outputFile, String code) throws IOException{
if(outputFile == null){
return;
}
File dir = outputFile.getParentFile();
if(!dir.exists()){
dir.mkdirs();
}
try{
outputFile.createNewFile();
FileOutputStream fos = new FileOutputStream(outputFile);
outputImage(w, h, fos, code);
fos.close();
} catch(IOException e){
throw e;
}
}
/**
* 输出指定验证码图片流
* @param w
* @param h
* @param os
* @param code
* @throws IOException
*/
public static void outputImage(int w, int h, OutputStream os, String code) throws IOException{
int verifySize = code.length();
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Random rand = new Random();
Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
Color[] colors = new Color[5];
Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,
Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,
Color.PINK, Color.YELLOW };
float[] fractions = new float[colors.length];
for(int i = 0; i < colors.length; i++){
colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
fractions[i] = rand.nextFloat();
}
Arrays.sort(fractions);
g2.setColor(Color.GRAY);// 设置边框色
g2.fillRect(0, 0, w, h);
Color c = getRandColor(200, 250);
g2.setColor(c);// 设置背景色
g2.fillRect(0, 2, w, h-4);
//绘制干扰线
Random random = new Random();
g2.setColor(getRandColor(160, 200));// 设置线条的颜色
for (int i = 0; i < 20; i++) {
int x = random.nextInt(w - 1);
int y = random.nextInt(h - 1);
int xl = random.nextInt(6) + 1;
int yl = random.nextInt(12) + 1;
g2.drawLine(x, y, x + xl + 40, y + yl + 20);
}
// 添加噪点
float yawpRate = 0.05f;// 噪声率
int area = (int) (yawpRate * w * h);
for (int i = 0; i < area; i++) {
int x = random.nextInt(w);
int y = random.nextInt(h);
int rgb = getRandomIntColor();
image.setRGB(x, y, rgb);
}
shear(g2, w, h, c);// 使图片扭曲
g2.setColor(getRandColor(100, 160));
int fontSize = h-4;
Font font = new Font("Algerian", Font.ITALIC, fontSize);
g2.setFont(font);
char[] chars = code.toCharArray();
for(int i = 0; i < verifySize; i++){
AffineTransform affine = new AffineTransform();
affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, h/2);
g2.setTransform(affine);
g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, h/2 + fontSize/2 - 10);
}
g2.dispose();
ImageIO.write(image, "jpg", os);
}
private static Color getRandColor(int fc, int bc) {
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}
private static int getRandomIntColor() {
int[] rgb = getRandomRgb();
int color = 0;
for (int c : rgb) {
color = color << 8;
color = color | c;
}
return color;
}
private static int[] getRandomRgb() {
int[] rgb = new int[3];
for (int i = 0; i < 3; i++) {
rgb[i] = random.nextInt(255);
}
return rgb;
}
private static void shear(Graphics g, int w1, int h1, Color color) {
shearX(g, w1, h1, color);
shearY(g, w1, h1, color);
}
private static void shearX(Graphics g, int w1, int h1, Color color) {
int period = random.nextInt(2);
boolean borderGap = true;
int frames = 1;
int phase = random.nextInt(2);
for (int i = 0; i < h1; i++) {
double d = (double) (period >> 1)
* Math.sin((double) i / (double) period
+ (6.2831853071795862D * (double) phase)
/ (double) frames);
g.copyArea(0, i, w1, 1, (int) d, 0);
if (borderGap) {
g.setColor(color);
g.drawLine((int) d, i, 0, i);
g.drawLine((int) d + w1, i, w1, i);
}
}
}
private static void shearY(Graphics g, int w1, int h1, Color color) {
int period = random.nextInt(40) + 10; // 50;
boolean borderGap = true;
int frames = 20;
int phase = 7;
for (int i = 0; i < w1; i++) {
double d = (double) (period >> 1)
* Math.sin((double) i / (double) period
+ (6.2831853071795862D * (double) phase)
/ (double) frames);
g.copyArea(i, 0, 1, h1, 0, (int) d);
if (borderGap) {
g.setColor(color);
g.drawLine(i, (int) d, i, 0);
g.drawLine(i, (int) d + h1, i, h1);
}
}
}
public static void main(String[] args) throws IOException {
//获取验证码
String s = generateVerifyCode(4);
//将验证码放入图片中
outputImage(260,60,new File("/Users/chenyannan/Desktop/安工资料/aa.jpg"),s);
System.out.println(s);
}
}
测试验证码类生成图片方法:
public class VerifyCodeTests {
@Test
public void testGenerate() throws IOException {
// 生成一个几位数随机数
String s = VerifyCodeUtils.generateVerifyCode(4);
System.out.println(s);
// 写入图片
// 参数1:宽 参数2:高 参数3:图片生成到哪里 参数4:验证码
File os = new File("D:\\springbootcodes\\ems-jsp\\aa.png");
VerifyCodeUtils.outputImage(220, 80, os, s);
}
}
将regist.html修改为regist.jsp,并在regist.jsp文件里加上jap文件的表头
<%@ page pageEncoding="UTF-8" contentType="text/html; UTF-8" isELIgnored="false" %>
开发控制器
// 用来开发用户模块功能
@Controller
@RequestMapping("user")
public class UserController {
/**
* 用来生成验证码的方法
*/
@RequestMapping("generateImageCode")
public void generateImageCode(HttpSession session, HttpServletResponse response) throws IOException {
// 1. 生成随机字符串
String code = VerifyCodeUtils.generateVerifyCode(4); // 生成4位的验证码
// 2. 保存随机字符串到Session中
session.setAttribute("code", code);
// 3. 将随机字符串生成图片
// 4. 通过response响应图片
response.setContentType("image/png"); // 设置响应类型为png
ServletOutputStream os = response.getOutputStream();
VerifyCodeUtils.outputImage(220, 80, os, code);
}
}
修改regist.jsp文件中的验证码图片路径
${pageContext.request.contextPath}/user/generateImageCode
将换一张的路径修改为验证码图片的路径重新发一次请求
换一张
判断验证码是否一致
如果一致完成用户注册
判断用户(用户名应该唯一)是否存在
再去完成注册业务
完成注册向数据库中保存当前的用户信息
a.保存信息之前判断当前用户名是否存在 如果存在直接返回错误
b.如果当前用户名不存在保护用户信息 保存用户信息给密码进行加密处理
创建实体类user
public class User {
private Integer id;
private String username;
private String realname;
private String password;
private Boolean gender; // 数据库在存的时候性别是1和0,到实体类中就转化为bool了,true代表男,false代表女
// 提供有参、无参构造方法、get、set方法、toString方法
// 为了避免代码太多影响阅读体验,这里并没有粘,但其实是有的
}
Controller中的注册方法
前端的regist.jsp页面中的名字可能和方法参数中user对象中的属性名不一致,需要改一下前端传过来的数据的name,如果验证码的name也和注册方法的验证码名字不一致也要修改
// 用来开发用户模块功能
@Controller
@RequestMapping("user")
public class UserController {
private static final Logger log = LoggerFactory.getLogger(UserController.class);
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
/**
* 用户注册
* @return
*/
@RequestMapping("register")
public String register(User user, String code, HttpSession session) throws UnsupportedEncodingException {
log.debug("接收到的验证码:{}" + code);
log.debug("用户名:{}, 真实姓名:{}, 密码:{}, 性别:{}", user.getUsername(), user.getRealname(), user.getPassword(), user.getGender());
try {
// 1. 比较验证是否一致
String sessionCode = session.getAttribute("code").toString();
// 如果验证码不一致,程序抛出异常,不会再往下执行;否则会继续后面的注册用户操作
if(!sessionCode.equalsIgnoreCase(code)) throw new RuntimeException("验证码输入错误!");
// 2. 注册用户
userService.register(user);
} catch (RuntimeException e) {
e.printStackTrace();
// 注册失败进行重新注册并在页面上展示出错误信息
return "redirect:/regist.jsp?msg=" + URLEncoder.encode(e.getMessage(), "UTF-8");
}
// 注册成功跳转到登录页面
return "redirect:/login.jsp";
}
}
创建service接口
public interface UserService {
// 用户注册
void register(User user);
}
创建Service实现类
@Service
@Transactional
public class UserServiceImpl implements UserService{
private UserDAO userDAO;
@Autowired
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
@Override
public void register(User user) {
// 1. 根据用户查询数据库是否存在该用户名
User userDB = userDAO.findByUserName(user.getUsername());
// 2. 如果存在报错:用户名已经存在
// 工具类判断是否为空,不为空返回false,取反之后变为true
if(!ObjectUtils.isEmpty(userDB)) throw new RuntimeException("用户名已存在!");
// 3. 如果不存在进行注册,进行注册之前给明文密码加密
// 给密码加密,并且将加密后的密码设置进去
String passwordSecret = DigestUtils.md5DigestAsHex(user.getPassword().getBytes(StandardCharsets.UTF_8));
user.setPassword(passwordSecret);
userDAO.save(user);
}
}
创建DAO接口
public interface UserDAO {
// 根据用户名查询用户
User findByUserName(String username);
// 保存用户
void save(User user);
}
DAO接口对应的mapper配置文件
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.baizhi.dao.UserDAO">
<select id="findByUserName" parameterType="String" resultType="com.baizhi.eneity.User">
select id, username, realname, password, gender from user where username = #{username}
select>
<insert id="save" parameterType="com.baizhi.eneity.User" useGeneratedKeys="true" keyProperty="id">
insert into user values(#{id}, #{username}, #{realname}, #{password}, #{gender})
insert>
mapper>
根据用户输入用户名去数据库中查询是否存在该用户名
如果存在,判断密码是否一致 如果不存在,用户名输入错误
判断密码根据数据库加密密码与对接收密码进行md5加密之后比较
md5:只要内容相同 多次计算md5 结果一定是一致
保存用户登录标记到Session中
登录方法
// 用来开发用户模块功能
@Controller
@RequestMapping("user")
public class UserController {
private static final Logger log = LoggerFactory.getLogger(UserController.class);
private UserService userService;
/**
* 用户登录
* @return
*/
@RequestMapping("login")
public String login(String username, String password, HttpSession session) throws UnsupportedEncodingException {
log.debug("接收到用户名:{}, 接收到密码:{}", username, password);
try {
// 1. 执行登陆业务逻辑
User user = userService.login(username, password);
// 2. 登录成功,保存用户登录的标记
session.setAttribute("user",user);
} catch (Exception e) {
e.printStackTrace();
return "redirect:/login.jsp?msg=" + URLEncoder.encode(e.getMessage(), "UTF-8");
}
return "redirect:/emplist.jsp";
}
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}
userDAO
public interface UserDAO {
// 根据用户名查询用户,该方法已在上一个注册功能时实现过,所以这里不再粘贴mapper配置文件
User findByUserName(String username);
}
service接口
public interface UserService {
// 用户注册
void register(User user);
User login(String username, String password);
}
service实现类
@Service
@Transactional
public class UserServiceImpl implements UserService{
private UserDAO userDAO;
@Autowired
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
@Override
public User login(String username, String password) {
// 1. 根据用户输入用户名查询数据库中是否存在
User user = userDAO.findByUserName(username);
// 2. 判断对象是否存在
if(ObjectUtils.isEmpty(user)) throw new RuntimeException("用户名输入错误");
// 3. 判断密码正确性
String digestPassword = DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
if(!user.getPassword().equals(digestPassword)) throw new RuntimeException("密码输入错误");
return user;
}
}
将login.jsp的表单提交修改为提交给login方法,并修改提交数据的name与数据库中user的属性一致
登陆成功会跳转到员工列表页面,将emplist.html文件改为emplist.jsp,并加上jsp文件的头
<%@ page pageEncoding="UTF-8" contentType="text/html; UTF-8" isELIgnored="false" %>
如果登录错误登录页面login.jsp要展示后端传过来的错误信息
另外还要处理一下登录页面login.jsp的regist的链接到regist.jsp
另外如果还想再注册页面登录需要在regist.jsp中填上这句话
员工Controller
/**
* 用来开发员工相关功能
*/
@Controller
@RequestMapping("/employee")
public class EmployeeController {
private static final Logger log = LoggerFactory.getLogger(EmployeeController.class);
private EmployeeService employeeService;
@Autowired
public EmployeeController(EmployeeService employeeService) {
this.employeeService = employeeService;
}
/**
* 员工列表
*
* @return
*/
@RequestMapping("list")
public String listEmployee(HttpServletRequest request, Model model) {
//1.获取员工列表
List<Employee> employees = employeeService.list();
//request.setAttribute("employees",employees);
model.addAttribute("employees", employees);
return "emplist";
}
}
员工Dao接口
public interface EmployeeDao {
//查询员工信息列表
List<Employee> list();
}
员工Dao对应的mapper配置文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.baizhi.dao.EmployeeDao">
<select id="list" resultType="Employee">
select id,name,birthday,salary,gender from `employee`
select>
mapper>
员工Service
public interface EmployeeService {
//员工列表
List<Employee> list();
}
员工Service的实现类
@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService{
private EmployeeDao employeeDao;
@Autowired
public EmployeeServiceImpl(EmployeeDao employeeDao) {
this.employeeDao = employeeDao;
}
@Override
public List<Employee> list() {
return employeeDao.list();
}
}
在用户登录之后展示出员工列表,所以要将用户登录方法之后跳转到员工列表方法
在emplist.jsp进行遍历时需要在第二行写入
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
但是idea在写 为了在跳转之后不因为相对路径产生歧义,在emplist.jsp里明确告诉应该从哪里哪css 生日和性别与数据库对应 为了使日期格式化还有数据库性别是1显示男数据库性别是0显示女 员工controller中的添加方法 EmployeeService接口 EmployeeService实现类 EmployeeDao接口 EmployeeDao接口对应的mapper配置文件 将addEmp.html修改为addEmp.jsp,并添加上jsp的头信息 修改emplist.jsp的跳转到addEmp.jsp 修改addEmp.jsp跳转到controller的添加方法,并将表单中传递数据的name与Employee中的属性一一对应 springboot springmvc spring 默认处理日期格式: yyyy/MM/dd HH:mm:ss 如果想要修改对象中日期属性格式,需要在对象的日期属性上加上@DateTimeFormat(pattern = “yyyy-MM-dd”) 注解修改日期格式 上半步 数据回显: 1. 点击展示页面的更新链接传递当前更新员工id到controller 3. 将查询到的员工信息保存到作用域 4. 跳转到更新页面展示修改员工信息 下半步 更新操作: 1. 获取更新之后员工信息 2. 更新数据库 员工controller中的根据id查询用户的方法和更新方法 EmployeeService接口 EmployeeService接口实现类 EmployeeDao接口 EmployeeDao接口对应的mapper配置文件,根据id查询员工信息,更新员工信息 将updateEmp.html修改为updateEmp.jsp并添加上jsp的表头 将更新页面的回显数据取为员工controller的detail方法传过来的数据,并且处理一下性别,当性别是1让“男”显示,当性别是0让“女”显示(使用c标签时要在jsp前面导入) 在展示员工列表页面一点更新的时候应该跳转到updateEmp.jsp,并且应该将点的那条员工信息在updateEmp.jsp进行一个回写,也就是说应该拿着那条记录的id到数据库中查这个人的信息,把信息查出来依赖再把信息展示到页面上,修改emplist.jsp的跳转到员工controller的根据id查询员工方法并通过拼接将id传过去 为了防止样式丢失,updateEmp.jsp的css路径应该改为绝对路径 将updateEmp.jsp中的生日修改为格式化 更新操作时updateEmp.jsp应该发送请求的员工controller的更新方法,并且将穿过的数据name与Employee的属性名一一对应 员工controller的删除方法 EmployeeService接口 EmployeeService接口实现类 EmployeeDao接口 EmployeeDao接口对应的mapper配置文件 在展示列表页面点击删除按钮应该跳转到员工controller的删除方法,并且将id传给后端的删除方法 在展示列表页面中User登录之后出现 Welcome 用户真实名字 在展示列表页面按删除按钮时应该有一个确认,确认删除再删除 列表展示页面相邻两行底层颜色不同
员工添加功能实现
/**
* 用来开发员工相关功能
*/
@Controller
@RequestMapping("/employee")
public class EmployeeController {
private static final Logger log = LoggerFactory.getLogger(EmployeeController.class);
private EmployeeService employeeService;
@Autowired
public EmployeeController(EmployeeService employeeService) {
this.employeeService = employeeService;
}
/**
* 添加员工信息
* @return
*/
@RequestMapping("add")
public String addEmployee(Employee employee){
log.debug("员工名称: {}", employee.getName());
log.debug("员工工资: {}", employee.getSalary());
log.debug("员工生日: {}", employee.getBirthday());
log.debug("员工性别: {}", employee.getGender());
// 1. 保存员工信息
employeeService.add(employee);
return "redirect:/employee/list"; // 跳转到列表
}
/**
* 员工列表
*
* @return
*/
@RequestMapping("list")
public String listEmployee(HttpServletRequest request, Model model) {
//1.获取员工列表
List<Employee> employees = employeeService.list();
//request.setAttribute("employees",employees);
model.addAttribute("employees", employees);
return "emplist";
}
}
public interface EmployeeService {
//员工列表
List<Employee> list();
// 添加员工信息
void add(Employee employee);
}
@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService{
private EmployeeDao employeeDao;
@Autowired
public EmployeeServiceImpl(EmployeeDao employeeDao) {
this.employeeDao = employeeDao;
}
@Override
public List<Employee> list() {
return employeeDao.list();
}
@Override
public void add(Employee employee) {
employeeDao.add(employee);
}
}
public interface EmployeeDao {
//查询员工信息列表
List<Employee> list();
// 添加员工信息
void add(Employee employee);
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.baizhi.dao.EmployeeDao">
<select id="list" resultType="Employee">
select id,name,birthday,salary,gender from `employee`
select>
<insert id="add" parameterType="Employee" useGeneratedKeys="true" keyProperty="id">
insert into `employee` values(#{id}, #{name}, #{birthday}, #{salary}, #{gender})
insert>
mapper>
<%@page pageEncoding="UTF-8" contentType="text/html; UTF-8" isELIgnored="false" %>
员工更新功能实现
2. 在controller中根据id查询员工信息
/**
* 用来开发员工相关功能
*/
@Controller
@RequestMapping("/employee")
public class EmployeeController {
private static final Logger log = LoggerFactory.getLogger(EmployeeController.class);
private EmployeeService employeeService;
@Autowired
public EmployeeController(EmployeeService employeeService) {
this.employeeService = employeeService;
}
/**
* 更新员工信息
* @return
*/
@RequestMapping("update")
public String updateEmployee(Employee employee){
log.debug("员工id: {}", employee.getId());
log.debug("员工名称: {}", employee.getName());
log.debug("员工工资: {}", employee.getSalary());
log.debug("员工生日: {}", employee.getBirthday());
log.debug("员工性别: {}", employee.getGender());
// 1. 更新员工信息
employeeService.update(employee);
// 2. 跳转到员工列表
return "redirect:/employee/list";
}
/**
* 根据id查询员工信息
* @return
*/
@RequestMapping("detail")
public String detailEmployee(Integer id, Model model){
log.debug("接收id: {}", id);
// 1. 根据员工查询一个员工
Employee employee = employeeService.idByEmployee(id);
// 2. 存入作用域
model.addAttribute("employee", employee);
return "updateEmp"; // 跳转页面
}
/**
* 员工列表
*
* @return
*/
@RequestMapping("list")
public String listEmployee(HttpServletRequest request, Model model) {
//1.获取员工列表
List<Employee> employees = employeeService.list();
//request.setAttribute("employees",employees);
model.addAttribute("employees", employees);
return "emplist";
}
}
public interface EmployeeService {
//员工列表
List<Employee> list();
// 添加员工信息
void add(Employee employee);
// 根据id查询员工信息
Employee idByEmployee(Integer id);
// 更新员工信息
void update(Employee employee);
}
@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService{
private EmployeeDao employeeDao;
@Autowired
public EmployeeServiceImpl(EmployeeDao employeeDao) {
this.employeeDao = employeeDao;
}
@Override
public List<Employee> list() {
return employeeDao.list();
}
@Override
public void add(Employee employee) {
employeeDao.add(employee);
}
@Override
public Employee idByEmployee(Integer id) {
return employeeDao.idByEmployee(id);
}
@Override
public void update(Employee employee) {
employeeDao.update(employee);
}
}
public interface EmployeeDao {
//查询员工信息列表
List<Employee> list();
// 添加员工信息
void add(Employee employee);
// 根据id查询员工信息
Employee idByEmployee(Integer id);
// 更新员工信息
void update(Employee employee);
}
<select id="idByEmployee" parameterType="Integer" resultType="Employee">
select id, name, birthday, salary, gender from `employee`
where id = #{id}
select>
<update id="update" parameterType="Employee">
update employee set name = #{name}, birthday=#{birthday}, salary = #{salary}, gender = #{gender}
where id = #{id}
update>
<%@page pageEncoding="UTF-8" contentType="text/html; UTF-8" isELIgnored="false" %>
员工删除功能实现
/**
* 用来开发员工相关功能
*/
@Controller
@RequestMapping("/employee")
public class EmployeeController {
private static final Logger log = LoggerFactory.getLogger(EmployeeController.class);
private EmployeeService employeeService;
@Autowired
public EmployeeController(EmployeeService employeeService) {
this.employeeService = employeeService;
}
/**
* 根据id删除员工信息
*/
@RequestMapping("delete")
public String deleteEmployee(Integer id){
log.debug("删除的id: {}", id);
// 1. 根据id删除员工信息
employeeService.delete(id);
// 2. 跳转到列表页面
return "redirect:/employee/list";
}
/**
* 员工列表
*
* @return
*/
@RequestMapping("list")
public String listEmployee(HttpServletRequest request, Model model) {
//1.获取员工列表
List<Employee> employees = employeeService.list();
//request.setAttribute("employees",employees);
model.addAttribute("employees", employees);
return "emplist";
}
}
public interface EmployeeService {
//员工列表
List<Employee> list();
// 添加员工信息
void add(Employee employee);
// 根据id查询员工信息
Employee idByEmployee(Integer id);
// 更新员工信息
void update(Employee employee);
// 根据id删除员工信息
void delete(Integer id);
}
@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService{
private EmployeeDao employeeDao;
@Autowired
public EmployeeServiceImpl(EmployeeDao employeeDao) {
this.employeeDao = employeeDao;
}
@Override
public List<Employee> list() {
return employeeDao.list();
}
@Override
public void add(Employee employee) {
employeeDao.add(employee);
}
@Override
public Employee idByEmployee(Integer id) {
return employeeDao.idByEmployee(id);
}
@Override
public void update(Employee employee) {
employeeDao.update(employee);
}
@Override
public void delete(Integer id) {
employeeDao.delete(id);
}
}
public interface EmployeeDao {
//查询员工信息列表
List<Employee> list();
// 添加员工信息
void add(Employee employee);
// 根据id查询员工信息
Employee idByEmployee(Integer id);
// 更新员工信息
void update(Employee employee);
// 根据id删除员工信息
void delete(Integer id);
}
<?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.baizhi.dao.EmployeeDao">
<!--员工列表-->
<select id="list" resultType="Employee">
select id,name,birthday,salary,gender from `employee`
</select>
<!--添加员工信息-->
<insert id="add" parameterType="Employee" useGeneratedKeys="true" keyProperty="id">
insert into `employee` values(#{id}, #{name}, #{birthday}, #{salary}, #{gender})
</insert>
<!--根据id查询一个员工信息-->
<select id="idByEmployee" parameterType="Integer" resultType="Employee">
select id, name, birthday, salary, gender from `employee`
where id = #{id}
</select>
<!--更新员工信息-->
<update id="update" parameterType="Employee">
update employee set name = #{name}, birthday=#{birthday}, salary = #{salary}, gender = #{gender}
where id = #{id}
</update>
<!--根据id删除员工信息-->
<delete id="delete" parameterType="Integer">
delete from employee where id = #{id}
</delete>
</mapper>
一些细节
6. 部分效果图展示