一、属性的拷贝以及密码的加密
使用org.springframework.beans中的BeanUtils.copyProperties()方法时,二者的属性名必须要一致。
/**
* 新增员工
* @param employeeDTO
*/
@Override
public void save(EmployeeDTO employeeDTO) {
Employee employee = new Employee();
// 对象的属性拷贝,从employeeDTO拷贝到employee
BeanUtils.copyProperties(employeeDTO, employee);
// 设置账号的状态,默认正常状态。1表示正常,0表示异常
employee.setStatus(StatusConstant.ENABLE);
// 设置初始密码,默认123456。使用md5算法进行加密(org.springframework.util)
employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));
// 设置创建时间和修改时间,当前系统时间
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
// 设置当前记录创建人的id和修改人的id
// TODO
employee.setCreateUser(10L);
employee.setUpdateUser(10L);
// 使用持久层更新数据库的数据
employeeMapper.insert(employee);
}
二、写SQL语句时自动提示功能
1. 选中SQL语句,右键选择“show Context Actions”,然后点击“Uninject language or reference”,然后选择“MySQL”。
2. 使用IDEA连接数据库,选择MySQL,然后填写相关信息。最后,刷新一下。
三、安装插件MyBatisX
效果:方便快速定位(点那个小鸟可以快速切换到SQL语句)
四、ThreadLocal
ThreadLocal并不是一个Thread,而是Thread的局部变量。ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。
ThreadLocal的常用方法:
方法名称 | 作用 |
public void set(T value) | 设置当前线程的线程局部变量的值 |
public T get() | 返回当前线程所对应的线程局部变量的值 |
public void remove() | 移除当前线程局部变量 |
public class BaseContext {
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();
}
}
五、PageHelper分页插件
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper}</version>
</dependency>
/**
* 员工的分页查询
* @param employeePageQueryDTO
* @return
*/
@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();
// 封装到pageResult
return new PageResult(total, records);
}
六、对日期进行格式化
方式一:在属性上加入注解,对日期进行格式化
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
对日期进行格式化与不进行格式化的对比:
方式二:在WebMvcConfiguration中扩展Spring MVC的消息转换器,统一对日期类型进行格式化处理
package com.sky.json;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
/**
* 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
*/
public class JacksonObjectMapper extends ObjectMapper {
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
//public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
public JacksonObjectMapper() {
super();
//收到未知属性时不报异常
this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
//反序列化时,属性不存在的兼容处理
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
SimpleModule simpleModule = new SimpleModule()
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
//注册功能模块 例如,可以添加自定义序列化器和反序列化器
this.registerModule(simpleModule);
}
}
package com.sky.config;
import com.sky.json.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.util.List;
/**
* 配置类,注册web层相关组件
*/
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
/**
* 扩展spring MVC框架的消息转换器
* @param converters
* @Override
*/
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
log.info("扩展消息转换器······");
// 创建一个消息转换器对象
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
// 需要为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据
converter.setObjectMapper(new JacksonObjectMapper());
// 将自己的消息转换器加入容器中,排在第一位,优先使用
converters.add(0, converter);
}
}
效果:
七、@PathVariable注解、@RequestParam注解、@RequestBody注解、@ResponseBody注解
1. @PathVariable注解
定义:通过@PathVariable可以将URL中占位符参数绑定到控制器(Controller)处理方法的形参中:URL中的{xxx}占位符可以通过@PathVariable("xxx")绑定到操作方法的形参中。
用法:通常用于RESTful API中,例如@PostMapping("/status/{status}")中的{status}就是一个路径变量,可以使用@PathVariable注解将其注入到方法参数中。
/**
* 启动禁用员工信号
* @param status
* @param id
* @return
*/
@PostMapping("/status/{status}")
@ApiOperation("启用禁用员工账号")
public Result startOrStop(@PathVariable Integer status, Long id) {
log.info("启用禁用员工账号:{}, {}", status, id);
employeeService.startOrStop(status, id);
return Result.success();
}
2. @RequestParam注解
定义:用于从HTTP请求中获取请求参数的值,并将其绑定到方法参数上。
用法:可以指定参数名和是否必须的属性,如@RequestParam("name") String name 表示获取名为"name"的请求参数,并将其赋值给name变量。
注意,如果参数前写了@RequestParam(xxx),那么前端必须要有对应的xxx名字(不管其是否有值,当然也可以通过设置该注解的required属性来调节是否必须传),如果没有xxx名的话,请求会出错,报400。
@RequestMapping(value="/user")
public String getUserBlog(@RequestParam(value="name") String username) {
return name;
}
3. @RequestBody注解
定义:用于将HTTP请求体中的数据绑定到方法参数上,通常用于接收JSON或XML格式的数据。
用法:在方法参数上添加@RequestBody注解,Spring会自动将请求体中的数据转换为对应的Java注解。
@RestController
@RequestMapping("api/users")
public class UserController {
@PostMapping("/create")
public ResponseEntity<User> createUser(@RequestBody UserRequest userRequest) {
// 创建用户
User user = userService.createUser(userRequest);
return ResponseEntity.ok(user);
}
}
4. @ResponseBody注解
定义:用于将方法的返回值直接作为HTTP响应体返回给客户端,通常用于返回JSON或XML格式的数据。
用法:在方法上添加@ResponseBody注解,Spring将方法的返回值序列化为JSON或XML格式,并作为HTTP响应返回给客户端。
@RestController
@RequestMapping("/api/users")
public class UserController {
GetMapping("/all")
@ResponseBody
public List<User> getAllUsers() {
// 获取所有用户信息
List<User> users = userService.getAllUsers();
return users;
}
}
总的来说,@PathVariable用于获取路径变量,@RequestParam用于获取请求参数,@RequestBody用于接收请求体数据,@ResponseBody用于返回响应体数据。
八、构造实体对象的两种方式
/**
* 启动禁用员工信号
* @param status
* @param id
* @return
*/
@Override
public void startOrStop(Integer status, Long id) {
// 构造实体对象
// 第一种方式
// Employee employee = new Employee();
// employee.setStatus(status);
// employee.setId(id);
// 第二种方式
Employee employee = Employee.builder()
.status(status)
.id(id)
.build();
employeeMapper.update(employee);
}