工程搭建
创建SpringBoot工程,并引入Web开发起步依赖,mybasits,mysql驱动,lombok
developer tools: lombok
Web:Spring Web
SQL:Mybatis Framework,MySQL Driver
创建之后保留这三个文件就可以了
把resources中的文件都删掉,新建application.yml文件,在此文件中连接数据库
yml配置文件形式
关于数据库
在不同主机名(如localhost)下都是一个个电脑,而数据库就是在这电脑里,通过idea连接的就是此数据库(因为之前不明白数据库是怎么工作的),只要属性都对上就可以正常工作
创建数据库表,并在application.yml中配置数据库的基本信息
可以像这么写
1 2 3 4 5 datasource: driver-class-name: ${sky.datasource.driver-class-name} url: jdbc:mysql: username: ${sky.datasource.username} password: ${sky.datasource.password}
其中mapper的xml配置可以像这么配置
寻找在recources的mapper目录下的所有xml
1 2 3 4 5 mybatis: mapper-locations: classpath:mapper
准备基础代码结构,并引入实体类及统一的相应结果分装类Result
DTO接收数据
1 2 3 4 5 6 7 8 9 10 11 12 @PostMapping("/login") public Result login (@RequestBody EmployeeLoginDTO dto) { }
通过``@RequestBody`把前端返回的数据变为java语言
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @PostMapping("/login") public Result<EmployeeVO> login (@RequestBody EmployeeLoginDTO dto) { Employee entity = employeeService.login(dto); EmployeeVO vo = new EmployeeVO (); vo.setId(entity.getId()); vo.setName(entity.getName()); Result<EmployeeVO> result = Result.success(vo); return result; }
通过return Result.success(employeeLoginVO);把VO装进result返回
新增员工
员工的DTO按前端的来设置
如:
1 2 3 4 5 6 7 8 9 10 11 private Long id;private String username;private String name;private String phone;private String sex;private String idNumber;
controller
1 2 3 4 5 6 7 8 9 10 @PostMapping @ApiOperation("新增员工") public Result save (@RequestBody EmployeeDTO employeeDTO) { log.info("新增员工:{}" ,employeeDTO); employeeService.save(employeeDTO); return Result.success(); }
获取dto,用@RequestBody变为java语言,在用sava方法传给Service
service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Override public void save (EmployeeDTO employeeDTO) { Employee employee = new Employee (); BeanUtils.copyProperties(employeeDTO,employee); employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes())); employee.setCreateTime(LocalDateTime.now()); employee.setUpdateTime(LocalDateTime.now()); employee.setCreateUser(10L ); employee.setUpdateUser(10L ); employeeMapper.insert(employee); }
一键拷贝只能拷dto和employee共有的,其余的要手动打
再用insert方法传给mapper
mapper
1 2 3 4 5 6 @Insert("insert into employee (name, username, password, phone, sex, id_number, create_time, update_time, create_user, update_user) VALUE " + "(#{name},#{username},#{password},#{phone},#{sex},#{idNumber},#{createTime},#{updateTime},#{createUser},#{updateUser})") void insert (Employee employee)
用驼峰来传递
代码完善 目前有两个问题:
录入的用户名已存在,抛出异常后没有处理
新增员工时,创建人id和修改人id设置为固定值
问题一
在handler全局异常处理器中
原语句:java.sql.SQLIntegrityConstraintViolationException: Duplicate entry ‘慈超栋’ for key ‘employee.idx_username’
1 2 3 4 5 6 7 8 9 10 11 12 13 @ExceptionHandler public Result exceptionHandler (SQLIntegrityConstraintViolationException ex) { String message = ex.getMessage(); if (message.contains("Duplicate entry" )){ String[] split = message.split(" " ); String username = split[2 ]; String msg = username + "已存在" ; return Result.error(msg); } else { return Result.error("未知错误" ); } }
问题二
客户端发送的每一个请求都是一个单独的线程,因此可以用ThreadLocal在这个线程内,通过拦截器获取id并把id设置到线程中来获取
1 2 3 4 5 6 7 8 9 10 11 12 13 public static ThreadLocal<Long> threadLocal = new ThreadLocal <>();public static void setCurrentId (Long id) { threadLocal.set(id); } public static Long getCurrentId () { return threadLocal.get(); } public static void removeCurrentId () { threadLocal.remove(); }
分页查询 先分析一下
Result中的data里面有total和records,records里有员工的信息,因此可以把data单独封装,以便方便
1 2 3 4 5 6 7 8 9 10 @Data @AllArgsConstructor @NoArgsConstructor public class PageResult implements Serializable { private long total; private List records; }
controller
1 2 3 4 5 6 @GetMapping("/page") public Result<PageResult> pageQuery (EmployeePageQueryDTO employeePageQueryDTO) { log.info("分页查询:{}" ,employeePageQueryDTO); PageResult pageResult = employeeService.pageQuery(employeePageQueryDTO); return Result.success(pageResult); }
因为是分页查询,所以返回的Result的泛型就要为PageResult(看图,相当于Result包含PageResult)
最后返回PageResult
service
1 2 3 4 5 6 7 8 9 10 11 @Override public PageResult pageQuery (EmployeePageQueryDTO employeePageQueryDTO) { PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize()); Page<Employee> page = employeeMapper.pageQuery(employeePageQueryDTO); long total = page.getTotal(); List<Employee> records = page.getResult(); return new PageResult (total,records); }
通过PageHelper插件计算页码
最后返回PageResult
mapper
1 2 3 4 5 6 7 8 9 <select id="pageQuery" resultType="com.sky.entity.Employee" > select * from employee <where> <if test="name != null and name !=''" > and name like concat ('%' ,#{name},'%' ) </if > </where> order by create_time desc </select>
其中like是模糊查询,concat(‘%’,#{name},’%’)是拼接字符串,会查询任何包含name的字符串
但是操作时间有问题,需要改一下
在config中改
1 2 3 4 5 6 7 8 9 10 @Override protected void extendMessageConverters (List<HttpMessageConverter<?>> converters) { log.info("扩展消息转换器" ); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter (); converter.setObjectMapper(new JacksonObjectMapper ()); converters.add(0 ,converter); }
JacksonObjectMapper()到时候找ai生成就行了,比较固定(懒
禁用&启用员工账号 原理就是通过更新
controller
1 2 3 4 5 6 @PostMapping("/status/{status") public Result startOrStop (@PathVariable Integer status, Long id) { log.info("启用禁用员工,{},{}" ,status,id); employeeService.startOrStop(status,id); return Result.success(); }
路径参数就加上@PathVariable
service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Override public void startOrStop (Integer status, Long id) { Employee employee = Employee.builder() .status(status) .id(id) .build(); employeeMapper.update(employee); }
mapper
1 2 3 4 5 6 7 8 9 10 11 12 13 <update id="update" > update employee <set> <if test="username != null" >username = #{username},</if > <if test="name != null" >name = #{name},</if > <if test="phone != null" >phone = #{phone},</if > <if test="sex != null" >sex = #{sex},</if > <if test="idNumber != null" >id_number = #{idNumber},</if > <if test="status != null" >status = #{status},</if > <if test="updateTime != null" >update_time = #{updateTime},</if > </set> where id = #{id} </update>
编辑员工 两个接口
查询员工 controller
1 2 3 4 5 6 @GetMapping("/{id}") public Result<Employee> getById (@PathVariable Long id) { log.info("根据id查询员工,{}" ,id); Employee employee = employeeService.getById(id); return Result.success(employee); }
service
1 2 3 4 5 6 @Override public Employee getById (Long id) { Employee employee = employeeMapper.getById(id); employee.setPassword("****" ); return employee; }
把密码隐藏掉
mapper
1 2 @Select("select * from employee where id = #{id}") Employee getById (Long id) ;
11.15
分类管理模块的功能已写好,就是按类型分类有问题,其他的跟员工部分没什么区别