spring boot项目练习

#员工管理系统

1.项目准备

- 需求分析      模块 功能
- 库表设计      数据库
- 详细设计      流程图伪代码方式(没用上)
- 编码环节      
    环境准备
    正式进入编码环节
- 测试
- 部署上线

2.技术选项

- 前端:vue + axios
- 后端:springboot + mybatis + mysql + tomcat

3.需求分析

###开始

1.创建数据库表

create table t_user(
	id int(6) primary key auto_increment,
	username varchar(60),
	realname varchar(60),
	password varchar(50),
	sex varchar(4),
	status varchar(4),
	regsterTime timestamp
);

create table t_emp(
	id int(6) primary key auto_increment,
	`name` varchar(40),
	path varchar(100),
	salary double(10,2),
	age int(3)
);

2.创建springboot的项目
3.导入依赖

<dependencies>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.1.21</version>
		</dependency>
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.4</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.1.4</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.junit.vintage</groupId>
			<artifactId>junit-vintage-engine</artifactId>
			<version>5.5.2</version>
			<scope>test</scope>
		</dependency>

	</dependencies>

4.编写配置文件

server.servlet.context-path=/ems_vue
server.port=8989
spring.application.name=ems

#配置数据库
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/emps?characterEncoding=utf-8
#配置数据库

#路径
mybatis.mapper-locations=classpath:com/huang/mapper/*.xml
mybatis.type-aliases-package=com.huang.entity

#日志
logging.level.com.huang.dao=debug
logging.level.com.huang.service=info
logging.level.com.huang.controller=info

##功能一、验证码的实现

1.编写注册页面regist.html

<div id="wrap">
    <h1>我是注册页面</h1>
    <div>
        <h1>
            <a href="#">main</a>
        </h1>
    </div>
    <div>
        <h1>注册</h1>
        <form action="login.html" method="post">
            <table cellpadding="0" cellspacing="0" border="0">
                <tr>
                    <td valign="middle" align="right">
                        用户名:
                    </td>
                    <td valign="middle" align="left">
                        <input type="text" name="username"/>
                    </td>
                </tr>
                <tr>
                    <td valign="middle" align="right">
                        真实姓名:
                    </td>
                    <td valign="middle" align="left">
                        <input type="text" name="name"/>
                    </td>
                </tr>
                <tr>
                    <td valign="middle" align="right">
                        密码:
                    </td>
                    <td valign="middle" align="left">
                        <input type="password" name="pwd"/>
                    </td>
                </tr>
                <tr>
                    <td valign="middle" align="right">
                        性别:
                    </td>
                    <td valign="middle" align="left"><input type="radio" name="sex" value="m" checked/><input type="radio" name="sex" value="f"/>
                    </td>
                </tr>

                <tr>
                    <td valign="middle" align="right">
                        验证码:
                    </td>
                    <td valign="middle" align="left">
                        <input type="text" name="number"/>
                    </td>
                    <td>
                        <!--用vue的 :src ,url 方法在下面的script中实现-->
                        <img id="num" :src="url"/>
                        <!--用vue的 @click ,getImg方法在下面的script中实现-->
                        <a href="javascript:;" @click="getImg">
                        <!--点击‘换一张’ 就会触发一次 getImg 方法,具体方法实现见<script>中-->
                            换一张
                        </a>
                    </td>
                </tr>
            </table>
            <p>
                <input type="submit" value="提交"/>
            </p>
        </form>
    </div>
</div>

2.在regist.html中导入js文件(vue和axios的)

<script src="/ems_vue/js/vue.js"></script>
<script src="/ems_vue/js/axios.min.js"></script>

3.在java/main/com/huang/utils/VerifyCodeUtils.java文件中写生成验证码的工具类(网上找的资源)
4.编写controller,在…/UserController.java文件中

    /**
     * 生成验证码图片
     */
    @GetMapping("getImage")
    public String getImageCode(HttpServletRequest request) throws IOException {
        //1.使用工具类生成验证码
        String code = VerifyCodeUtils.generateVerifyCode(4);
        //2.放入servletContext作用域
        request.getServletContext().setAttribute("code",code);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        VerifyCodeUtils.outputImage(120,30,byteArrayOutputStream,code);
        return "data:image/png;base64,"+ Base64Utils.encodeToString(byteArrayOutputStream.toByteArray());
    }

5.在regist.html文件中编写vue相关的axios,为了获取到验证码图片

<script>
    var app = new Vue({
        el:"#wrap",
        data:{
            url:"",
        },
        methods:{
          getImg(){
             this.getSrc();
          },
            //封装获取随机验证码的图片(实现方法的复用)
          getSrc(){
            var _this = this;
            //这个 ?time"+Math.random() 是为了实现随机产生一个
            axios.get("http://localhost:8989/ems_vue/user/getImage?time"+Math.random()).then(res =>{
                console.log(res.data);
                _this.url = res.data;
            });
          }
        },
        created(){
            this.getSrc();
        }
    })
</script>

##功能二、注册的实现

1.构建用户实体对象,在…/entity/User.java中

package com.huang.entity;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;

@Data
@Accessors(chain = true) //让set方法返回的不是void
public class User {
    private String id; //数据库中是int,但在这里用String类型,是String类型的api较多,可以进行更为复杂的操作
    private String username;
    private String realname;
    private String password;
    private String sex;
    private String status;
    private Date regsterTime;
}

2.写一个关于插入的UserDAO接口,在…/dao/UserDAO.java中

package com.huang.dao;
import com.huang.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper //用来创建DAO对象
public interface UserDAO {
    void save(User user);
}

3.写mapper配置文,在resources/com/huang/mapper/UserDAOMapper.xml中

<?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">

<!--命名空间一定要记得写,它管理的是com.huang.dao.UserDAO的接口-->
<mapper namespace="com.huang.dao.UserDAO">

    <!-- useGeneratedKeys="true" keyProperty="id"使用自动生成的id -->
    <insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">
        insert into emps.t_user values (#{id},#{username},#{realname},#{password},#{sex},#{status},#{regsterTime})
    </insert>
</mapper>

4.编写业务方法,编写业务接口,在…/service/UserService.java接口中

package com.huang.service;
import com.huang.entity.User;
//业务接口
public interface UserService {
    //用户注册的方法
    void register(User user);
}

5.对应的业务层,实现业务,在…/Service/UserServiceImpl.java中去实现UserService接口

package com.huang.service;
import com.huang.dao.UserDAO;
import com.huang.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;

@Service
@Transactional
public class UserServiceImpl implements UserService {
    //调用业务,去处理DAO,所以直接注入 UserDAO
    @Autowired
    private UserDAO userDAO;

    @Override
    public void register(User user) {    
            //1.生成用户的状态
            user.setStatus("已经激活了哦");
            //2.设置用户注册的时间
            user.setRegsterTime(new Date());
            //3.调用DAO
            userDAO.save(user);
    }
}

6.在UserController.java中添加一个注册功能的方法

@Autowired
private UserService userService;
/**
 * 用来处理用户注册方法
 */
@PostMapping("register")
        // Map是用来承载注册的信息
        // @RequestBody User user ,user用来接收用户信息,其中的@RequestBody将json转换为User对象
        // code用来表示接收验证码信息
        // 用HttpServletRequest request 来拿之前的验证码信息
public Map<String, Object> register(@RequestBody User user, String code, HttpServletRequest request){
    log.info("用户信息:[{}]",user.toString()); //打印日志信息
    log.info("用户输入的验证信息:[{}]",code);

    Map<String, Object> map = new HashMap<>(); //构建map集合来存放数据
    //1.调用业务方法
    try {
        String key = (String) request.getServletContext().getAttribute("code"); //用request来拿前面存的code
        //判断 用户输入的验证码key 和,当前的验证码code是否一致
        if (key.equalsIgnoreCase(code)) { 
            userService.register(user);
            map.put("state", true); //state是表示状态
            map.put("msg", "注册成功L");
        }else {
            //当验证码没有通过时,抛出异常,再进入catch
            throw new RuntimeException("验证码出现错误咯哦");
        }
    } catch (Exception e){
        e.printStackTrace();
        map.put("state", false);
        map.put("msg","注册失败Q"+e.getMessage()); // e.getMessage() 表示用e捕获的具体信息
    }
    return map;

}

7.处理前台,发起request请求

- 1.在vue中定义一个user对象
data:{
    user:{//定义一个user对象,为了注册用户使用的
            sex:"男"
        },
    code:""
    },
- 2.将用户输入的信息绑定给user对象 v-model="user.username"
<td valign="middle" align="left">
    <input type="text" v-model="user.username"/>
</td>
- 3.同理将realname、password、sex都用v-model="user.xxx"去绑定
- 4.绑定验证码(但验证码不属于用户信息),要去data中定义一个code,然后再绑定v-model="code"
- 5.给提交表单的button 添加单击事件 @click="register",对这个事件,要在后台(即<script>中)发起请求
<script>
    var app = new Vue({
        el:"#wrap",
        data:{
            url:"",
            user:{//定义一个user对象,为了注册用户使用的
                sex:"男"  //这个默认值,是让初始的时候就被选中,因为上面的 value="男"
            },
            code:""
        },
        methods:{
          getImg(){
             this.getSrc();
          },
            //封装获取随机验证码的图片(实现方法的复用)
          getSrc(){
            var _this = this;
            axios.get("http://localhost:8989/ems_vue/user/getImage?time"+Math.random()).then(res =>{
                console.log(res.data);
                _this.url = res.data;
            });
          },
          //@click="register" 对点击事件发起请求的操作
            //用来注册用户信息的
          register() {
              // 01.对http://localhost:8989/ems_vue/user/register路径发起一个post请求
              // 02.这里的 +this.code, this.user 代表地址栏传参,可以直接赋值给UserController.java 中对应的
              // public Map<String, Object> register(@RequestBody User user, String code, HttpServletRequest request) 
              // 的code 和user 
              // 03.通过then来拿到结果(ES6的语法),  .then(res => {
              axios.post("http://localhost:8989/ems_vue/user/register?code="+this.code, this.user).then(res => {
                  console.log(res.data); //结果的打印,res.data是代表拿到的结果
                  if (res.data.state){
                      alert(res.data.msg+",点击确定跳转至登录页面!");
                      location.href="/ems_vue/login.html";
                  }else {
                      alert(res.data.msg);
                  }
              });
          }
        },
        created(){
            this.getSrc();
        }
    })
</script>

8.根据用户输入的用户名,判断用户名是否存在(基于用户名去查询)

- 1.在UserDAO.java接口中先加入一个方法
 User findByUserName(String username);
- 2.对findByUserName方法的实现,在UserDAOMapper.xml文件中
<select id="findByUserName" parameterType="String" resultType="User">
    select id,username,realname,password,sex,status,regsterTime
    from emps.t_user
    where username = #{username};
</select>
- 3.在业务层做处理UserServiceImpl.java中,先查询用户User userDB = userDAO.findByUserName(user.getUsername()); 在判断是否为空if
package com.huang.service;
import com.huang.dao.UserDAO;
import com.huang.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDAO userDAO;

    @Override
    public void register(User user) {
        //0.查询用户输入用户名,判断用户是否存在
        User userDB = userDAO.findByUserName(user.getUsername());
        if (userDB == null){
            //1.生成用户的状态
            user.setStatus("已经激活了哦");
            //2.设置用户注册的时间
            user.setRegsterTime(new Date());
            //3.调用DAO
            userDAO.save(user);
        } else {
            throw new RuntimeException("用户名已经存在了,请修改。。。");
        }
    }
}

##功能三、登录

1.可以复用注册中使用名字查询的方法,即UserDAO.java中的findByUserName和相关的xml文件
2.在UserService.java接口中添加用户登录方法

 User login(User user);

3.到UserServiceImpl.java中去实现 改登录方法

//实现UserService接口中的用户登录方法
@Override
public User login(User user) {
    //1.根据用户输入的用户名进行查询
    User userDB = userDAO.findByUserName(user.getUsername());
    //判断用户名是否为空(到数据库中比较,是否为空)
    if (!ObjectUtils.isEmpty(userDB)){  // 使用工具类 !ObjectUtils.isEmpty(userDB)的使用和userDB != null的效果相同
        //2.用户名不为空时,再比较密码
            //数据库中的密码userDB.getPassword() 和 当前的用户输入的密码user.getPassword() 作比较
        if (userDB.getPassword().equals(user.getPassword())) { 
            return userDB;
        } else {
            throw new RuntimeException("密码不对哦");
        }
    }else {
        throw new RuntimeException("用户名输入错误哦");
    }
}

4.再到UserController.java中,处理登录方法

/**
 * 用来处理登录方法
 */
@PostMapping("login")
public Map<String, Object> login(@RequestBody User user){
    log.info("当前的登录用户的信息:[{}]",user.toString());
    //1、收集数据
    Map<String, Object> map = new HashMap<>(); 

    try {
        //2、调用业务方法 userService
        User userDB = userService.login(user);
        map.put("state", true);
        map.put("msg", "登录成功啦!");
    } catch (Exception e){
        e.printStackTrace();
        map.put("state", false);
        map.put("msg", e.getMessage());
    }
    return map;
}

5.修改前端页面,在login.html

- 1.双向绑定用户名和密码 v-model="user.xxx"
- 2.对‘登录’时,添加一个单击事件 @click="login" 要在methods中写一个login(){}方法
<script src="/ems_vue/js/vue.js"></script>
<script src="/ems_vue/js/axios.min.js"></script>

<script>
<!--  new 一个vue实例 -->
    var app = new Vue({
        el:"#wrap",
        data:{
            user:{}, //用来保存用户数据
        },
        methods:{
            //点击事件触发@click="login" 后,用户登录的方法
            login(){
                console.log(this.user);
                //发送登录请求
                axios.post("http://localhost:8989/ems_vue/user/login",this.user).then( res =>{
                    console.log(res.data);
                    if (res.data.state){
                        alert(res.data.msg+"点击确定,就到了另外一个地方啦");
                        location.href="/ems_vue/emplist.html";
                    }else {
                        alert(res.data.msg);
                    }
                });
            }
        }
    });
</script>

##功能四、展示用户信息(欢迎用户进入)

1.在UserController.java中,添加 map.put(“user”,userDB); 为了把登录的用户信息给user,给前端使用

/**
 * 用来处理登录方法
 */
@PostMapping("login")
public Map<String, Object> login(@RequestBody User user){
    log.info("当前的登录用户的信息:[{}]",user.toString());
    Map<String, Object> map = new HashMap<>();

    try {
        User userDB = userService.login(user);
        map.put("state", true);
        map.put("msg", "登录成功啦!");
        //在登录成功之后,放了一个用户的数据
        map.put("user",userDB); //将用户信息给user
    } catch (Exception e){
        e.printStackTrace();
        map.put("state", false);
        map.put("msg", e.getMessage());
    }
    return map;
}

2.在前端的login.html中,将登录的用户信息放入localStorage中

 //将登录的用户信息放入localStorage key value
localStorage.setItem("user",JSON.stringify(res.data.user));
//这里的"user"就是,在后台获取的 map.put("user",userDB); 里面的"user"
//这里的JSON.stringify(res.data.user)是将"user"存入res.data.user中,并且将对象形式转为JSON形式的存储

3.在emplist.html中取出用户信息,并使用

<script src="/ems_vue/js/vue.js"></script>
<script src="/ems_vue/js/axios.min.js"></script>

<script>
    var app = new Vue({
        el:"#wrap",
        data:{ //vue的数据
           user:{
               realname:""
           } //这个user对象是用来存放用户登录的信息
        },
        methods:{  //自定义函数
        },
        created(){  //生命周期函数
            var userJSONString = localStorage.getItem("user");  //将login.html中存的数据取出来
            if (userJSONString){
                var user = JSON.parse(userJSONString); //将取出来的数据userJSONString转化为对象形式
                this.user = user;  //将去出来的数据user,赋值给data:{}中定义的数据user:{},即this.user
            } else{
                alert("您还没有登录哦!点击确定跳转到登录页面吧");
                location.href="/ems_vue/login.html";
            }

        }
    });
</script>

##功能五、安全退出

1.在emplist.html中添加‘安全退出’的按钮,添加点击事件@click=“logout”

<h1>
    <input type="button" value="安全退出" @click="logout">
</h1>

2.在emplist.html中,为绑定的事件logout添加方法

 methods:{  //自定义函数
    //处理安全退出
    logout(){
        localStorage.removeItem("user");
        location.reload(true);  //刷新页面
    }
},

功能六、列表展示

1.构建实体对象…/entity/Emp.java

package com.huang.entity;
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class Emp {
    private String id;
    private String name;
    private String path;
    private Double salary;
    private int age;
}

2.开发Emp的接口…/dao/EmpDAO.java

package com.huang.dao;
import com.huang.entity.Emp;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;

@Mapper //用于创建DAO对象
public interface EmpDAO {
    
    List<Emp> findAll(); //查询所有的方法
}

3.对接口中的findAll()方法的实现,resources/com/huang/mapper/EmpDAPMapper.xml

<?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.huang.dao.EmpDAO">

    <select id="findAll" resultType="Emp">
        select id,name,path,salary,age from emps.t_emp
    </select>
</mapper>

4.构建业务层,EmpService.java接口,构建Emp类型的集合方法

package com.huang.service;
import com.huang.entity.Emp;
import java.util.List;

public interface EmpService {
    
    List<Emp> findAll();
}

5.开发EmpServiceImpl.java去实现EmpService(实现接口中没有实现的方法)

package com.huang.service;
import com.huang.dao.EmpDAO;
import com.huang.entity.Emp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

@Service
@Transactional
public class EmpServiceImpl implements EmpService {
    
    @Autowired
    private EmpDAO empDAO;

    @Override
    @Transactional(propagation = Propagation.SUPPORTS)  //支持事务
    public List<Emp> findAll() {
        return empDAO.findAll();
    }
}

6.开发EmpController.java

package com.huang.controller;
import com.huang.entity.Emp;
import com.huang.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
@RequestMapping("emp")
@CrossOrigin //允许跨域
public class EmpController {
    
    @Autowired //注入对应的业务对象
    private EmpService empService;
    
    //获取员工列表的方法
    @GetMapping("findAll")
    private List<Emp> findAll(){
        return empService.findAll(); //获取所有员工的数据
    }
}

7.通过EmpController.java已经可以拿到数据库中的数据,再去前端修改emplist.html

- 1.在data{}中添加一个emps:[]的数组,去接收后端从数据库中得到的结果
data:{ //vue的数据
   
    emps:[],
},
- 2.在生命周期函数created(){}中,去查询所有信息
created(){  //生命周期函数
            

            //查询所有员工
            var _this = this;
            axios.get("http://localhost:8989/ems_vue/emp/findAll").then(res =>{
                _this.emps = res.data;
            })

        }
- 3.对拿到的数据,到页面中去遍历 ***v-for="(emp,index) in emps"***
<table border="1">
    <tr>
        <td width="70px">序号</td>
        <td width="70px">名字</td>
        <td width="70px">照片</td>
        <td width="70px">工资</td>
        <td width="70px">年龄</td>
        <td width="150px">操作</td>
    </tr>
    <tr v-for="(emp,index) in emps" :key="emp.id">
        <td v-text="emp.id"></td>
        <td v-text="emp.name"></td>
        <td>
            <img :src="emp.path" style="height: 60px ;width: 60px">
        </td>
        <td v-text="emp.salary"></td>
        <td v-text="emp.age"></td>
        <td><a href="#">删除员工</a>&nbsp;&nbsp;<a href="#">修改</a> </td>
    </tr>
</table>

##功能七、员工的添加(设计到文件的上传----头像的展示)

1.编写添加页面addEmp.html

- 1.在data{}中添加一个自定义的员工信息对象
 data: {
        emp:{}//定义一个员工信息的对象
    },
- 2.添加绑定事件v-model="emp.xxx"
 <input type="text" v-model="emp.name"/>
- 3.添加‘提交’按钮的单击事件saveEmp
<input type="button" @click="saveEmp" value="提交">
- 4.头像的要另外写
<input type="file" ref="myPhoto"/>
- 5.在methods{}中添加saveEmp()方法
 methods: {
    //保存员工信息
    saveEmp(){
        console.log(this.emp);//获取员工的信息
        //拿到对应头像的myPhoto文件信息,其中.files[0]是为了拿到myPhoto文件中具体的第1个文件信息
        console.log(this.$refs.myPhoto.files[0]); //获取文件信息
        //文件上传时,请求方式必须是post 其中enctype属性必须为multipart/form-data
        //构建员工formData对象,模拟一个表单
        var formData = new FormData();
        formData.append("name",this.emp.name);
        formData.append("salary",this.emp.salary);
        formData.append("age",this.emp.age);
        formData.append("photo",this.$refs.myPhoto.files[0]);
        var _this = this;
        //通过axios的构造,再去配置,如何配置,见如下
        axios({ 
            method: "post",  //这个method不能加s,否则
            // 会报这个错误 Resolved [org.springframework.web.HttpRequestMethodNotSupportedException:Request method 'GET' not supported]
            url: "http://localhost:8989/ems_vue/emp/save", //后端接口
            data: formData, //把表单数据放进来就行
            headers: {
                'content-type': 'multipart/form-data'
            }
        }).then(res =>{  //通过then的方式拿到结果信息
            console.log(res.data);
            if (res.data.state){
                if (window.confirm(res.data.msg+",点击确定就回到主页了")){
                    //如果点击了‘确定’就跳转到 改/ems_vue/emplist.html 页面
                    location.href = "/ems_vue/emplist.html";
                } else {
                    //否则就保存到当前页面
                    _this.emp = {}; //保存到当前页面时,清除刚才填入的数据信息
                }
            } else {
                alert(res.data.msg)
            }
        });
    }
},

2.到EmpController.java中编写保存员工信息

//保存员工信息
@PostMapping(value = "save")
//这里的Emp emp用来接收用户信息,MultipartFile photo用来接收头像
// (这个photo要和前端的formData.append("photo",this.$refs.myPhoto.files[0]);里的photo写的要一致)
public Map<String, Object> save(Emp emp, MultipartFile photo) throws IOException {
    log.info("员工信息:[{}]",emp.toString()); //日志信息
    log.info("头像信息:[{}]",photo.getOriginalFilename());
    Map<String, Object> map = new HashMap<>();

    try {
        //头像的保存
        //这里的 UUID.randomUUID().toString() 表示原始的文件名,加上
        // 原始文件的扩展名 FilenameUtils.getExtension(photo.getOriginalFilename())
        String newFileName = UUID.randomUUID().toString()+"."+ FilenameUtils.getExtension(photo.getOriginalFilename());
        photo.transferTo(new File(realPath,newFileName)); //进行文件的上传

        //设置头像地址
        emp.setPath(newFileName);

        //保存员工信息
        empService.save(emp); //这个save方法要去EmpService.java接口中创建(见第6 步)
        map.put("state",true);
        map.put("msg","员工信息保存成功!!");
    } catch (Exception e) {
        e.printStackTrace();
        map.put("state", false);
        map.put("msg","保存失败哦。");
    }

    return map;
}

3.到配置文件application.properties中添加对照片文件的存储路径

#声明文件上传的目录(为上传头像做准备)
photo.dir=D:\\Self-taught\\MY\\emps\\emp01\\src\\main\\resources\\static\\photos

4.到EmpController.java中去注入改文件上传的路径

@Value("${photo.dir}")
private String realPath;

5.在EmpService.java接口文件中创建,所需的save方法

void save(Emp emp);

6.有了save方法后,去EmpServiceImpl.java文件中去做实现

@Override
public void save(Emp emp) {
    empDAO.save(emp); //调用EmpDAO的save方法,对emp进行保存,但是目前还没有,要求创建改save方法
}

7.到EmpDAO.java接口文件中,创建save方法,用于保存

void save(Emp emp);

8.对改save保存方法,在EmpDAO.xml文件中去实现(将员工信息保存到数据库中)

<insert id="save" parameterType="Emp" useGeneratedKeys="true" keyProperty="id">
    insert into emps.t_emp values (#{id}, #{name}, #{path}, #{salary}, #{age})
</insert>

9.到emplist.html中实现头像的加载

<!-- 这里的 '/ems_vue/' 实现头像的加载 -->
<img :src="'/ems_vue/'+emp.path" style="height: 60px ;width: 60px">

10.到application.properties中放行资源的访问(图片资源)

#这里的photo.dir 是之前声明的路径
spring.resources.static-locations=classpath:/static/,file:${photo.dir}

##功能八、员工删除

1.到EmpDAO.java接口中,写一个delete的删除

void delete(String id);

2.到mapper中做实现,即SQL语句,在EmpDAOMapper.xml

<delete id="delete" parameterType="String">
    delete from emps.t_emp where id = #{id}
</delete>

3.写完dao后,回到业务处理,到EmpService.java接口中写一个删除的方法

void delete(String id)

4.在EmpServiceImpl.java对delete方法的实现

@Override
public void delete(String id) {
    empDAO.delete(id);
}

5.到EmpController.java中写删除员工信息的方法

//删除员工
@GetMapping("delete")
public Map<String,Object> delete(String id ){
    log.info("删除员工的id是【{}】",id); //打印日志
    Map<String, Object> map = new HashMap<>();

    try {
        //删除员工的头像
        Emp photo = empService.findPhoto(id);
        File file = new File(realPath, photo.getPath());
        if (file.exists()){
            //删除头像文件
            file.delete();
        }

        //删除员工信息
        empService.delete(id);
        map.put("state",true);
        map.put("msg","删除成功喽^-^");
    } catch (Exception e) {
        e.printStackTrace();
        map.put("state",false);
        map.put("msg","没有删除哦!");
    }

    return map;
}

6.编写前端删除操作,在emplist.html中

- 1.添加一个单击事件delEmp(emp.id),并获取要删除的那个id
<a href="#" @click="delEmp(emp.id)">删除员工</a>
- 2.在methods中编写delEmp(id){}方法
methods:{  //自定义函数
    //删除员工的操作
    delEmp(id){
        if (window.confirm("确定要删除该员工的信息吗??")){
            var _this = this;
            axios.get("http://localhost:8989/ems_vue/emp/delete?id="+id).then(res =>{
                if (res.data.state){
                    alert(res.data.msg+"点击确定,刷新数据");
                    _this.findAll(); //重新加载数据
                }else {
                    alert(res.data.msg);
                }
            });
        }
    },
    //查询员工列表方法(对该方法进行封装,实现复用)
    findAll(){
        var _this = this;
        axios.get("http://localhost:8989/ems_vue/emp/findAll").then(res =>{
            _this.emps = res.data;
        })
    }
},

7.删除时,要把用户的头像也删除了,步骤见8-13

8.在EmpDAO.java中编写查找改id对应的图片

Emp findPhoto(String id);

9.在mapper文件(EmpDAOMapper.xml)中,实现该方法

<select id="findPhoto" parameterType="String" resultType="Emp">
    select id,name,path,salary,age from emps.t_emp
    where id = #{id}
</select>

10.去业务层,添加数据接口(EmpService.java接口)

Emp findPhoto(String id);

11.到EmpServiceImpl.java中,对业务接口的方法进行实现

@Override
public Emp findPhoto(String id) {
    return empDAO.findPhoto(id);
}

12.在EmpServiceImpl.java中查询到了员工的信息后,可以到EmpController.java中实现删除头像的操作

//删除员工的头像
Emp photo = empService.findPhoto(id);  //查询对应的用户信息
File file = new File(realPath, photo.getPath()); //构建一个file,来获取文件
if (file.exists()){ //如果文件存在
    //删除头像文件
    file.delete();
}

##功能九、修改员工信息

1.先在emplist.html中穿一个id

<a :href="'/ems_vue/updateEmp.html?id='+emp.id">修改</a>

2.到updateEmp.html中截取获取到的页面

var app = new Vue({
    el: "#wrap",
    data:{
        emp:{} //用户展示数据库回响用的对象
    },
    methods:{
        //处理员工的修改信息
        editEmp(){
            console.log(this.emp); //拿到员工信息
            console.log(this.$refs.photo.files[0]); //拿到头像信息<input ref="photo" type="file"/>,通过这个photo

            var formData = new FormData();
            formData.append("id",this.emp.id);
            formData.append("name",this.emp.name);
            formData.append("path",this.emp.path); //将原始的文件路径this.emp.path传给"path",否则文件(图片)会丢失
            formData.append("salary",this.emp.salary);
            formData.append("age",this.emp.age);
            formData.append("photo",this.$refs.photo.files[0]);
            var _this = this;
            axios({ //通过axios的构造,再去配置,如何配置,见如下
                method: "post",
                url: "http://localhost:8989/ems_vue/emp/update",
                data: formData,
                headers: {
                    'content-type': 'multipart/form-data'
                }
            }).then(res =>{
                console.log(res.data);
                if (res.data.state){
                    if (window.confirm(res.data.msg+",点击确定就回到主页了")){
                        location.href = "/ems_vue/emplist.html";
                    } 
                } else {
                    alert(res.data.msg)
                }
            });
        }
    },

    created(){
        //获取对应的id信息
        var start = location.href.lastIndexOf("="); //从路径的 = 等号 开始截取信息(截取的起始值)
        var id = location.href.substring(start+1); //从start+1的位置开始截取
        console.log(id);
        //查询一个人的信息
        var _this = this;
        //通过获取id查询一个员工的方法(在EmpController.java中的/emp/findOne)来获取对应id的员工信息,见第3步
        axios.get("http://localhost:8989/ems_vue/emp/findOne?id="+id).then(res=>{
            console.log(res.data);
            _this.emp = res.data; //展示数据库回响对象
        });
    }

})

3.在EmpController.java中,通过获取id查询一个员工信息的方法

//根据id查询一个员工的信息
@GetMapping("findOne")
public Emp findOne(String id){
    log.info("查询一个员工信息的id是【{}】",id);
    return empService.findPhoto(id); //之前删除用户头像时写的方法(是用来查询对应id的员工个人信息用的)
}

4.对在updateEmp.html中的created(){}方法中,获取到了***_this.emp = res.data;***的展示数据库的回响对象,进行双向绑定v-text=“emp.xxx”

<!--用户的id-->
<td valign="middle" v-text="emp.id" align="left">
<!--用户的name,salary,age都是同理可得-->
<input type="text" v-model="emp.name"/>
<!--用户的头像展示-->
<img :src="'/ems_vue/'+emp.path" style="height: 60px; width: 60px"/>
    &nbsp;&nbsp;
<input ref="photo" type="file"/>

5.给提交表单添加员一个单击事件editEmp,在methods:{}中实现,见步骤2

<input type="button" @click="editEmp" value="提交">

6.到EmpController.java中写修改员工信息的实现方法

 //修改用户信息
@PostMapping(value = "update")
public Map<String, Object> update(Emp emp, MultipartFile photo) throws IOException {
    log.info("员工信息:[{}]",emp.toString());

    Map<String, Object> map = new HashMap<>();
    try {
        if (photo != null && photo.getSize() != 0){ //这个photo是一个MultipartFile 对象,是一直不为0的,所以要做这样的判断
            log.info("头像信息:[{}]",photo.getOriginalFilename());
            //头像的保存
            String newFileName = UUID.randomUUID().toString()+"."+ FilenameUtils.getExtension(photo.getOriginalFilename());
            photo.transferTo(new File(realPath,newFileName));

            //设置头像地址
            emp.setPath(newFileName);
        }

        //保存员工信息
        empService.update(emp); //目前还没有update方法,要求EmpService中写一个update方法,见步骤7
        map.put("state",true);
        map.put("msg","员工信息更新成功!!");
    } catch (Exception e) {
        e.printStackTrace();
        map.put("state", false);
        map.put("msg","保存更新哦。");
    }

    return map;
}

7.在EmpService.java接口中创建一个update

void update(Emp emp);

8.在对应的业务中(EmpServiceImpl.java),执行update

@Override
public void update(Emp emp) {
    empDAO.update(emp); //目前该EmpDAO中,还没有这个update方法,要去创建
}

9.在EmpDAO.java接口中创建update方法

void update(Emp emp);

10.到EmpDAOMapper.xml中去实现这个update方法

<update id="update" parameterType="Emp">
    update emps.t_emp
    set
    name = #{name},
    path = #{path},
    salary = #{salary},
    age = #{age}
    where
    id = #{id}
</update>
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值