项目结构
用到的pom.xml配置
(1)springdata-jpa 操作数据库:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
(2)springmvc
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
(3) 参数效验
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
(4) 单元测试
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
yaml配置
spring:
application:
name: springboot_xushu
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/t2?useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
jpa:
hibernate:
ddl-auto: update #自动更新数据库表的结构
properties:
hibernate:
format_sql: true # 格式化sql(不格式化会导致在控制台一行打印)
show-sql: true # 显示sql语句
server:
port: 8088
补充解释:这是mysql驱动配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/t2?useUnicode=true&characterEncoding=utf-8 这里数据库名用t2,问号后面是可以防止乱码问题
username: root
password: 123456
springdata-jpa动态操作数据库表
1.导入依赖
<!--springdata-jpa 操作数据库-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
2.创建一个数据库:省略
3.通过javabin结构创建数据库表
package com.huanyu.springboot_xushu.poji;
import jakarta.persistence.*;
/**
* 这些注释都是通过映射用Java建mysql数据库表
*/
@Table(name="tb_user")//表名
@Entity
public class User {
@Id //主键ID
@GeneratedValue(strategy = GenerationType.IDENTITY) //自增长
@Column(name = "user_id")//字段名
private Integer userId;
@Column(name = "user_name")
private String userName;
@Column(name = "password")
private String password;
@Column(name = "email")
private String email;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String username) {
this.userName = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", username='" + userName + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
'}';
}
}
3.yaml配置
spring:
jpa:
hibernate:
ddl-auto: update #启用动态数据库
properties:
hibernate:
format_sql: true #格式化,方便程序员查看问题
show-sql: true #在控制面板打印sql语句
用户传过来的数据类型一般单独创建一个类,叫数据传输类
package com.huanyu.springboot_xushu.poji.dto;
import jakarta.persistence.Column;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import org.hibernate.validator.constraints.Length;
public class UserDto {
private Integer userId;
//@NotEmpty 不能为双引号 (这些注解是在pom.xml里面导入了参数效验功能的配置)
@NotBlank(message = "用户名不能为空") //去除空壳
private String userName;
@NotBlank(message = "用户名不能为空") //去除空壳
@Length(min = 6, max = 12) //指定密码长度,最小值6,最大值12
private String password;
@Email(message = "邮箱格式不正确")
private String email;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
@Override
public String toString() {
return "UserDto{" +
", userName='" + userName + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
'}';
}
}
请求成功返回的参数
package com.huanyu.springboot_xushu.poji;
import jakarta.servlet.http.HttpServlet;
import org.springframework.http.HttpStatus;
public class ResponseMessage<T> {
private Integer code;
private String message;
private T data;
public ResponseMessage(Integer code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
//接口请求成功
public static <T> ResponseMessage<T> success(T data){
/**
* 参数一:请求成功参数:200
* 参数二:请求成功打印
* 参数三:响应的数据
*/
return new ResponseMessage<>(HttpStatus.OK.value(), "success!",data);
}
//接口请求成功
public static <T> ResponseMessage<T> success(){
/**
* 参数一:请求成功参数:200
* 参数二:请求成功打印
* 参数三:响应的数据
*/
return new ResponseMessage<>(HttpStatus.OK.value(), "success!",null);
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
一般在业务逻辑类service里面会建一个接口,面向接口进行编程对于以后的扩展性,维护下更强
public interface IUserService {
/**
* 插入用户
*
* @param user
* @return
*/
User add(UserDto user);
/**
* 查询用户
* @param userId 用户Id
* @return
*/
User getUser(Integer userId);
/**
* 修改用户
* @param user 需要修改的用户对象
* @return
*/
User edit(UserDto user);
/**
* 删除用户
*
* @param userId 用户Id
*/
void delete(Integer userId);
}
数据访问类
package com.huanyu.springboot_xushu.repository;
import com.huanyu.springboot_xushu.poji.User;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
/**
* CrudRepository<User, Integer>
* 第一个参数是操作什么类,这里我们在操作User类,所以是User
* 第二个参数是主键id是什么数据类型
*/
@Repository //这个同样是把当前这个类注册为spring的bean
// 之所以跟UserService中的这个@Service 注解不一样是区分业务分类,让逻辑更清晰
public interface UserRepository extends CrudRepository<User, Integer> {
}
业务逻辑类
package com.huanyu.springboot_xushu.service;
import com.huanyu.springboot_xushu.poji.User;
import com.huanyu.springboot_xushu.poji.dto.UserDto;
import com.huanyu.springboot_xushu.repository.UserRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service //spring的bean //标记成spring的bean后,我们就可以在Controller那里给他自动装配进去
public class UserService implements IUserService{
@Autowired
UserRepository userRepository;
@Override
public User add(UserDto user){
User userPojo = new User();
BeanUtils.copyProperties(user, userPojo);//参数一:你要拷贝那一个对象 参数二:你要拷贝到那一个对象里面去
/**
* save()方法
* 增加可以调,修改也可以
* 他会自动判别如果他有id修改,没有就是删除
*/
return userRepository.save(userPojo);
// 调用数据访问类
}
/**
* 查询用户
*
* @param userId 用户Id
* @return
*/
@Override
public User getUser(Integer userId) {
/**
* userRepository.findById():返回的类型是Optional,
* Optional是专门用来处理空指针的(因为可能根据id查不出来)
* orElseThrow() 如果是空指针那就抛出异常
*/
return userRepository.findById(userId).orElseThrow(() -> {
throw new IllegalArgumentException("用户不存在,参数异常"); //朗姆达表达式
});
}
/**
* 修改用户
*
* @param user
* @return
*/
@Override
public User edit(UserDto user) {
User userPojo = new User();
BeanUtils.copyProperties(user, userPojo);
return userRepository.save(userPojo);//插入和修改都调用save方法
}
/**
* 删除用户
*
* @param userId 用户Id
*/
@Override
public void delete(Integer userId) {
userRepository.deleteById(userId);
}
}
控制器类
服务器访问指定路径容器后调用指定方,再从容器方法调用逻辑包中的方法
package com.huanyu.springboot_xushu.controller;
import com.huanyu.springboot_xushu.poji.ResponseMessage;
import com.huanyu.springboot_xushu.poji.User;
import com.huanyu.springboot_xushu.poji.dto.UserDto;
import com.huanyu.springboot_xushu.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@RestController //接口方法返回对象 转化成json文本
@RequestMapping("/user") //URL: localhost:8088/user
public class UserController {
@Autowired //Spring 容器会自动查找匹配的 bean,并将其注入到该成员变量、方法参数或构造函数中。
IUserService userService;
// REST
// 增加
@PostMapping
/**
* @Validated 参数效验
* @RequestBody 自动把传进来的json文本转换成对象
*/
public ResponseMessage<User> add(@Validated @RequestBody UserDto user){ //这里可以用User对象当参数,但一般自定义一个用户传输类
User userNew = userService.add(user);
//return "success!";
//这里可以直接调用ResponseMessage里面的方法,把返回出来的新user响应到客户端
return ResponseMessage.success(userNew);
}
// 查询
@GetMapping("/{userId}")
public ResponseMessage<User> query(@PathVariable Integer userId){
User userNew = userService.getUser(userId);
return ResponseMessage.success(userNew);
}
// 修改
@PutMapping
public ResponseMessage<User> edit(@Validated @RequestBody UserDto user){ //这里可以用User对象当参数,但一般自定义一个用户传输类
User userNew = userService.edit(user);
return ResponseMessage.success(userNew);
}
// 删除
@DeleteMapping("/{userId}")
public ResponseMessage<User> delete(@PathVariable Integer userId){
userService.delete(userId);
return ResponseMessage.success();
}
}
@GetMapping("{id}"):意思就是在原@RequestMapping("/hello")路径下,下一个路径时调用对应地址的方法;
@PathVariable:意思就是获取地址里面的值
统一异常处理通知
package com.huanyu.springboot_xushu.exception;
import com.huanyu.springboot_xushu.poji.ResponseMessage;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice //统一处理
public class GlobalExceptionHandlerAdvice {
Logger log= LoggerFactory.getLogger(GlobalExceptionHandlerAdvice.class);
@ExceptionHandler({Exception.class}) //因为所有异常父类都是Exception,所以这里用Exception为所有异常做统一处理
public ResponseMessage handlerException(Exception e, HttpServletRequest request, HttpServletResponse response){
//日志记录
log.error("统一异常:",e);
return new ResponseMessage(500,"error",null);
}
}
启动类
package com.huanyu.springboot_xushu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootXushuApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootXushuApplication.class, args);
}
}
标签:return,springboot,项目,userId,User,简单,import,public,String
From: https://www.cnblogs.com/zhshy/p/18516373