一、SpringBoot

SpringBoot是spring公司pivotal后续研发的一款框架,其目的是简化传统的Spring框架的开发,并不是替代spring。简化的过程主要体现在对于传统Spring项目中的一些繁琐的配置、繁琐的依赖管理进行简化。而且和传统的web项目有很大不同的是SpringBoot提供了一种新的部署方式:服务器内置,传统的web项目需要打包,然后将程序包放到外置tomcat中去运行,而Springboot通过将tomcat内置,将Tomcat的启动放到了SpringBoot项目的启动过程中。

Spring-Boot实现原理

POM.xml

  • 依赖版本的管理 BOM spring-boot-starter-parent —> Spring-boot-dependencies(所有的依赖版本)
    • 统一版本,减少技术成本
    • 解决jar包之间版本兼容的问题,尽量不写版本,沿用父项目中的版本
  • starter依赖
    • 简化依赖
    • 自动配置
  • spring-boot-maven-plugin插件
    • 通过maven运行spring-boot项目 mvn spring-boot:run
    • 打包 jar (fatjar,支持直接运行)
      • mvn clean package -Dmaven.test.skip=true
      • java -jar demo56-0.0.1-SNAPSHOT.jar

自动配置原理

  • 目的: 集成第三方框架之后,可自动配置,集成到spring中

image.png问题:
mybatis集成到spring中的方式是一样的,换言之,以下代码在不同项目中是重复存在的

  1. //sqlSessionFactoryBean配置,替代mybatis-config.xml
  2. @Bean
  3. public SqlSessionFactoryBean sqlSessionFactoryBean() throws IOException {
  4. SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
  5. //数据源
  6. sqlSessionFactoryBean.setDataSource(dataSource());
  7. //别名包
  8. sqlSessionFactoryBean.setTypeAliasesPackage("com.woniuxy.framework.model");
  9. org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
  10. //下划线映射到驼峰
  11. configuration.setMapUnderscoreToCamelCase(true);
  12. //日志
  13. configuration.setLogImpl(StdOutImpl.class);
  14. sqlSessionFactoryBean.setConfiguration(configuration);
  15. //配置文件位置
  16. PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
  17. Resource[] resources = patternResolver.getResources("classpath*:mappers/**/*.xml");
  18. sqlSessionFactoryBean.setMapperLocations(resources);
  19. return sqlSessionFactoryBean;
  20. }

1) 重复的,套路式的配置代码,在不同项目中是一样的
2) 部分配置,需要手动配置,每个项目是不同
如果有一种方式,能够将重复的配置代码封装掉,并且提供了修改的配置项的配置的方式,能够很大的提高效率
spring-boot的starter完成以上功能
技术实现:

  1. @SpringBootApplication 包含了@EnableAutoConfiguration,启动自动配置
  2. xxx-spring-boot-starter 的包下有一个文件夹 META-INF,文件叫spring.factories,包含了自动配置类路径
    1. # Auto Configure
    2. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    3. org.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration,\
    4. org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
    3.定位自动配置类,自动配置类提供了必要的bean 的配置 ```java @org.springframework.context.annotation.Configuration //配置类 public class MybatisAutoConfiguration implements InitializingBean {

@Bean //注册springbean @ConditionalOnMissingBean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); factory.setDataSource(dataSource); … //设置配置map-underscore-to-camel-case、log-impl applyConfiguration(factory); if (this.properties.getConfigurationProperties() != null) { factory.setConfigurationProperties(this.properties.getConfigurationProperties()); } if (!ObjectUtils.isEmpty(this.interceptors)) { factory.setPlugins(this.interceptors); } … //设置别名包 if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) { factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage()); } … //mapper.xml的路径位置 if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) { factory.setMapperLocations(this.properties.resolveMapperLocations()); } …. return factory.getObject(); }

}

  1. 4. 需要自定义的配置,自动配置类MybatisAutoConfiguration关联了一个配置属性类 @EnableConfigurationProperties_(_MybatisProperties.class_)_
  2. ```java
  3. @org.springframework.context.annotation.Configuration
  4. @ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
  5. @ConditionalOnSingleCandidate(DataSource.class)
  6. >>>>@EnableConfigurationProperties(MybatisProperties.class)
  7. @AutoConfigureAfter({ DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class })
  8. public class MybatisAutoConfiguration implements InitializingBean {
  9. private static final Logger logger = LoggerFactory.getLogger(MybatisAutoConfiguration.class);
  10. >>>> private final MybatisProperties properties;
  1. 配置属性类与applicatoin.yml配置文件里的属性相对应 ```java //标记为配置属性类,指定前缀,此处为mybatis,完整配置项名为mybatis.属性名 例如mybatis.typeAliasesPackage @ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX) public class MybatisProperties {

    public static final String MYBATIS_PREFIX = “mybatis”;

    private String typeAliasesPackage;

  1. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/953441/1623744612298-4f98a571-9e06-4539-a4f6-0846f76e1836.png#align=left&display=inline&height=442&margin=%5Bobject%20Object%5D&name=image.png&originHeight=442&originWidth=1178&size=152386&status=done&style=none&width=1178)<br />1) 重复的,套路式的配置代码,在不同项目中是一样的 ---> 自动配置类<br />2) 部分配置,需要手动配置,每个项目是不同 ---> 配置属性类+外化配置文件
  2. <a name="eKD3M"></a>
  3. ## 二、SpringBoot的基本使用
  4. <a name="KTg1i"></a>
  5. #### 第一种创建方式
  6. <a name="7c263a62"></a>
  7. ### 1、创建一个Maven项目
  8. 创建一个Maven项目,使用quick-start模板
  9. <a name="e0ba759c"></a>
  10. ### 2、以SpringBoot提供的start依赖作为父项目
  11. 通过SpringBoot的父项目可以将一个SpringBoot版本之下的一整套web项目中所需的依赖版本进行约束。

org.springframework.boot spring-boot-parent 2.2.10.RELEASE

  1. <a name="1dffd83c"></a>
  2. ### 3、引入spring-boot-starter-web依赖
  3. 引入一个web项目中所要使用到的常用依赖,包括内置的tomcat、spring、springmvc、hibernate-validator、jackson,不包括_mybatis**、**jdbc**、连接池、**spring-jdbc、file-upload。_

org.springframework.boot spring-boot-starter-web

  1. <a name="bb8e0cdf"></a>
  2. ### 4、提供springboot配置文件
  3. 在resources文件夹下名为application.properties或者application.yml的配置文件。
  4. <a name="1de8b151"></a>
  5. ### 5、完善项目结构
  6. 在resources之下新建static的文件夹,因为springboot默认加载了SpringMVC,而在加载SpringMVC的前端控制器时,使用的地址规则为/,为了访问静态资源SpringBoot也做了静态资源映射,默认情况下映射的路径为static目录下,所以我们要新建static目录。
  7. ![](https://cdn.nlark.com/yuque/0/2021/png/12430968/1618902755119-bce95b46-bb2a-4e3e-8098-3060425d07f6.png#align=left&display=inline&height=218&margin=%5Bobject%20Object%5D&originHeight=218&originWidth=610&status=done&style=none&width=610)
  8. <a name="ed70425a"></a>
  9. ### 6、启动springboot项目
  10. 在一个拥有main函数的类中添加一个注解@SpringBootApplication,在main函数中执行SpringApplication.run(主类名.class)

@SpringBootApplication public class App { public static void main( String[] args ) { SpringApplication.run(App.class); } }

  1. @SpringBootApplicationspringboot项目的核心注解,该注解是一个复合注解,在它上面有3大注解:
  2. @SpringBootConfiguration:被Configuration注解修饰表示配置类,也就是我们的springboot启动类也是一个配置类
  3. @EnableAutoConfiguration:启动自动配置,springboot会自动将一些重要框架的核心对象进行配置、包括spring的监听器、springmvc的前端控制器。
  4. @ComponentScan:扫描包加载bean,默认扫描和启动类同级的包以及子包
  5. <a name="ooWmy"></a>
  6. #### 第二种创建方式
  7. 1. 选择spring intializer
  8. 1. 填写maven坐标GAV
  9. 1. 选择依赖(spring-web\lombok)
  10. 1. 完成<br />a. 访问start.spring.io,根据所选依赖,生成代码<br />b. 返回一个项目zip<br />c. 解压,导入到idea<br />d. maven编译
  11. **注意**:Application类,一定放在根目录,跟其他包同级
  12. **打包是jar包,jar包怎么部署?**
  13. Spring Boot使创建独立的、生产级的、基于Spring的应用程序变得容易,您可以 just run 这些应用程序。<br />我们对于spring平台和第三方库做了统一的视图,以便于以最小的代价开始开发。大多数Spring Boot应用程序需要最少的Spring配置。
  14. <a name="ExAJ2"></a>
  15. ## 特征
  16. - 创建**独立的Spring应用程序**:不依赖于其他的工具或者平台,直接运行
  17. - 直接**内嵌入Tomcat**、JettyUndertow (无需部署WAR文件): 直接启动tomcat运行,无须部署war
  18. - 提供自包含的 **“starter 依赖**,以简化您的构建配置
  19. - 将需要的依赖进行了依赖传递,简化依赖
  20. - spring-boot中使用的依赖都是starter依赖,换言之,引入springmvc,不直接导入spring-webmvc而是使用spring-boot-starter-web
  21. - 命名规范:官方spring-boot-starter-xxx 民间:xxx-spring-boot-starter
  22. - 简化配置
  23. - 尽可能**自动配置**Spring和第三方库
  24. - 集成springmvc,自动配置viewresolver
  25. - 提供可用于**生产级功能**,如指标、运行状况检查和**外部化配置**
  26. - 绝对没有代码生成,也不需要XML配置
  27. <a name="bb0cfffb"></a>
  28. ## 三、SpringBoot搭建SSM应用
  29. <a name="0fe2e25a"></a>
  30. ### 1、新建控制层业务层完成依赖注入
  31. 控制层和业务层的包必须和启动类平级或者处于它的子级,因为springboot会默认扫描启动类平级的包及子包。
  32. 热部署插件:

org.springframework.boot spring-boot-devtools true test

org.springframework.boot spring-boot-maven-plugin true

  1. <a name="f7225c01"></a>
  2. ### 2、springboot配置mybatis
  3. 引入依赖
  4. ```xml
  5. <dependency>
  6. <groupId>org.springframework</groupId>
  7. <artifactId>spring-jdbc</artifactId>
  8. </dependency>
  9. <dependency>
  10. <groupId>mysql</groupId>
  11. <artifactId>mysql-connector-java</artifactId>
  12. <!-- 如果是8.0,不需要加版本-->
  13. <version>5.1.47</version>
  14. </dependency>
  15. <dependency>
  16. <groupId>org.mybatis.spring.boot</groupId>
  17. <artifactId>mybatis-spring-boot-starter</artifactId>
  18. <version>2.1.4</version>
  19. </dependency>
  20. <dependency>
  21. <groupId>com.alibaba</groupId>
  22. <artifactId>druid</artifactId>
  23. <version>1.1.23</version>
  24. </dependency>

在引入了mybatis-spring-boot-starter以后,springboot就会自动对mybatis进行配置,而配置mybatis的第一步就是加载数据源,要加载数据源需要我们提供连接数据库的各项信息。如果没有提供连接数据库的信息会在启动项目时报错。

连接数据库的各项信息在application.yml文件中提供
外化配置配置文件,命名约定 : application / boostarp 后缀: yml/yaml/properties

  1. spring:
  2. datasource:
  3. type: com.alibaba.druid.pool.DruidDataSource
  4. url: jdbc:mysql://localhost/woniudb?useUnicode=true&characterEncoding=utf-8
  5. driver-class-name: com.mysql.jdbc.Driver
  6. username: root
  7. password: 123456
  8. server:
  9. port: 8000
  10. mybatis:
  11. type-aliases-package: com.example.demo56.entity
  12. configuration:
  13. map-underscore-to-camel-case: true
  14. log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
  15. mapper-locations: classpath*:mappers/**/*.xml

按照以前mybatis的使用方式建好mapper以及它的映射文件,映射文件存放到resource/mapper文件夹下。

然后在application.yml文件中提供mybatis映射文件的地址,如果使用了别名,别名在此处配置

  1. mybatis:
  2. mapper-locations: classpath:/mapper/*Mapper.xml
  3. type-aliases-package: com.woniuxy.entity

最后在启动类上添加一个注解@MapperScan(“数据层mapper的包名”),springboot就会自动的创建出mapper对象

  1. @SpringBootApplication
  2. @MapperScan("com.woniuxy.mapper")//扫包,一般设定为mapper包
  3. @EnableTransactionManagement //开启事务
  4. public class App {
  5. public static void main( String[] args ) {
  6. SpringApplication.run(App.class);
  7. }
  8. }

3、声明式事务

用注解的方式正常的完成依赖注入,调用方法。

在SpringBoot中声明式事务有两种配置方式:

方式一:使用常规的spring配置文件

  1. <!--配置事务管理器 封装了事务的提交回滚等方法-->
  2. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  3. <!--注入数据源-->
  4. <property name="dataSource" ref="dataSource"></property>
  5. </bean>
  6. <!--事务通知-->
  7. <!--定义在程序执行到切入点以后 具体的切面织入方式(哪些方法需要使用事务管理 哪些不需要)-->
  8. <tx:advice id="txAdvice" transaction-manager="transactionManager" >
  9. <tx:attributes>
  10. <!--配置方法名的规则 前缀是insert delete update的所有方法 需要事务控制-->
  11. <tx:method name="insert*" propagation="REQUIRED"/>
  12. <tx:method name="delete*" propagation="REQUIRED"/>
  13. <tx:method name="update*" propagation="REQUIRED"/>
  14. <!--其他方法不需要事务控制 read-only为只读 -->
  15. <tx:method name="*" read-only="true"/>
  16. </tx:attributes>
  17. </tx:advice>
  18. <!--切面的配置-->
  19. <!--定义切面-->
  20. <aop:config>
  21. <!--定义切入点-->
  22. <aop:pointcut expression="execution(* com.woniuxy.service.impl.*.*(..))" id="transactionPoint"/>
  23. <!--织入 在某个切入点执行通知-->
  24. <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPoint"/>
  25. </aop:config>

然后在启动类上添加一个@ImportResource(“xml文件地址”),加载xml文件完成声明式事务。

方式二:注解方式

在启动类上添加注解@EnableTransactionManagement开启声明式事务

  1. @SpringBootApplication
  2. @MapperScan("com.woniuxy.mapper")
  3. @EnableTransactionManagement
  4. public class App {
  5. public static void main( String[] args ) {
  6. SpringApplication.run(App.class);
  7. }
  8. }

在业务层的方法上需要开启事务管理的添加一个注解@Transactional

@Transactional注解可选的属性有:

  1. @Transactional
  2. public User insert(User user) throws Exception {
  3. System.out.println("执行新增");
  4. return userMapper.insert(user);
  5. }

propagation:配置事务传播机制

rollbackFor:配置需要进行回滚的异常种类,默认Exception

4、在SpringBoot配置过滤器

方式一:和以前一样创建一个过滤器,添加WebFilter注解。在启动类上添加一个注解@ServletComponentScan(“过滤器的包名”)。

  1. @WebFilter("/*")
  2. public class CrossFilter implements Filter {
  3. @Override
  4. public void init(FilterConfig filterConfig) throws ServletException {
  5. }
  6. @Override
  7. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  8. System.out.println("执行过滤器");
  9. filterChain.doFilter(servletRequest,servletResponse);
  10. }
  11. @Override
  12. public void destroy() {
  13. }
  14. }
  15. @SpringBootApplication
  16. @MapperScan("com.woniuxy.mapper")
  17. @EnableTransactionManagement
  18. @ServletComponentScan("com.woniuxy.filter")//扫描Servlet组件,也可以用于扫描WebListener、WebServlet
  19. public class App {
  20. public static void main( String[] args ) {
  21. SpringApplication.run(App.class);
  22. }
  23. }

方式二:使用SpringBoot提供的注册器来加载Filter

在一个配置类中通过bean标签创建FilterRegistrationBean对象,通过该对象来完成过滤器的加载。

  1. @Bean
  2. public FilterRegistrationBean initFilterRegister(){
  3. FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>();
  4. registrationBean.setFilter(new CrossFilter());//添加我们自己的Filter对象
  5. ArrayList<String> list = new ArrayList<>();
  6. list.add("/*");
  7. registrationBean.setUrlPatterns(list);//设置过滤器的地址规则
  8. registrationBean.setName("crossFilter");//设置filter名称
  9. registrationBean.setOrder(1);//设置filter执行顺序 1最先执行
  10. return registrationBean;
  11. }

5、在SpringBoot中配置拦截器

在springboot中配置拦截器需要借助Spring提供WebmvcConfigure这个接口,通过实现该接口重写addInterceptors方法。

  1. @Configuration
  2. public class IntercepterConfigure implements WebMvcConfigurer {
  3. @Override
  4. public void addInterceptors(InterceptorRegistry registry) {
  5. registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/js/**").excludePathPatterns("/css/**");
  6. }
  7. }

6、在SpringBoot中配置参数类型转换器

和以前一样首先写好一个参数类型转换器。然后在WebmvcConfigure配置类中通过addFormatters方法来加载参数类型转换器。

  1. public class DateConverter implements Converter<String, Date> {
  2. @Override
  3. public Date convert(String s) {
  4. SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
  5. SimpleDateFormat format2 = new SimpleDateFormat("yyyy/MM/dd");
  6. Date date=null;
  7. if(s.contains("/")){
  8. try {
  9. date=format2.parse(s);
  10. } catch (ParseException e) {
  11. e.printStackTrace();
  12. }
  13. }else if(s.contains("-")){
  14. try {
  15. date=format1.parse(s);
  16. } catch (ParseException e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. return date;
  21. }
  22. }
  23. @Configuration
  24. public class MVCComponentConfigure implements WebMvcConfigurer {
  25. @Override
  26. public void addFormatters(FormatterRegistry registry) {
  27. registry.addConverter(new DateConverter());
  28. }
  29. }

四、整合Swagger2框架提供在线API文档

在前后端分离开发的场景中,前端负责调用后端提供的数据接口来实现前端业务功能。前端需要后端开发人员提供一套详细的接口文档。传统的方式一般是后端人员以word、excel等格式编写API文档。传统的方式存在一些问题,首先后端人员要编写一份较为完善的API文档是具备一定难度的,更重要的是如果我们的代码发生了变更,API也需要同步修改。Swagger2框架的作用是可以快捷生成在线的API文档并可以进行在线测试。

springboot整合swagger2的步骤

1、引入swagger2的依赖

我们本次使用的是Swagger2 2.9.2的版本

  1. <dependency>
  2. <groupId>io.springfox</groupId>
  3. <artifactId>springfox-swagger2</artifactId>
  4. <version>2.9.2</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>io.springfox</groupId>
  8. <artifactId>springfox-swagger-ui</artifactId>
  9. <version>2.9.2</version>
  10. </dependency>

2、在配置类中配置Swagger2相关参数

  1. @Bean
  2. public Docket createRestApi() {
  3. //API构建器
  4. ApiInfoBuilder apiBuilder = new ApiInfoBuilder();
  5. //设置API的相关信息
  6. apiBuilder.title("蜗牛OA系统");
  7. apiBuilder.description("只为成就更好的你");
  8. apiBuilder.contact(new Contact("蜗牛学院","www.woniuxy.com","dengqiang@woniuxy.com"));
  9. apiBuilder.version("1.0");
  10. //构建API对象
  11. ApiInfo api = apiBuilder.build();
  12. //构建API清单 用于说明那些接口需要生成API文档
  13. Docket docket = new Docket(DocumentationType.SWAGGER_2).apiInfo(api);
  14. //定义接口(控制层)所在的包
  15. docket.select().apis(RequestHandlerSelectors.basePackage("com.woniuxy.controller")).paths(PathSelectors.any()).build();
  16. return docket;
  17. }

3、在启动类上添加一个注解@EnableSwagger2启用Swagger2

  1. @SpringBootApplication
  2. @MapperScan("com.woniuxy.mapper")
  3. @EnableTransactionManagement
  4. @EnableSwagger2
  5. public class App {}

项目启动之后通过swagger2提供的在线的API文档并可以进行测试,名称:swagger-ui.html。

4、对接口信息进行更为详细的描述

可以使用一些额外的注解将接口信息描述的更加详细。

@Api :添加到业务控制器类上,使用tags属性可以描述我们的业务控制器信息

@ApiOperation :添加到业务控制器方法上,用于对每一个方法进行说明

@ApiImplicitParams :对参数进行详细的描述,外层标签

@ApiImplicitParam :对某一个具体的参数进行详细描述,内层标签

  1. @PostMapping
  2. @ApiOperation("新增用户信息")
  3. @ApiImplicitParams({
  4. @ApiImplicitParam(name="id",required = false),
  5. @ApiImplicitParam(name="token",required = false),
  6. @ApiImplicitParam(name="account",required = true),
  7. @ApiImplicitParam(name="password",required = true),
  8. @ApiImplicitParam(name="nickname",required = true)
  9. })
  10. public JSONResult insert(User user) throws Exception{
  11. JSONResult result = new JSONResult();
  12. result.setCode("1001");
  13. result.setMessage("新增成功");
  14. return result;
  15. }

五、SpringBoot整合模板引擎

模板引擎是通过一个网页模板编写网页,在模板中使用了很多的占位符来代替动态数据的位置,最后在将动态数据渲染到网页模板中的这样一种技术。

1、引入thymeleaf依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-thymeleaf</artifactId>
  4. </dependency>

所有的依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-jdbc</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-thymeleaf</artifactId>
  8. </dependency>
  9. <dependency>
  10. <groupId>org.springframework.boot</groupId>
  11. <artifactId>spring-boot-starter-web</artifactId>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.mybatis.spring.boot</groupId>
  15. <artifactId>mybatis-spring-boot-starter</artifactId>
  16. <version>2.1.4</version>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.springframework.boot</groupId>
  20. <artifactId>spring-boot-devtools</artifactId>
  21. <scope>runtime</scope>
  22. <optional>true</optional>
  23. </dependency>
  24. <dependency>
  25. <groupId>mysql</groupId>
  26. <artifactId>mysql-connector-java</artifactId>
  27. <version>5.1.47</version>
  28. </dependency>
  29. <dependency>
  30. <groupId>org.projectlombok</groupId>
  31. <artifactId>lombok</artifactId>
  32. <optional>true</optional>
  33. </dependency>
  34. <dependency>
  35. <groupId>com.alibaba</groupId>
  36. <artifactId>druid</artifactId>
  37. <version>1.1.23</version>
  38. </dependency>

2、配置springboot的配置文件

  1. server.port=80
  2. spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
  3. spring.datasource.url=jdbc:mysql://localhost/woniudb?useUnicode=true&characterEncoding=utf-8
  4. spring.datasource.password=123456
  5. spring.datasource.username=root
  6. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  7. mybatis.mapper-locations=classpath:/mapper/*Mapper.xml
  8. mybatis.type-aliases-package=com.woniuxy.entity
  9. #配置模板引擎的存放位置和后缀
  10. #前后缀默认就是classpath:/templates/和.html所以可以不配置
  11. spring.thymeleaf.prefix=classpath:/templates/
  12. spring.thymeleaf.suffix=.html
  13. spring.thymeleaf.cache=false

3、编写一个模板文件

模板文件存放在resources的templates文件夹下,模板文件采用html格式,在html标签中可以指定命名空间,指定命名空间之后作用是可以提示thymeleaf的插值和表达式

在网页中使用th:text标签属性将数据渲染到span标签中。

  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>用户数据</title>
  6. </head>
  7. <body>
  8. <!--可以使用模板引擎的插值来作为占位符-->
  9. <span th:text="${user.nickname}"></span>
  10. </body>
  11. </html>

4、编写一个Controller

该Controller不会响应JSON的数据格式所以直接才@Controller注解,然后方法的返回值需要定义ModelAndView类型,用于存放模板名称和动态数据。

  1. @Controller
  2. public class UserController{
  3. @RequestMapping("select")
  4. public ModelAndView select() throws Exception{
  5. User user = new User();
  6. user.setNickname("宋昂泰");
  7. user.setAccount("songangtai");
  8. user.setPassword("250");
  9. ModelAndView modelAndView = new ModelAndView("user");
  10. modelAndView.addObject("user",user);
  11. return modelAndView;
  12. }
  13. }

5、启动项目访问

访问select地址,网页上出现了渲染的动态数据

SpringBoot - 图2

6、其他的插值

th:each:等同于jsp中的c:foreach用于遍历集合数据

th:attr :用于给标签属性赋值,例如要给图片标签的src属性赋值,

th:value:用于为表单控件赋值

th:text:给标签之间的文本赋值

  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>用户数据</title>
  6. <style>
  7. .red{background-color: red}
  8. .green{background-color: green}
  9. </style>
  10. </head>
  11. <body>
  12. <table>
  13. <tr>
  14. <td>用户编号</td>
  15. <td>账户</td>
  16. <td>密码</td>
  17. <td>昵称</td>
  18. <td>令牌</td>
  19. </tr>
  20. <tr th:each="u,i:${users}" th:attr="class=${i.even?'red':'green'}">
  21. <td th:text="${u.id}"></td>
  22. <td th:text="${u.account}"></td>
  23. <td th:text="${u.password}"></td>
  24. <td th:text="${u.nickname}"></td>
  25. <td><input th:value="${u.token}"></td>
  26. </tr>
  27. </table>
  28. </body>
  29. </html>

六、SpringBoot整合MybatisPlus框架

MybatisPlus框架并不是取代原本的mybatis,而是对Mybatis做了一层封装提供了更简洁的数据层访问方式,但是MybatisPlus并没有对原本mybatis的使用方式造成影响。MP主要优势有两点:提供了默认的API进行数据层的访问,在我们不去写任何sql的情况下就可以对数据库进行基本的CRUD。提供了内置的代码生成器可以快捷生成实体类、数据层接口、映射xml。

1、引入依赖

mp的依赖中已经默认引入了mybatis的依赖,就不需要再额外导入mybatis的依赖。

  1. <!--mybatis-plus依赖-->
  2. <dependency>
  3. <groupId>com.baomidou</groupId>
  4. <artifactId>mybatis-plus-boot-starter</artifactId>
  5. <version>3.4.0</version>
  6. </dependency>

2、在springboot项目中配置mybatis的属性

这里的配置和单独使用mybatis没有区别,仍然要配置数据源,mybatis映射文件地址等等。

  1. server:
  2. port: 80
  3. spring:
  4. datasource:
  5. type: com.alibaba.druid.pool.DruidDataSource
  6. url: jdbc:mysql://localhost/woniudb?useUnicode=true&characterEncoding=utf-8
  7. driver-class-name: com.mysql.jdbc.Driver
  8. username: root
  9. password: 123456
  10. mybatis:
  11. mapper-locations: classpath:/mapper/*Mapper.xml
  12. type-aliases-package: com.woniuxy.entity

3、新建数据层接口和映射文件

在新建数据层接口时继承一个叫BaseMapper的父类,同时传入泛型(当前这个数据层操作那个实体类就传那个泛型)

BaseMapper中提供了一系列CRUD的方法,而这些方法,MP已经帮我们进行了实现,要注意MP在执行sql时,是根据属性名称生成的SQL语句。所以我们需要保证实体类属性名称必须和数据库表的字段名称一致。

  1. public interface UserMapper extends BaseMapper<User> {
  2. }
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <!DOCTYPE mapper
  5. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  6. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  7. <mapper namespace="com.woniuxy.mapper.UserMapper">
  8. </mapper>

4、MP提供的数据层API

  1. int insert(T entity); //传入实体对象实现新增 (重要)
  2. int deleteById(Serializable id);//根据ID删除 (重要)
  3. int deleteByMap(@Param("cm") Map<String, Object> columnMap);//根据键值对删除数据,键值对中的每一对键值都会作为删除的条件来使用
  4. int delete(@Param("ew") Wrapper<T> wrapper);//根据条件删除 使用MP提供的条件封装API封装条件 (重要)
  5. int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);//根据ID集合删除数据
  6. int updateById(@Param("et") T entity);//(重要)根据传入的实体更新(根据主键更新其他所有数据),会将实体中的非空数据更新到数据库,但是0会更新到数据库,解决方式是尽量用包装类来定义属性
  7. int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);//根据传入的实体和Wrapper进行更新,entity中保存的是更新的数据,updateWrapper存放的是更新的条件和需要更新的字段
  8. T selectById(Serializable id);//根据传入的ID查询一个实体 (重要)
  9. List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);//根据多个ID查询实体集合
  10. List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);//根据键值对查询实体集合,键值对中的每一个键值对都会作为一个查询条件where key=value
  11. T selectOne(@Param("ew") Wrapper<T> queryWrapper);//根据条件查询一个实体
  12. Integer selectCount(@Param("ew") Wrapper<T> queryWrapper);//根据条件查询数据总行数
  13. List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);//根据条件查询实体集合 (重要)用于条件搜索不分页
  14. List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);//根据条件查询键值对
  15. List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);//根据条件查询主键值,将多个查询结果的主键封装为一个集合
  16. <E extends IPage<T>> E selectPage(E page, @Param("ew") Wrapper<T> queryWrapper);//(重要)做分页查询
  17. <E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param("ew") Wrapper<T> queryWrapper);

关于Wrapper类的使用:

在使用mybatis generator生成的代码中,每个类都有一个对应的example类,用于封装条件,mybatis plus提供了一个Wrapper类,用于封装各种条件。

下面我们就Wrapper中的常用条件的封装方式给出示例:

要封装条件首先需要实例化一个Wrapper类,Wrapper类分为两种,QueryWrapper和UpdateWrapper,UpdateWrapper比QueryWrapper多了set条件的设置,可以用于动态更新字段。实例化Wrapper类时需要指定泛型。例如:

SpringBoot - 图3

需要追加条件时,通过Wrapper提供的API来完成:

eq:eq用于添加相等的条件。

eq(R column, Object val):参数一为字段名称,参数二为值

eq(boolean condition, R column, Object val):参数一为boolean值,表示是否需要添加该条件到sql

ne:ne用于添加不相等的条件。

ne(R column, Object val):参数一为字段名称,参数二为值

ne(boolean condition, R column, Object val):参数一为boolean值,表示是否需要添加该条件到sql

gt:gt用于添加大于的条件

gt(R column, Object val)

gt(boolean condition, R column, Object val)

ge:ge用于添加大于等于的条件

ge(R column, Object val)

ge(boolean condition, R column, Object val)

lt:lt用于添加小于的条件

lt(R column, Object val)

lt(boolean condition, R column, Object val)

le:le用于添加小于等于的条件

le(R column, Object val)

le(boolean condition, R column, Object val)

between:between用于添加在两者之间的条件

between(R column, Object val1, Object val2)

between(boolean condition, R column, Object val1, Object val2)

notBetween:notBetween用于添加不在两者之间的条件

notBetween(R column, Object val1, Object val2)

notBetween(boolean condition, R column, Object val1, Object val2)

like:like用于添加模糊查询的条件

like(R column, Object val)

like(boolean condition, R column, Object val)

notLike:notlike用于添加not like 条件

notLike(R column, Object val)

notLike(boolean condition, R column, Object val)

likeLeft:leftLike用于添加左侧模糊匹配的条件

likeLeft(R column, Object val)

likeLeft(boolean condition, R column, Object val)

likeRight:likeRight用于添加右侧模糊匹配的条件

likeRight(R column, Object val)

likeRight(boolean condition, R column, Object val)

or:or用于追加or条件

or():主动调用则下一个条件会使用or来拼接

or(boolean condition)

orderBy:排序

orderBy(boolean condition, boolean isAsc, R… columns)

select:用于设置查询的字段列表

select(String… sqlSelect)

5、MybatisPlus分页插件的使用

加载MybatisPlus的分页插件,通过配置类来加载

  1. //加载分页插件拦截器
  2. @Bean
  3. public MybatisPlusInterceptor mybatisPlusInterceptor() {
  4. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  5. interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
  6. return interceptor;
  7. }

前端传条件数据封装为实体以及页码和每页显示行数,将这些数据一起传到业务层,业务的方法返回值需要定义为Page类型(MybatisPlus提供的Page类型)

  1. @Override
  2. public Page<User> selectPage(User user, int pageNum, int pageSize) {}

在业务方法中实例化一个Page对象,定义泛型为实体类型,在构造函数中传入页码和每页显示行数

  1. Page<User> userPage = new Page<>(pageNum,pageSize);

根据前端传递的条件参数,拼接动态查询条件

  1. QueryWrapper<User> wrapper = new QueryWrapper<>();
  2. if(user.getNickname()!=null&&!"".equals(user.getNickname())){
  3. wrapper.like("nickname",user.getNickname());
  4. }
  5. if(user.getAccount()!=null&&!"".equals(user.getAccount())){
  6. wrapper.like("account",user.getAccount());
  7. }

调用Mapper的API:selectPage(Page page,Wrapper wrapper);得到的返回值为Page对象,需要说明的是该Page对象就是我们之前所创建的Page对象。所有的数据(分页数据,业务数据)都保存在了这个Page对象中。返回该对象到控制层。

  1. @Override
  2. public Page<User> selectPage(User user, int pageNum, int pageSize) {
  3. Page<User> userPage = new Page<>(pageNum,pageSize);
  4. QueryWrapper<User> wrapper = new QueryWrapper<>();
  5. if(user.getNickname()!=null&&!"".equals(user.getNickname())){
  6. wrapper.like("nickname",user.getNickname());
  7. }
  8. if(user.getAccount()!=null&&!"".equals(user.getAccount())){
  9. wrapper.like("account",user.getAccount());
  10. }
  11. userMapper.selectPage(userPage, wrapper);
  12. return userPage;
  13. }

在控制层中将Page中的数据封装为一个自定义个Page对象(保存分页数据),取出其中的集合数据,一起封装为JSONresult,响应给前端。

  1. @GetMapping
  2. public JSONResult selectPage(User user,int pageNum,int pageSize)throws Exception{
  3. IPage<User> page = userService.selectPage(user, pageNum, pageSize);
  4. List<User> list = page.getRecords();
  5. Page page1 = new Page();
  6. page1.setCount(page.getTotal());
  7. page1.setTotal(page.getPages());
  8. page1.setCurrent(page.getCurrent());
  9. page1.setSize(page.getSize());
  10. return new JSONResult("1001","",page1,list);
  11. }

6、MybatisPlus代码生成器

引入依赖

  1. <dependency>
  2. <groupId>org.apache.velocity</groupId>
  3. <artifactId>velocity-engine-core</artifactId>
  4. <version>2.2</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.baomidou</groupId>
  8. <artifactId>mybatis-plus-generator</artifactId>
  9. <version>3.4.0</version>
  10. </dependency>

通过代码实现逆向工程:

  1. public class CodeGenerator {
  2. public static void main(String[] args) {
  3. String projectPath="D:\\springboot-demo\\src\\main\\";
  4. AutoGenerator ag = new AutoGenerator();
  5. //1. 全局配置
  6. GlobalConfig config = new GlobalConfig();
  7. config.setAuthor("wuyanzu") //作者
  8. .setOutputDir(projectPath+"java") //生成路径
  9. .setFileOverride(true)//是否文件覆盖,如果多次
  10. .setIdType(IdType.AUTO) //主键策略
  11. .setServiceName("%sService") //设置生成的service接口名首字母不用I开头
  12. .setBaseResultMap(true)//映射文件中生成默认的baseMap
  13. .setBaseColumnList(true);//映射文件中生成默认的基础列名sql
  14. //2. 数据源配置
  15. DataSourceConfig dsConfig = new DataSourceConfig();
  16. dsConfig.setDbType(DbType.MYSQL)
  17. .setUrl("jdbc:mysql://localhost:3306/woniudb")
  18. .setDriverName("com.mysql.jdbc.Driver")
  19. .setUsername("root")
  20. .setPassword("123456");
  21. //3.策略配置
  22. StrategyConfig stConfig = new StrategyConfig();
  23. stConfig.setCapitalMode(true) // 全局大写命名
  24. .setNaming(NamingStrategy.underline_to_camel) //下划线转驼峰
  25. .setInclude(new String[]{"t_student","teacher"});//生成的表,参数为数组
  26. //4.包名策略
  27. PackageConfig pkConfig = new PackageConfig();
  28. pkConfig.setParent("com.woniuxy")//父包名
  29. .setController("controller")
  30. .setEntity("entity")
  31. .setService("service")
  32. .setMapper("mapper");
  33. //5.生成xml的配置
  34. List<FileOutConfig> focList = new ArrayList<>();
  35. // 自定义配置
  36. InjectionConfig cfg = new InjectionConfig() {
  37. @Override
  38. public void initMap() {
  39. }
  40. };
  41. String templatePath = "/templates/mapper.xml.vm";
  42. // 自定义配置会被优先输出
  43. focList.add(new FileOutConfig(templatePath) {
  44. @Override
  45. public String outputFile(TableInfo tableInfo) {
  46. // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
  47. return projectPath+"\\resources\\mapper\\"+ tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
  48. }
  49. });
  50. cfg.setFileOutConfigList(focList);
  51. // 配置模板
  52. TemplateConfig templateConfig = new TemplateConfig();
  53. //不生成如下类型模板
  54. templateConfig.setXml(null);
  55. ag.setTemplate(templateConfig);
  56. //6.整合配置
  57. ag.setGlobalConfig(config)
  58. .setDataSource(dsConfig)
  59. .setStrategy(stConfig)
  60. .setPackageInfo(pkConfig)
  61. .setCfg(cfg)
  62. .setTemplateEngine(new VelocityTemplateEngine());
  63. ag.execute();
  64. }
  65. }