要求:1.数据库需创建 users 表,包含 id、username、email、password 字段
2.实现用户的增删改查功能
3.添加用户登录认证功能
4.实现密码加密存储
5.编写controller接口,验证用户管理功能
实现后端功能即可,用apifox进行接口检验
数据库准备
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
pom依赖准备
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
<version>5.6.8</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8080</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
创建框架
配置类编写
有SpringConfig\MybatisConfig\JdbcConfig\SpringMvcConfig\ServletConfig
@Configuration
@ComponentScan({"com.ywh.service"})
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
public class SpringConfig {
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
} //密码加密用的
}
public class MybatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setTypeAliasesPackage("com.ywh.pojo");//别名包
Configuration configuration = new Configuration();
configuration.setMapUnderscoreToCamelCase(true); //驼峰映射
factoryBean.setConfiguration(configuration);
return factoryBean;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.ywh.dao");
return msc;
}
}
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
@Configuration
@ComponentScan("com.ywh.controller")
@EnableWebMvc
public class SpringMvcConfig {
}
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
//加载Spring配置类
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
//加载SpringMVC配置类
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
//设置SpringMVC请求地址拦截规则
protected String[] getServletMappings() {
return new String[]{"/"};
}
//设置post请求中文乱码过滤器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("utf-8");
return new Filter[]{filter};
}
}
并编写jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/shixun?useUnicode=true&characterEncoding=utf8&useSSL=false
jdbc.username=root
jdbc.password=123456
pojo
@Data
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
@AllArgsConstructor
public class Users {
private Integer id;
private String username;
private String email;
private String password;
private Date createdAt;
private Date updatedAt;
}
dao
@Mapper
public interface UserDao {
// 插入用户(返回自增ID)
@Insert("INSERT INTO users(username, email, password, created_at, updated_at) " +
"VALUES(#{username}, #{email}, #{password}, NOW(), NOW())")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertUser(Users user);
// 根据ID删除用户
@Delete("DELETE FROM users WHERE id = #{id}")
int deleteById(@Param("id") Integer id);
// 更新用户信息
@Update("UPDATE users SET username=#{username}, email=#{email}, updated_at=NOW() WHERE id=#{id}")
int updateUser(Users users);
// 根据用户名查询用户(用于登录验证)
@Select("SELECT * FROM users WHERE username = #{username}")
Users selectByUsername(@Param("username") String username);
}
Service
public interface UserService {
int register(Users user);
// 删除用户
int deleteUser(Integer id);
// 更新用户信息
int updateUser(Users user);
// 用户登录验证
Users login(String username, String password);
// 根据用户名查询用户
Users getUserByUsername(String username);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Override
public int register(Users user) {
// 检查用户名是否已存在
if (userDao.selectByUsername(user.getUsername()) != null) {
throw new RuntimeException("用户名已存在");
}
// 加密密码
String encodedPassword = passwordEncoder.encode(user.getPassword());
user.setPassword(encodedPassword);
return userDao.insertUser(user);
}
@Override
public int deleteUser(Integer id) {
return userDao.deleteById(id);
}
@Override
public int updateUser(Users user) {
// 更新时不修改密码
user.setPassword(null);
return userDao.updateUser(user);
}
@Override
public Users login(String username, String password) {
if (!StringUtils.hasText(username) || !StringUtils.hasText(password)) {
throw new RuntimeException("用户名和密码不能为空");
}
Users user = userDao.selectByUsername(username);
if (user == null) {
throw new RuntimeException("用户不存在");
}
// 验证密码
if (!passwordEncoder.matches(password, user.getPassword())) {
throw new RuntimeException("密码错误");
}
return user;
}
@Override
public Users getUserByUsername(String username) {
return userDao.selectByUsername(username);
}
}
Controller
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/register")
public ResponseEntity<?> registerUser(@RequestBody Users user) {
int result = userService.register(user);
Map<String, Object> map = new HashMap<>();
map.put("user",user);
if (result > 0) {
map.put("message", "注册成功");
return ResponseEntity.ok(map);
}
map.put("message", "注册失败");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(map);
}
@PostMapping("/login")
public ResponseEntity<?> loginUser(@RequestBody Users user) {
Map<String, Object> map = new HashMap<>();
map.put("user",user);
Users user1 = userService.login(user.getUsername(), user.getPassword());
if (user1 != null) {
map.put("message", "登录成功");
return ResponseEntity.ok(map);
}
else
map.put("message", "登录失败");
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body(map);
}
@PostMapping("update")
public ResponseEntity<?> updateUser( @RequestBody Users user) {
Map<String, Object> map = new HashMap<>();
map.put("user",user);
int result = userService.updateUser(user);
if (result > 0) {
map.put("message", "用户更新成功");
return ResponseEntity.ok(map);
}
map.put("message", "用户更新失败");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(map);
}
@GetMapping("delete/{id}")
public ResponseEntity<?> deleteUser(@PathVariable Integer id) {
Map<String, Object> map = new HashMap<>();
int result = userService.deleteUser(id);
if (result > 0) {
map.put("message", "用户删除成功");
return ResponseEntity.ok(map);
}
map.put("message", "用户删除失败");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(map);
}
@GetMapping("select/{username}")
public ResponseEntity<?> getUserByUsername(@PathVariable String username) {
Map<String, Object> map = new HashMap<>();
Users user = userService.getUserByUsername(username);
if (user != null) {
map.put("user",user);
return ResponseEntity.ok(map);
}
map.put("message", "用户不存在");
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(map);
}
}
测试接口
编辑运行环境
然后使用Apifox进行接口测试
先注册用户
然后登录用户
更新普通信息,根据id来更新
根据用户名查询用户
删除用户
总结
其实这个demo的有些逻辑并不是非常合理,主要是自己动手体验一下mvc的架构,并且多熟悉一下其中的注解和配置,我争取后续的demo中业务逻辑更加的完善一些