环境信息
JAVA版本
SpringBoot版本
JDK 23.0.2
3.5.0-M2
MySQL
5.7.44
数据库配置 JPA spring: application: name: admin-auth datasource: url: jdbc:mysql://localhost:3306/admin_auth?useSSL=false username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver jpa: properties.hibernate.dialect: org.hibernate.dialect.MySQLDialect hibernate: ddl-auto: update
Security Config 关闭http认证
package com.admin.auth.config;import com.admin.auth.dao.UserRepository;import com.admin.auth.filter.JwtTokenFilter;import com.admin.auth.utils.JwtTokenProvider;import io.swagger.v3.oas.models.Components;import io.swagger.v3.oas.models.OpenAPI;import io.swagger.v3.oas.models.info.Info;import io.swagger.v3.oas.models.security.SecurityRequirement;import io.swagger.v3.oas.models.security.SecurityScheme;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.security.web.SecurityFilterChain;import static org.springframework.security.config.Customizer.withDefaults;@Configuration @EnableWebSecurity public class SecurityConfig { private final UserRepository userRepository; private final JwtTokenProvider jwtTokenProvider; public SecurityConfig (UserRepository userRepository, JwtTokenProvider jwtTokenProvider) { this .userRepository = userRepository; this .jwtTokenProvider = jwtTokenProvider; } @Bean public SecurityFilterChain securityFilterChain (HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers( "/swagger-ui.html" , "/swagger-ui/**" , "/swagger-resources/**" , "/v3/api-docs/**" , "/api/v1/auth/register" , "/api/v1/users/check" , "/api/v1/auth/login" ).permitAll() .anyRequest().authenticated() ) .csrf(csrf -> csrf.disable()); return http.build(); } @Bean public JwtTokenFilter jwtTokenFilter () { return new JwtTokenFilter (jwtTokenProvider, userRepository); } @Bean public PasswordEncoder passwordEncoder () { return new BCryptPasswordEncoder (); } }
Swagger Swagger 是一组开源工具,用于设计、构建、文档化和RESTful Web
服务。
配置swagger pom.xml添加依赖
<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui --> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.8.5</version> </dependency>
application.properties添加
springdoc.swagger-ui.path=/swagger-ui.html
访问地址:
http://localhost:8888/swagger-ui.html
如果访问404报错,重启IDE
如果springboot security
配置了PasswordEncoder Bean
访问swagger需要将spring.security.user.password的值设置为加密字符串,参考以下代码生成密码
package com.admin.auth.utils;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;public class GeneratePassword { public static void main (String[] args) { BCryptPasswordEncoder encoder = new BCryptPasswordEncoder (); String encodedPassword = encoder.encode("admin" ); System.out.println(encodedPassword); } }
用户名密码认证 SecurityConfig配置以下内容
@Bean public SecurityFilterChain securityFilterChain (HttpSecurity http) throws Exception { http .httpBasic(withDefaults()) return http.build(); } @Bean public OpenAPI customOpenAPI () { final String securitySchemeName = "basicAuth" ; return new OpenAPI () .addSecurityItem(new SecurityRequirement ().addList(securitySchemeName)) .components( new Components () .addSecuritySchemes(securitySchemeName, new SecurityScheme () .name(securitySchemeName) .type(SecurityScheme.Type.HTTP) .scheme("basic" ) ) ) .info(new Info ().title("Your API Title" ).version("1.0.0" )); }
JWT认证 package com.admin.api.config; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class OpenAPIConfig { @Bean public OpenAPI customOpenAPI() { final String jwtSchemeName = "JWT"; final String basicSchemeName = "BasicAuth"; return new OpenAPI() .info(new Info().title("Admin API").version("1.0.0")) // 同时支持两种认证方式 .addSecurityItem(new SecurityRequirement().addList(jwtSchemeName)) .addSecurityItem(new SecurityRequirement().addList(basicSchemeName)) .components(new Components() // JWT认证配置 .addSecuritySchemes(jwtSchemeName, new SecurityScheme() .name(jwtSchemeName) .type(SecurityScheme.Type.HTTP) .scheme("bearer") .bearerFormat("JWT") ) } }
编辑src/main/java/com/admin/api/config/SecurityConfig.java
将httpBasic
注释掉
@Bean public SecurityFilterChain securityFilterChain (HttpSecurity http) throws Exception { http .csrf(AbstractHttpConfigurer::disable) .sessionManagement(session -> session .sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(auth -> auth .requestMatchers( "/swagger-ui.html" , "/api/auth/login" ).permitAll() .anyRequest().authenticated() ) .addFilterBefore(jwtTokenFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); }
获取token
curl -X POST http://localhost:8888/api/auth/login -H "Content-Type: application/json" -d '{"username":"acai","password":"12345678"}'
使用token请求接口
curl -X GET http://localhost:8888/api/users -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhY2FpIiwicm9sZXMiOlsiW3JlYWQsIHdyaXRlXSJdLCJpYXQiOjE3NDI5ODE4NjEsImV4cCI6MjM0Nzc4MTg2MX0.JAehbzWJR5080ClHI-veK8QhHSO5O2YD7bJ9upj3jViLxokX1umbLJYewhgbvhwDW4KpLEhrBpONULu9rS44bg"
注解 数据模型注解 在实体类上使用,以下是注解描述:
注解
描述
示例
@ApiModel
描述数据模型,用于类级别。
@ApiModel(value = "User", description = "用户信息")
@ApiModelProperty
描述数据模型的属性,用于字段级别。
@ApiModelProperty(value = "用户ID") private Long id;
API描述注解 在控制器上使用,以下是注解描述:
注解
描述
示例
@Api
标识整个 API 文档的信息,包括 tags、description 等。
@Api(tags = "Sample Controller", description = "示例控制器")
@ApiOperation
描述一个操作,包括请求方法、路径、操作说明等。
@ApiOperation("示例接口")
请求参数注解 在控制器的public方法上使用,比如:请求API接口需要提供的参数等
注解
描述
示例
@ApiParam
描述单个请求参数,包括参数名、类型、描述等。
@ApiParam(value = "姓名", required = true) @RequestParam String name
@ApiImplicitParam
定义单个请求参数,支持更多参数设置,如示例值、参数位置等。
@ApiImplicitParam(name = "name", value = "姓名", required = true, dataType = "string", paramType = "query")
@ApiImplicitParams
定义多个请求参数。
@ApiImplicitParams({ @ApiImplicitParam(...), @ApiImplicitParam(...) })
使用方式 在pom.xml中添加依赖
<dependency > <groupId > com.spring4all</groupId > <artifactId > swagger-spring-boot-starter</artifactId > <version > 1.9.1.RELEASE</version > </dependency >
在启动类添加swagger注解
package com.acaiblog.auth;import com.spring4all.swagger.EnableSwagger2Doc;import lombok.extern.slf4j.Slf4j;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@Slf4j @SpringBootApplication @EnableSwagger2Doc public class HelloApplication { private static final Logger logger = LoggerFactory.getLogger(HelloApplication.class); public static void main (String[] args) { SpringApplication.run(HelloApplication.class, args); log.info("test" ); logger.info("test11111" ); System.out.println("http://127.0.0.1:8080/test/swagger-ui.html#" ); } }
在控制器类添加注解
package com.acaiblog.auth.controller;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import lombok.extern.slf4j.Slf4j;import org.springframework.security.core.Authentication;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.Collection;@Slf4j @Api(tags = "test", description = "测试接口") @RestController @RequestMapping("/test") public class HelloController { @ApiOperation("hello接口") @GetMapping("/hello") public String hello () { return "hello world" ; } }
浏览器访问:http://127.0.0.1:8080/swagger-ui.html#
Slf4j日志框架 Slf4j(Simple Logging Facade for Java)
是一个Java日志框架的简单外观,旨在为各种日志框架提供一个简单的统一接口。Slf4j
提供了一个通用的日志API,使得开发者可以在应用中使用不同的日志框架,而无需改变应用代码。
日志级别
日志级别
描述
TRACE
用于最详细的日志信息,通常用于调试。
DEBUG
用于详细信息,适用于开发环境的调试。
INFO
用于生产环境中的一般信息,表明应用程序正常运行。
WARN
表示潜在的问题,不会阻止应用程序的正常运行。
ERROR
表示出现了一个严重的问题,可能导致应用程序停止运行。
自定义日志 自定义日志输出格式,创建logback.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 控制台输出的Appender --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level - %msg%n</pattern> </encoder> </appender> <!-- 设置全局日志级别为INFO,并指定输出到控制台和文件 --> <root level="info"> <appender-ref ref="CONSOLE"/> </root> </configuration>
注解
注解
描述
@Slf4j
自动生成一个名为log的日志对象,用于在程序中输出日志信息。需要添加Lombok库的依赖。
@LogMethod
在方法被调用时输出日志。可以在方法级别或类级别使用。
@LogMessage
在方法执行时输出日志。可以在方法级别或类级别使用。
注解方式打印日志
在类上添加@Slf4j
注解,然后在指定位置打印日志。例如:
package com.acaiblog.auth;import lombok.extern.slf4j.Slf4j;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication @Slf4j public class HelloApplication { public static void main (String[] args) { SpringApplication.run(HelloApplication.class, args); log.info("test" ); System.out.println("http://127.0.0.1:8080/test/swagger-ui.html#" ); } }
使用logger属性打印日志
在要使用的类上创建logger私有属性,然后在指定位置打印日志。例如:
package com.acaiblog.auth;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication public class HelloApplication { private static final Logger logger = LoggerFactory.getLogger(HelloApplication.class); public static void main (String[] args) { SpringApplication.run(HelloApplication.class, args); logger.info("test11111" ); System.out.println("http://127.0.0.1:8080/test/swagger-ui.html#" ); } }
实体类 在Spring Boot
中,实体类(Entity)通常用于表示系统中的业务实体或数据模型,它映射到数据库中的表。可以理解为实体类中的属性对应数据库表中的字段
注解 Spring Boot
实体类通常使用JPA(Java Persistence API
注解进行标注,以实现与数据库表的映射。常见的注解包括:
注解
描述
@Entity
标识这个类为 JPA 实体类,表示它将与数据库表进行映射。
@Table
用于指定实体类与数据库表的映射关系,包括表名、索引等。
@Id
标识主键字段。
@GeneratedValue
用于定义主键生成策略。
@GeneratedValue
常见策略:
策略
描述
GenerationType.AUTO
主键由 JPA 提供商自动选择适当的策略,通常是表的自增长。
GenerationType.IDENTITY
主键由数据库生成,如 MySQL 中的 AUTO_INCREMENT。
GenerationType.SEQUENCE
通过序列生成主键,需要指定一个序列的名称。
GenerationType.TABLE
通过表模拟序列,需要额外生成一个表来保存生成的主键。
实体类示例代码:
@Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String password; }
Lombok Lombok 是一个 Java 库,它通过注解的方式来简化 Java 代码的编写,减少冗长的样板代码。使用 Lombok 可以提高代码的可读性、简洁性,并且减少了开发者编写重复且繁琐的代码的负担。以下是 Lombok 中一些常用注解的详解
注解
描述
@Getter
自动生成属性的 getter 方法
@Setter
自动生成属性的 setter 方法
@ToString
自动生成 toString()
方法
@EqualsAndHashCode
自动生成 equals()
和 hashCode()
方法
@NoArgsConstructor
自动生成无参构造函数
@AllArgsConstructor
自动生成包含所有字段的构造函数
@RequiredArgsConstructor
自动生成包含被 @NonNull
注解标注的字段的构造函数
@Data
自动生成 @ToString
、@EqualsAndHashCode
、@Getter
、@Setter
和 @RequiredArgsConstructor
@Builder
自动生成一个建造者模式的构造器
@Slf4j
自动生成日志对象
数据访问层 在Spring Boot
项目中,数据访问层(Data Access Layer,简称DAO)负责与数据库进行交互,执行数据的增删改查操作。Spring Boot
中常用的数据访问层技术包括Spring Data JPA
、MyBatis
等。
Spring Data JPA Spring Data JPA 是 Spring Data 项目的一部分,它提供了一种简化的数据访问方式,用于与关系型数据库进行交互。它基于 Java Persistence API(JPA) 标准,并提供了一套简洁的 API 和注解,使开发人员能够通过简单的 Java 对象来表示数据库表,并通过自动生成的 SQL 语句执行常见的 CRUD 操作。
MyBatis MyBatis和MyBatisPlus的区别
特性
MyBatis
MyBatis Plus
功能扩展
相对轻量级,基本的 SQL 映射功能
在 MyBatis 的基础上进行了扩展和封装
CRUD 操作
需要手动编写 SQL 语句
提供通用的 CRUD 操作,继承 BaseMapper 接口
分页插件
原生不提供分页功能,需要手动编写分页 SQL 语句
集成了强大的分页插件,方便使用分页功能
代码生成器
没有官方的代码生成器,第三方工具可辅助
集成了代码生成器,根据数据库表生成代码
Lambda 表达式
XML 中使用 OGNL 表达式,语法复杂
引入了 Lambda 表达式,更直观简洁的查询条件
Wrapper 查询条件
使用 XML 或注解手动拼接查询条件
提供了 QueryWrapper 和 UpdateWrapper 等包装器,方便构建查询条件
其他功能
基本的 ORM 支持,需要手动配置和编写 SQL 语句
提供更多便捷功能,如条件构造器、自动填充、逻辑删除等
MyBatisPlus MyBatis Plus
是在MyBatis
的基础上进行增强和扩展的持久层框架,旨在简化数据访问层的开发,提高开发效率。
MapperXML 在 MyBatis 中,Mapper XML 文件(通常以 .xml 后缀结尾)用于定义 SQL 映射。这些文件包含了数据库操作的具体 SQL 语句,以及映射到 Java 对象的规则。
namespace 定义Mapper
接口的命名空间,与Java
接口绑定。比如:namespace="com.acaiblog.article.mapper.AdvertMapper"
绑定到com/acaiblog/article/mapper/AdvertMapper
接口文件
<mapper namespace ="com.acaiblog.article.mapper.AdvertMapper" > </mapper >
ResultMap id="exampleResultMap"
将MapperXml文件中的增删改查绑定到exampleResultMap
,将数据库查询SQL结果和实体类com.example.ExampleEntity
进行映射,最终返回java类型数据。
<resultMap id ="exampleResultMap" type ="com.example.ExampleEntity" > <id property ="id" column ="id" /> <result property ="name" column ="name" /> </resultMap >
动态查询sql 根据Mapper中定义的接口传递的参数类型,在MapperXml文件中使用#{xx}占位符实现,例如: 在Mapper接口中定义
public interface ArticleMapper extends BaseMapper <Article> { Article findArticleAndLabelById (String id) ; }
在MapperXml中使用动态sql,其中#{id}就是findArticleAndLabelById接口传入的id值。
<mapper namespace ="com.acaiblog.article.mapper.ArticleMapper" > <select id ="findArticleAndLabelById" resultMap ="ArticleAndLabelMap" > SELECT t1.*, t3.id label_id, t3.`name` label_name FROM article t1 LEFT JOIN article_label t2 ON t1.id = t2.article_id LEFT JOIN label t3 ON t2.label_id =t3.id WHERE t1.id = #{id} </select > </mapper >
增删改查 MyBatis Plus 提供了通用的 CRUD 操作,通过继承 BaseMapper 接口,无需手动编写基本的增删改查 SQL 语句。
BaseMapper接口内置方法
方法名
描述
insert
插入记录
insertBatchSomeColumn
批量插入记录
selectById
根据主键查询记录
selectBatchIds
根据主键批量查询记录
selectOne
根据条件查询一条记录
selectList
根据条件查询记录列表
selectCount
根据条件查询记录总数
update
根据条件更新记录
deleteById
根据主键删除记录
deleteBatchIds
根据主键批量删除记录
delete
根据条件删除记录
selectCount
根据 Wrapper 条件,查询总记录数
exists
根据 Wrapper 条件,判断是否存在记录
selectOne
根据 Wrapper 条件,查询一条记录,多条抛出异常
selectMap
根据 Wrapper 条件,查询一条记录
selectMaps
根据 Wrapper 条件,查询列表
自定义查询实现
在pom.xml文件中添加依赖
<dependencies > <dependency > <groupId > com.baomidou</groupId > <artifactId > mybatis-plus-boot-starter</artifactId > <version > 3.4.3.1</version > </dependency > <dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > <version > 2.2.0</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.2.6</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 8.0.23</version > </dependency > <dependency > <groupId > org.mariadb.jdbc</groupId > <artifactId > mariadb-java-client</artifactId > <version > 2.7.1</version > </dependency > </dependencies >
在com.acaiblog.article.mapper.ArticleMapper
中定义自定义查询方法的接口
package com.acaiblog.article.mapper;import com.acaiblog.entities.Article;import com.baomidou.mybatisplus.core.mapper.BaseMapper;public interface ArticleMapper extends BaseMapper <Article> { Article findArticleAndLabelById (String id) ; }
在com/acaiblog/article/mapper/xml/ArticleMapper.xml
配置文件中定义查询sql语句并与查询方法接口关联
<?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.acaiblog.article.mapper.ArticleMapper" > <select id ="findArticleAndLabelById" > SELECT t1.*, t3.id label_id, t3.`name` label_name FROM article t1 LEFT JOIN article_label t2 ON t1.id = t2.article_id LEFT JOIN label t3 ON t2.label_id =t3.id WHERE t1.id = #{id} </select > </mapper >
在com.acaiblog.article.service.IArticleService
服务层定义操作数据访问层接口
package com.acaiblog.article.service;import com.acaiblog.entities.Article;import com.acaiblog.util.base.Result;import com.baomidou.mybatisplus.extension.service.IService;public interface IArticleService extends IService <Article> { Result findArticleAndLabelById (String id) ; }
在com.acaiblog.article.service.impl.ArticleServiceImpl
中定义findArticleAndLabelById接口具体实现
package com.acaiblog.article.service.impl;import com.acaiblog.entities.Article;import com.acaiblog.article.mapper.ArticleMapper;import com.acaiblog.article.service.IArticleService;import com.acaiblog.util.base.Result;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import org.springframework.stereotype.Service;@Service public class ArticleServiceImpl extends ServiceImpl <ArticleMapper, Article> implements IArticleService { @Override public Result findArticleAndLabelById (String id) { return Result.ok(baseMapper.findArticleAndLabelById(id)); } }
代码生成器 MyBatis Plus
代码生成器是MyBatis Plus
提供的一个工具,可以根据数据库表结构自动生成对应的Java
实体类、Mapper
接口以及XML
映射文件。
实现步骤
创建一个子模块generator
,用来管理代码生成器 在模块generator
的pom.xml
添加依赖
<dependency > <groupId > com.baomidou</groupId > <artifactId > mybatis-plus-boot-starter</artifactId > <version > 3.4.3.1</version > </dependency > <dependency > <groupId > org.mariadb.jdbc</groupId > <artifactId > mariadb-java-client</artifactId > <version > 2.7.1</version > </dependency >
在resouces
目录下创建application.yml
配置文件,添加数据源
spring.datasource.url=jdbc:mariadb://localhost:3306/your_database spring.datasource.username=your_username spring.datasource.password=your_password spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
创建com.acaiblog.generator.CodeGenerator
代码生成器类
package com.acaiblog.generator;import ch.qos.logback.classic.Logger;import com.baomidou.mybatisplus.annotation.IdType;import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;import com.baomidou.mybatisplus.generator.AutoGenerator;import com.baomidou.mybatisplus.generator.config.DataSourceConfig;import com.baomidou.mybatisplus.generator.config.GlobalConfig;import com.baomidou.mybatisplus.generator.config.PackageConfig;import com.baomidou.mybatisplus.generator.config.StrategyConfig;import com.baomidou.mybatisplus.generator.config.rules.DateType;import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;import org.apache.commons.lang.StringUtils;import org.slf4j.LoggerFactory;import org.slf4j.impl.StaticLoggerBinder;import java.util.Scanner;public class CodeGenerator { private static final String PROJECT_NAME = "blog-system" ; private static final String DATABASE_NAME = "blog" ; private static final String MODULE_NAME = "system" ; public static void main (String[] args) { AutoGenerator autoGenerator = new AutoGenerator (); DataSourceConfig dataSourceConfig = new DataSourceConfig (); dataSourceConfig.setUrl("jdbc:mariadb://localhost:3306/" + DATABASE_NAME + "?useUnicode=true&useSSL=false&characterEncoding=utf8" ); dataSourceConfig.setDriverName("org.mariadb.jdbc.Driver" ); dataSourceConfig.setUsername("root" ); dataSourceConfig.setPassword("123456" ); autoGenerator.setDataSource(dataSourceConfig); GlobalConfig globalConfig = new GlobalConfig (); String projectPath = System.getProperty("user.dir" ) + "/" ; globalConfig.setOutputDir(projectPath + PROJECT_NAME + "/src/main/java" ); globalConfig.setIdType(IdType.ASSIGN_ID); globalConfig.setAuthor("baocai.guo@qq.com" ); globalConfig.setFileOverride(true ); globalConfig.setOpen(false ); globalConfig.setDateType(DateType.ONLY_DATE); globalConfig.setSwagger2(true ); autoGenerator.setGlobalConfig(globalConfig); PackageConfig packageConfig = new PackageConfig (); packageConfig.setParent("com.acaiblog" ); packageConfig.setController(MODULE_NAME + ".controller" ); packageConfig.setService(MODULE_NAME + ".service" ); packageConfig.setServiceImpl(MODULE_NAME + ".service.impl" ); packageConfig.setMapper(MODULE_NAME + ".mapper" ); packageConfig.setXml(MODULE_NAME + ".mapper.xml" ); packageConfig.setEntity("entities" ); autoGenerator.setPackageInfo(packageConfig); StrategyConfig strategyConfig = new StrategyConfig (); strategyConfig.setNaming(NamingStrategy.underline_to_camel); strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel); strategyConfig.setEntityLombokModel(true ); strategyConfig.setEntitySerialVersionUID(true ); strategyConfig.setRestControllerStyle(true ); strategyConfig.setInclude(scanner("表名,多个英文逗号分割" ).split("," )); strategyConfig.setControllerMappingHyphenStyle(true ); strategyConfig.setTablePrefix("mxg_" ); autoGenerator.setStrategy(strategyConfig); autoGenerator.setTemplateEngine(new FreemarkerTemplateEngine ()); autoGenerator.execute(); } public static String scanner (String tip) { Scanner scanner = new Scanner (System.in); System.out.println("请输入" + tip + ":" ); if (scanner.hasNext()) { String ipt = scanner.next(); if (StringUtils.isNotEmpty(ipt)) { return ipt; } } throw new MybatisPlusException ("请输入正确的" + tip); } }
执行CodeGenerator类,在input中输入模块对应的数据库表名。如果一个模块有多个数据库表则使用逗号隔开,比如: aaa,bbb,ccc
服务层 在SpringBoot中服务层是应用程序的核心,主要处理业务逻辑、调用数据访问层(DAO)进行数据操作。
@Service注解 在Spring Boot
中,使用@Service
注解来标识一个类为服务层的组件。这样Spring
容器会自动扫描并注册这些服务类。
import org.springframework.stereotype.Service;@Service public class MyService { }
事物管理 服务层通常涉及到事务的处理,确保在一组相关的操作中,要么全部成功执行,要么全部回滚到初始状态。Spring
提供了@Transactional
注解来声明事务性的方法。
import org.springframework.transaction.annotation.Transactional;@Service public class MyService { @Transactional public void performTransactionalOperation () { } }
调用数据访问层 示例代码:
public Result findArticleAndLabelById (String id) { return Result.ok(baseMapper.findArticleAndLabelById(id)); }
控制层 在Spring Boot
中,控制层是应用程序的入口点,负责接收用户请求、调用服务层进行业务处理,并返回相应的视图或数据给用户。通俗理解:
当用户访问一个API接口时,SpringBoot根据请求接口的地址匹配到对应控制器的方法。
控制器方法调用服务层接口
服务层接口处理业务逻辑,并调用数据访问层接口
数据访问层根据接口关联到MappXml的sql,在数据库查询结果并根据ResultMap将查询结果映射到实体类,最终将查询结果由控制器返回给用户