项目工程
一、环境搭建
-
准备数据库表(dept、emp)
-
创建springboot工程,引入对应的起步依赖(web、mybatis、mysql驱动、lombok)
-
配置文件application.properties中引入maybatis的配置信息,准备对应的实体类
-
准备对应的Mapper、Service(接口、实现类)、Controller基础结构
application.properties文件配置:
spring.application.name=Spring1
#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=123456
#配置mybatis日志,指定输出到控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#开启mybatis驼峰命名自动映射开关(例:a_column --->aColumn)
mybatis.configuration.map-underscore-to-camel-case=true
el-case=true
导入结构
controller(实体类)
mapper(接口)
pojo(实体类)
service(接口)
配置xml映射文件,编写SQL语句(在resources文件夹下新建)
和Mapper接口名一样,在resources下创建包时不能用 “.” 来分层,只能用 “/”,但是显现出的效果相同
约束直接从官方文档拷贝
在Mybatis中文网进入“入门”,找到配置SQL语句的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="Mapper接口的全类名">
</mapper>
二、开发规范
Restful特点
-
url定位资源
-
HTTP动词描述操作
Rest是风格,是约定方式,约定不是规定,可以打破
描述模块的功能通常使用复数,也就是加s的格式来描述,表示此类资源,而非单个资源。如:user、emps等
前后端交互统一响应结果Result:(放在pojo包下)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result{
private Integer code; ==响应码,1代标成功,0代表失败
private String msg; ==响应信息,描述字符串
private Object data; ==返回的数据
public static Result success(){
==增删改 响应成功
return new Result(1,"success",null);
}
public static Result success(Object data){
==查询 响应成功
return new Result(1,"success",data);
}
public static Result error(String msg){
==响应失败
return new Result(0,msg,null);
}
}
三、前后端联调
-
将资料中的文件压缩包拷贝到一个没有中文不带空格的目录下解压
-
打开nginx.exe ,启动前端服务器(http://localhost:90/)
-
nginx会根据配置信息转到8080端口
-
若tomcat端口号不是8080的,去nginx的config配置中把端口号改成要使用的端口号,并重新启动nginx
四、部门管理
(一)查询部门信息
在controller层下的DeptController类下编写
@Slf4j //省略Logger对象
@RestController //交给ioc容器管理,成为bean对象
public class DeptController {
//@RequestMapping("/depts") //通过其value属性来指定请求路径,method属性来指定请求方式,下面为简化版
//有Get,Post,Put,Delete
@GetMapping("/depts")
public Result list() {
log.info("查询全部数据");//输出日志
//调用Service查询数据
List<Dept> deptList = deptService.list();
return Result.success(deptList);//传递返回的值
}
}
====以下为SLf4j的源码====
Example: @Slf4j public class LogExample {
}
will generate: public class LogExample {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class); }
在Service层的DeptService接口下创建 list() 方法,并在具体的实现类中重写 list() 方法,创建mapper对象并调用其方法、
接口
/**
* 部门管理
*/
public interface DeptService {
/*
* 查询全部部门数据*/
List<Dept> list();
}
//
实现类
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;//调用Dao层从数据库获取数据
@Override
public List<Dept> list() {
return deptMapper.list();
}
}
在Dao层实现从数据库获取数据,用注解方式进行调用
/**
* 部门管理
*/
@Mapper
public interface DeptMapper {
/*
* 查询全部部门方法
* */
@Select("select * from dept")
List<Dept> list();
}
(二)删除部门
controller层:
/**
* 删除部门
* @return
*/
// @DeleteMapping("/depts/{id}")
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id){
//使用@PathVariable注解去获取@RequestMapping中{}中传进来的值,并绑定到处理方法定一的形参上
//应用时,在@RequestMapping请求路径中,将需要传递的参数用花括号{}括起来,
//然后通过@PathVariable("参数名称")获取URL中对应的参数值。
log.info("根据id删除部门:{}",id);//一个大括号就是一个参数占位符
deptService.delete(id);
//调用Service删除部门
return Result.success();
}
service层
接口
/**
* 根据id删除部门
*
* @param id
*/
void delete(Integer id);
//
实现类
@Override
public void delete(Integer id) {
deptMapper.delete(id);
}
dao层
@Delete("delete from mybatis.dept where id = #{id}")
void delete(Integer id);
PS:postman测试时记得把请求方式换成DELETE
(三)新增部门
-
controller层
/** * 新增部门 */ @PostMapping("/depts") public Result addDept(@RequestBody Dept dept){ log.info("新增部门:{}",dept); //调用Service层新增 deptService.addDept(dept); return Result.success(); }
-
service层
接口Dept addDept(Dept dept);
实现类
@Override public Dept addDept(Dept dept) { dept.setCreateTime(LocalDateTime.now()); dept.setUpdateTime(LocalDateTime.now());//补全数据类型 return deptMapper.addDept(dept); }
-
dao层
/** * 新增部门 * @param dept * @return */ @Insert("INSERT INTO dept (name, create_time, update_time) VALUES (#{name},#{createTime},#{updateTime})") Dept addDept(Dept dept);
五、员工管理
基本数据封装对象:PageBean
package com.itheima.pojo;
import java.util.List;
public class PageBean {
private Long total;
private List rows;
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
public List getRows() {
return rows;
}
public void setRows(List rows) {
this.rows = rows;
}
}
补充:
@RequestParam,@PathVariable注解的区别:
-
@RequestParam:
从前端获取参数,其中的 defaultValue 可设置默认值 -
@PathVariable:
通过请求路径指定参数,其中 defaultValue() 设置默认值请求路径:/depts/{id}
-
@DateTimeFormat :
其中的pattern可以设置日期的格式,如@DateTimeFormat (pattern = "yyyy-MM-dd")
-
@RequestBody:
@RequsetParam 可以接受post请求,但是请求的contentType 为 form-data格式,而@RequestBody接受的请求方式application/json;charset=UTF-8
(一)分页查询员工列表
1、原始方法
controller层
@Slf4j
//@RequestMapping("/emps")
@RestController
public class EmpController {
@Autowired
private EmpService empService;
@GetMapping("/emps")
public Result empSelect(@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10")Integer pageSize){
//设置默认值
// if(page==null)page = 1;
// if(pageSize==null)pageSize=10;
log.info("员工信息分页查询第{}页{}条",page,pageSize);
PageBean bean = empService.empSelect(page,pageSize);
return Result.success(bean);
}
}
service层(在service层完成对数据的封装)
-
接口
public interface EmpService { PageBean empSelect(Integer page, Integer pageSize); }
-
实体类
public class EmpServiceImpl implements EmpService { @Autowired private EmpMapper empMapper; @Override public PageBean empSelect(Integer page, Integer pageSize) { PageBean bean = new PageBean(); bean.setRows(empMapper.empSelect(page,pageSize)); //把从Dao层获取的数据封装到整合对象PageBean里 bean.setTotal(empMapper.empTotal()); return bean; } }
dao层
@Mapper
public interface EmpMapper {
@Select("select *from emp limit #{page},#{pageSize}")
public List<Emp> empSelect(Integer page, Integer pageSize);
@Select("select count(*) from emp")
public Long empTotal();
}
2、PageHelper插件
-
配置pom.xml文件
<!--PageHelper分页插件--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.4.6</version> </dependency>
-
EmpMapper
/** * 员工信息查询 * @return */ @Select("select * from emp") public List<Emp> list();
-
EmpServicelmp
@Override public PageBean empSelect(Integer page, Integer pageSize) { //1.设置分页参数 PageHelper.startPage(page,pageSize); //2.执行查询 List<Emp> empList = empMapper.list(); Page<Emp> p =(Page<Emp>) empList;//强制转换成Page对象 //3.封装pagebean对象 PageBean bean = new PageBean(p.getTotal(),p.getResult()); return bean; }
3、条件分页查询(动态SQL)
SQL语句:
select * from emp where name like concat('%',?,'%') and gender = ? and entrydate between ? and ? order by update_time desc;
controller层
(补全参数)
public class EmpController {
@Autowired
private EmpService empService;
@GetMapping("/emps")
public Result empSelect(@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10")Integer pageSize,
String name, Short gender,
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){
log.info("员工信息分页查询第{}页{}条",page,pageSize);
PageBean bean = empService.empSelect(page,pageSize);
return Result.success(bean);
}
}
service层
(改造empSelect方法)
接口
public interface EmpService {
PageBean empSelect(Integer page, Integer pageSize,String name, Short gender, LocalDate begin, LocalDate end);
}
实现类
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
@Override
public PageBean empSelect(Integer page, Integer pageSize, String name, Short gender, LocalDate begin, LocalDate end) {
//1.设置分页参数
PageHelper.startPage(page,pageSize);
//2.执行查询
List<Emp> empList = empMapper.list(name,gender,begin ,end);
Page<Emp> p =(Page<Emp>) empList;//强制转换成Page对象
//3.封装pagebean对象
PageBean bean = new PageBean(p.getTotal(),p.getResult());
return bean;
}
}
dao层
(改造list方法)
mapper
public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
EmpMapper映射文件
<?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.itheima.mapper.EmpMapper">
<select id="list" resultType="com.itheima.pojo.Emp">
select * from emp <where>
<if test="name!=null">
name like concat('%',#{name},'%')
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
<if test="begin!=null and end!=null">
and entrydate between #{begin} and #{end}
</if>
</where>
order by update_time desc
</select>
</mapper>
(二)批量删除员工数据
contraller
@DeleteMapping("/emps/{ids}")
public Result Delete(@PathVariable ArrayList<Integer> ids){
log.info("批量删除,ids:{}",ids);
empService.Delete(ids);
return Result.success();
}
service
-
接口
void Delete(ArrayList ids);
-
实现类
@Override public void Delete(ArrayList ids) { empMapper.Delete(ids); }
dao
-
mapper
void Delete(ArrayList ids);
-
xml映射文件
<!-- 批量删除操作--> <delete id="Delete"> delete from emp where id in <foreach collection="ids" item="id" separator="," open="(" close=")"> #{id} </foreach> </delete>
(三)新增员工数据
controller
@PostMapping("/emps")
public Result save(@RequestBody Emp emp){
log.info("新增员工,{}",emp);
empService.Insert(emp);
return Result.success();
}
service
-
接口
void Insert(Emp emp);
-
实现类(补全参数)
@Override public void Insert(Emp emp) { emp.setCreateTime(LocalDateTime.now());//设置创建时间参数 emp.setUpdateTime(LocalDateTime.now());//设置修改时间参数 empMapper.Insert(emp); }
dao
@Insert("Insert Into emp (username, name, gender, image, job, entrydate, dept_id, create_time, update_time) " +
"VALUES (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})")
void Insert(Emp emp);
(四)文件上传
将本地图片、视频、音频上传到服务器供其他用户浏览或下载
1.本地存储
代码实现:
- 在服务器本地磁盘上创建images目录,用来存储上传的文件(例:E盘创建images目录)
- 使用MultipartFile类提供的API方法,把临时文件转存到本地磁盘目录下
MultipartFile 常见方法:
- String getOriginalFilename(); //获取原始文件名
- void transferTo(File dest); //将接收的文件转存到磁盘文件中
- long getSize(); //获取文件的大小,单位:字节
- byte[] getBytes(); //获取文件内容的字节数组
- InputStream getInputStream(); //获取接收到的文件内容的输入流
把前端文件复制到resources文件夹下的static中
controller
package com.itheima.controller;
import com.itheima.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;