当前位置:   article > 正文

SpringBoot 项目搭建(详细介绍+案例源码)

springboot 项目

SpringBoot 项目整合源码

博客地址:SpringBoot 项目整合源码
其实不用直接去看源码了,源码也是按下面步骤搭建完的结果

SpringBoot 项目整合

一、项目准备

1.1 快速创建 SpringBoot 项目

博客地址:快速搭建 SpringBoot 项目(看完 【 1. 快速创建 SpringBoot 项目】 就可以回到这里了)

1.2 标准项目结构图如下

在这里插入图片描述

1.3 添加springboot-parent

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.3</version>
    <relativePath/>
</parent>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

1.4 添加 spring-boot-start-web

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

1.5 添加 Lambok 依赖

<!-- lombok 依赖 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

1.6 SpringBoot 打包插件

 <!-- SpringBoot 打包插件 -->
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
  • 1
  • 2
  • 3
  • 4
  • 5

1.7 添加 application.properties

# 修改端口号
server.port=80
  • 1
  • 2

1.8 编写启动类App

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

1.9 在 resources 创建static静态资源目录

1.10 在 resources 创建templates模板目录

1.11 在 resources 添加 banner.txt 文件

                   _ooOoo_
                  o8888888o
                  88" . "88
                  (| -_- |)
                  O\  =  /O
               ____/`---'\____
             .'  \\|     |//  `.
            /  \\|||  :  |||//  \
           /  _||||| -:- |||||_  \
           |   | \\\  -  /// |   |
           | \_|  ''\---/''  |   |
           \  .-\__  `-`  ___/-. /
         ___`. .'  /--.--\  `. . __
      ."" '<  `.___\_<|>_/___.'  >'"".
     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
     \  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======
                   `=---='
           佛祖保佑        永无BUG
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

二、整合数据库连接池

2.1 集成druid数据源

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.5</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.2 配置application.properties 文件

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql:///springboot?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=admin
  • 1
  • 2
  • 3
  • 4

2.3 数据源

  1. 默认数据源-Hikari

在springboot2.0之后 , 采用的默认连接池就是Hikari, 号称"史上最快的连接池", 所以我们没有添加依赖也能直接用, springboot的自动配置中含有DataSourceAutoConfiguration配置类, 会先检查容器中是否已经有连接池对象, 没有则会使用默认的连接池, 并根据特定的属性来自动配置连接池对象, 用到的属性值来源于DataSourceProperties对象。

  1. 配置 Druid 数据源

只需要添加依赖即可, 此时加的是Druid的springboot自动配置包, 里面包含了DruidDataSourceAutoConfigure自动配置类,会自动创建druid的连接池对象, 所以springboot发现已经有连接池对象了,则不会再使用Hikari

<!-- druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.5</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注意: 如果添加的依赖是以前那种普通包, 也就是和以前 ssm 项目一样,只添加 Druid 自身的依赖, 并不是自动配置包, 则需要以下配置(一般如果已经提供了springboot相关的自动配置包 , 直接使用自动配置的会更方便些):

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.19</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

还要在 application.properties 中加上一下配置。

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
  • 1

三、集成MyBatis

3.1 案例准备

需求:员工列表

1:将项目一里面员工表拷贝到新建的springboot表

2:拷贝逆向工程,创建员工domain, mapper

3:整合mybatis

3.2 准备依赖

<!--mybatis集成到SpringBoot中的依赖-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.4</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.3 配置Mapper接口扫描器

只要在配置类上贴个注解@MapperScan(…)即可。

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

3.4 配置属性

application.properties

以前在XML配置了哪些mybatis的属性在这里就配置哪些属性,属性前缀mybatis。

#mybatis.configuration.lazy-loading-enabled=true
#mybatis.configuration.lazy-load-trigger-methods=clone
#mybatis.mapper-locations=classpath:cn/wolfcode/*/mapper/*Mapper.xml
#mybatis.type-aliases-package=cn.wolfcode.sb.domain
  • 1
  • 2
  • 3
  • 4

3.5 设置SQL打印日志

#打印SQL日志
logging.level.cn.wolfcode.crm.mapper=trace
  • 1
  • 2

四、添加事务管理

4.1 准备依赖

<!-- 支持使用 Spring AOP 和 AspectJ 进行切面编程。 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  1. XML方式(了解)
    采取配置类和XML混用的策略, 在配置类上使用@ImportResource(“classpath:spring-tx.xml”)。

  2. 注解方式
    直接在业务层实现类上或者其方法上直接贴@Transactional注解即可。

#SpringBoot默认优先选择CGLIB代理,如果需要改为优先使用JDK代理,需要做以下配置
#spring.aop.proxy-target-class=false #优先使用JDK代理
  • 1
  • 2

SpringBoot 自动配置中提供了TransactionAutoConfiguration事务注解自动配置类 , 引入了事务的依赖后, 可直接使用@Transactional注解 。


五、静态资源处理

  1. 默认情况下,Springboot会从classpath下的 /static , /public , /resources , /META-INF/resources下加载静态资源;

  2. 可以在application.properties中配置spring.resources.staticLocations属性来修改静态资源加载地址;

  3. 因为应用是打成jar包,所以之前的src/main/webapp就作废了,如果有文件上传,那么就的必须去配置图片所在的路径;


六、集成FreeMarker

6.1 准备依赖

<!-- SpringBoot集成FreeMarker的依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

6.2 配置资源文件

#一般我们会做3个配置,其余默认即可
#暴露session对象的属性
spring.freemarker.expose-session-attributes=true
#配置为传统模式,空值自动处理
spring.freemarker.settings.classic_compatible=true
#重新指定模板文件后缀 springboot 2.2.x 后 默认后缀为 .ftlh
spring.freemarker.suffix=.ftl
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

6.3 常见配置属性

spring.freemarker.enabled=true: 是否开启freemarker支持
spring.freemarker.charset=UTF-8: 模板编码
spring.freemarker.content-type=text/html: 模板contenttype
spring.freemarker.expose-session-attributes: 是否开启session属性暴露,默认false
spring.freemarker.prefix: 加载模板时候的前缀
spring.freemarker.settings.*: 直接配置freemarker参数
spring.freemarker.suffix: 模板文件后缀
spring.freemarker.template-loader-path=classpath:/templates/: 模板加载地址
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

七、统一异常处理

7.1 框架自带方式

SpringBoot默认情况下,会把所有错误都交给BasicErrorController类完成处理,错误的视图导向到 classpath:/static/error/ 和 classpath:/templates/error/ 路径上,http状态码就是默认视图的名称

如: 出现404错误 -> classpath:/static/error/404.html 或者 出现5xx类错误 -> classpath:/static/error/5xx.html

7.2 控制器增强器方式

自己定义一个控制器增强器,专门用于统一异常处理,该方式一般用于5xx类错误

@ControllerAdvice //控制器增强器
public class ExceptionControllerAdvice {
    @ExceptionHandler(RuntimeException.class) //处理什么类型的异常
    public String handlException(RuntimeException e, Model model) {
        return "errorView"; //错误页面视图名称
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

八、添加拦截器

8.1 自定义拦截器

@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String url = request.getRequestURI();
        if (url.contains("/employee")) {
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write("请先登录");
            return false;
        }
        return true;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

8.2 注册拦截器

声明一个配置类, 实现WebMvcConfigurer接口 ,在addInterceptors方法注册拦截器

@SpringBootApplication
// mybatis 中 mapper 接口扫描器,指定参数为:mapper 接口所在路径
// 功能:将包中路径下所有接口动态代理,创建 mapper 接口实现类交给 spring 容器管理
@MapperScan(basePackages = "com.yy.springboot.mapper")
public class MvcJavaConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    @Autowired
    private PermissionInterceptor permissionInterceptor;

    public void addInterceptors(InterceptorRegistry registry) {
        // 注册登录拦截器
        registry.addInterceptor(loginInterceptor)
            // 对哪些资源起过滤作用
            .addPathPatterns("/**")
            // 对哪些资源起排除作用
            .excludePathPatterns("/loginUser","/login.html","/css/**","/js/**");
        
    }
    
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

九、添加系统日志

9.1 SpringBoot中的日志介绍

  1. Springboot默认已经开启日志

默认的日志格式为: 时间 日志级别 线程ID 线程名称 日志类 日志说明;

  1. Springboot的日志分为: 系统日志和应用日志;

  2. 日志级别,设置的级别越高,输出的内容越少, 如果设置的级别为info, 则debug以及trace级别的都无法显示
    trace < debug < info < warn < error

  3. Springboot默认选择Logback作为日志框架,也能选择其他日志框架,但是没有必要
    common-logging / java-logging / log4j / log4j2 / logback / slf4j;

  4. SpringBoot 默认日志级别是 info,因为 debug、trace 低于 info 级别,所以不会显示,除非主动配置

9.2 类中使用日志输出

方式1: 在类中定义一个静态Logger对象

这里传入当前类的作用是方便输出日志时可以清晰地看到该日志信息是属于哪个类的(导入的包是 org.slf4j)

private static final Logger log = LoggerFactory.getLogger(当前类.class);
  • 1

方式2: 使用lombok提供的@Slf4j注解来简化代码 , 其实和方式1的作用是一样的

@Slf4j
@Service
public class PermissionServiceImpl implements IPermissionService {}
  • 1
  • 2
  • 3

在需要输出日志的地方使用日志的输出方法(一般我们在 CRUD 操作前后进行日志信息输出,error 一般在 catch 中输出)

log.info(...);
log.error(...);
...
//输出日志中有变量可以使用{}作为占位符
log.info("删除id为{}的数据", id);
  • 1
  • 2
  • 3
  • 4
  • 5

十、逆向工程

10.1 导入逆向工程插件

<build>
    <plugins>
        <!-- MyBatis 逆向工程插件 -->
        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.2</version>
            <configuration>
                <verbose>true</verbose>
                <overwrite>false</overwrite>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>5.1.45</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

10.2 generatorConfig.xml 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
		PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
		"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- 配置生成器 -->
<generatorConfiguration>

	<context id="mysql" defaultModelType="hierarchical"
			 targetRuntime="MyBatis3Simple">

		<!-- 自动识别数据库关键字,默认false,如果设置为true,根据SqlReservedWords中定义的关键字列表; 一般保留默认值,遇到数据库关键字(Java关键字),使用columnOverride覆盖 -->
		<property name="autoDelimitKeywords" value="false" />
		<!-- 生成的Java文件的编码 -->
		<property name="javaFileEncoding" value="UTF-8" />
		<!-- 格式化java代码 -->
		<property name="javaFormatter"
				  value="org.mybatis.generator.api.dom.DefaultJavaFormatter" />
		<!-- 格式化XML代码 -->
		<property name="xmlFormatter"
				  value="org.mybatis.generator.api.dom.DefaultXmlFormatter" />

		<!-- beginningDelimiter和endingDelimiter:指明数据库的用于标记数据库对象名的符号,比如ORACLE就是双引号,MYSQL默认是`反引号; -->
		<property name="beginningDelimiter" value="`" />
		<property name="endingDelimiter" value="`" />

		<commentGenerator>
			<property name="suppressDate" value="true" />
			<property name="suppressAllComments" value="true" />
		</commentGenerator>

		<!-- 必须要有的,使用这个配置链接数据库 @TODO:是否可以扩展 -->
		<jdbcConnection driverClass="com.mysql.jdbc.Driver"
						connectionURL="jdbc:mysql:///car" userId="root" password="admin">
			<!-- 这里面可以设置property属性,每一个property属性都设置到配置的Driver上 -->
		</jdbcConnection>

		<!-- java类型处理器 用于处理DB中的类型到Java中的类型,默认使用JavaTypeResolverDefaultImpl; 注意一点,默认会先尝试使用Integer,Long,Short等来对应DECIMAL和 
			NUMERIC数据类型; -->
		<javaTypeResolver
				type="org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl">
			<!-- true:使用BigDecimal对应DECIMAL和 NUMERIC数据类型 false:默认, scale>0;length>18:使用BigDecimal; 
				scale=0;length[10,18]:使用Long; scale=0;length[5,9]:使用Integer; scale=0;length<5:使用Short; -->
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver>


		<!-- java模型创建器,是必须要的元素 负责:1,key类(见context的defaultModelType);2,java类;3,查询类 
			targetPackage:生成的类要放的包,真实的包受enableSubPackages属性控制; targetProject:目标项目,指定一个存在的目录下,生成的内容会放到指定目录中,如果目录不存在,MBG不会自动建目录 -->
		<!-- TODO -->
		<javaModelGenerator targetPackage="com.yy.homework.domain"
							targetProject="src/main/java">
			<!-- for MyBatis3/MyBatis3Simple 自动为每一个生成的类创建一个构造方法,构造方法包含了所有的field;而不是使用setter; -->
			<property name="constructorBased" value="false" />

			<!-- for MyBatis3 / MyBatis3Simple 是否创建一个不可变的类,如果为true, 那么MBG会创建一个没有setter方法的类,取而代之的是类似constructorBased的类 -->
			<property name="immutable" value="false" />

			<!-- 设置是否在getter方法中,对String类型字段调用trim()方法
			<property name="trimStrings" value="true" /> -->
		</javaModelGenerator>

		<!-- 生成SQL map的XML文件生成器, 注意,在Mybatis3之后,我们可以使用mapper.xml文件+Mapper接口(或者不用mapper接口),
			或者只使用Mapper接口+Annotation,所以,如果 javaClientGenerator配置中配置了需要生成XML的话,这个元素就必须配置
			targetPackage/targetProject:同javaModelGenerator -->
		<!-- TODO -->
		<sqlMapGenerator targetPackage="com.yy.homework.mapper"
						 targetProject="src/main/resources">
			<!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
			<property name="enableSubPackages" value="true" />
		</sqlMapGenerator>


		<!-- 对于mybatis来说,即生成Mapper接口,注意,如果没有配置该元素,那么默认不会生成Mapper接口 targetPackage/targetProject:同javaModelGenerator
			type:选择怎么生成mapper接口(在MyBatis3/MyBatis3Simple下): 1,ANNOTATEDMAPPER:会生成使用Mapper接口+Annotation的方式创建(SQL生成在annotation中),不会生成对应的XML;
			2,MIXEDMAPPER:使用混合配置,会生成Mapper接口,并适当添加合适的Annotation,但是XML会生成在XML中; 3,XMLMAPPER:会生成Mapper接口,接口完全依赖XML;
			注意,如果context是MyBatis3Simple:只支持ANNOTATEDMAPPER和XMLMAPPER -->
		<!-- TODO -->
		<javaClientGenerator targetPackage="com.yy.homework.mapper"
							 type="XMLMAPPER" targetProject="src/main/java">
			<!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
			<property name="enableSubPackages" value="true" />

			<!-- 可以为所有生成的接口添加一个父接口,但是MBG只负责生成,不负责检查 <property name="rootInterface"
				value=""/> -->
		</javaClientGenerator>

		<!-- TODO -->
		<table tableName="message_reply">
			<property name="useActualColumnNames" value="false"/>
			<property name="constructorBased" value="false" />
			<generatedKey column="id" sqlStatement="JDBC" />
		</table>
	</context>
</generatorConfiguration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

十一、分页查询

11.1 导入依赖

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.3.0</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

11.2 分页代码-EmployeeQuery

@Setter
@Getter
public class QueryObject {
    private int currentPage = 1;
    private int pageSize = 5;
}

@Setter
@Getter
public class EmployeeQuery extends QueryObject {
    private String keyword;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

11.3 分页逻辑代码

public PageInfo<Employee> query(QueryObject qo) {
    PageHelper.startPage(qo.getCurrentPage(),qo.getPageSize());
    List<Employee> employees = employeeMapper.selectForList(qo);
    return new PageInfo<>(employees);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  <sql id="where_sql">
    <where>
      <if test="keyword != null and keyword !=''">
        and (e.name like concat('%', #{keyword} ,'%') or e.email like concat('%', #{keyword} ,'%'))
    </where>
  </sql>
      
  <select id="selectForList" resultMap="BaseResultMap">
    select e.id, e.name,e.username, e.password, e.email, e.age, e.admin, e.deptId
    from employee e 
    <include refid="where_sql" />
  </select>
      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

11.4 测试

@RequestMapping("/list")
public String list(Model model, @ModelAttribute("qo") EmployeeQuery qo){
    model.addAttribute("pageInfo", employeeService.query(qo));
    return "employee/list";
}
  • 1
  • 2
  • 3
  • 4
  • 5

总结

以上就是 SpringBoot 项目搭建的介绍了,代码仅供参考,欢迎讨论交流。
SpringBoot 项目入门请看我上一篇博客,博客地址:SpringBoot快速入门(解析+入门案例源码实现)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/125590
推荐阅读
相关标签
  

闽ICP备14008679号