Gitee地址
Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化老的Spring 应用开发。该框架
使用了自动方式来进行配置,减少开发人员定义配置复杂度。
SpringBoot 支持如下的嵌入式Servlet容器,Spring Boot应用程序最低支持到Servlet 3.1的容器。
这里使用多模块工程来进行演示
使用maven构建一个父工程spring-boot
添加springboot依赖
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.4.RELEASEversion>
parent>
<properties>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
使用maven构建一个子模块工程 spring-boot-helloworld 继承父模块工程 spring-boot,工程结构如下:
在父包com.iweb下创建启动类 HelloWorldApplication
/**
* 南京艾瑞
* 作者: jack
* 时间: 2020-06-29 21:07
* 描述: WebApplication
*/
@SpringBootApplication
public class HelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldApplication.class);
}
}
在resources下创建springboot核心配置文件application.yml,可以不需要配置任何参数,基本参数都有默认值
server:
port: 8080
编写控制器
/**
* 南京艾瑞
* 作者: jack
* 时间: 2020-06-29 21:07
* 描述: UserController
*/
@RestController
public class UserController {
@RequestMapping("hello")
public String hello(String name) {
System.out.println(name);
return "hello:" + name;
}
}
启动工程:执行启动类HelloWorldApplication的main方法即可
测试访问
starters是依赖关系的整理和封装。是一套依赖坐标的整合,可以让导入应用开发的依赖坐标更方便。
有了这些Starters,你获得Spring和其整合的所有技术的一站式服务。无需配置、无需复制粘贴依赖坐
标,一个坐标即可完成所有入门级别操作。举例:JPA or Web开发,只需要导入 spring-bootstarter-data-jpa 或 spring-boot-starter-web 。
spring boot starts常用参考地址
我们知道SpringBoot是基于约定的,所以很多配置都有默认值。如果想修改默认配置,可以使用
application.properties或application.yml(application.yaml)自定义配置。SpringBoot默认从Resource
目录加载自定义配置文件。application.properties是键值对类型(一直在用)。application.yml是
SpringBoot中一种新的配置文件方式。
YML文件格式是YAML(YAML Aint Markup Language)编写的文件格式。可以直观被电脑识别的格式。
容易阅读,容易与脚本语言交互。可以支持各种编程语言(C/C++、Ruby、Python、Java、Perl、C#、
PHP)。以数据为核心,比XML更简洁。扩展名为.yml或.yaml
spring boot 配置信息参考地址
spring boot内部使用Commons Logging来记录日志,但也保留外部接口可以让一些日志框架来进行实现,例如Java Util Logging,Log4J2还有Logback。如果你想用某一种日志框架来进行实现的话,就必须先配置,默认情况下,spring boot使用Logback作为日志实现的框架。
我们还可以在classpath路径下,通过定义具体的日志文件来配置——logback.xml。
参考工程:spring-boot-log
添加依赖
<dependencies>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-classicartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
dependencies>
lombok是为了方便打印日志
<configuration debug="false">
<property name="LOG_HOME" value="D:\\log"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
encoder>
appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/access.log.%d{yyyy-MM-dd}.logFileNamePattern>
<MaxHistory>30MaxHistory>
rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
encoder>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MBMaxFileSize>
triggeringPolicy>
appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
root>
configuration>
控制器代码
/**
* 南京艾瑞
* 作者: jack
* 时间: 2020-06-29 11:27
* 描述: UserController
*/
@Slf4j
@RestController
public class UserController {
@GetMapping("hello")
public String hello(String name) {
log.info(name);
return "hello:" + name;
}
}
测试:
Spring boot默认是支持thymeleaf模板,如果需要使用jsp需要手动添加
参考工程:spring-boot-jsp
基本配置就不说了,添加jsp的依赖
<dependencies>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-classicartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-tomcatartifactId>
dependency>
<dependency>
<groupId>org.apache.tomcat.embedgroupId>
<artifactId>tomcat-embed-jasperartifactId>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
dependency>
dependencies>
success.jsp代码
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<h1>successh1>
body>
html>
控制器代码
@Controller
public class UserController {
@GetMapping("hello")
public String hello() {
System.out.println("hello");
return "success";
}
}
application.properties配置
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
GlobalConfig这个文件如果是单个工程就不需要了,只有子模块工程需要
@Configuration
public class GlobalConfig {
// 整合JSP子模块工程
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> customizer() {
return (factory) -> {
factory.addContextCustomizers((context) -> { //模块中webapp相对路径
//你子项目的module名称,而不是你修改的application name这点需要注意;
String relativePath = "spring-boot-jsp/src/main/webapp";
File docBaseFile = new File(relativePath); // 如果路径不存在,则把这个路径加入进去
if (docBaseFile.exists()) {
context.setDocBase(docBaseFile.getAbsolutePath());
}
});
};
}
}
简单说, Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP
参考工程: spring-boot-thymeleaf
添加依赖
<dependencies>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-classicartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
<groupId>net.sourceforge.nekohtmlgroupId>
<artifactId>nekohtmlartifactId>
<version>1.9.22version>
dependency>
dependencies>
application.yml配置
spring:
thymeleaf:
prefix: classpath:/templates/
suffix: .html
# 默认值是HTML,其实是一个很严格的检查,改为LEGACYHTML5可以得到一个可能更友好亲切的格式要求
# LEGACYHTML5需要搭配一个额外的库NekoHTML才可用
mode: LEGACYHTML5
cache: false
encoding: UTF-8
控制器代码
@Controller
public class UserController {
@GetMapping("hello")
public ModelAndView hello(String name, Model model) {
System.out.println(name);
// 模拟一个list返回页面
List<String> list = new ArrayList<>();
list.add("AA");
list.add("BB");
list.add("CC");
model.addAttribute("list", list);
return new ModelAndView("success", "model", model);
}
}
在templates下创建success.html
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<h1>successh1>
<div th:each="its,iterStat:${model.list}">
<p th:text="${its}">p>
div>
body>
html>
<p th:text="${index}">p>
<p th:text="*{index}">p>
<div th:object="${user}">
<p th:text="${user.username}">p>
<p th:text="*{username}">p>
div>
<p th:inline="text">[[${index}]] 88888p>
<p th:inline="text">[[${index}]] 88888p>
<script th:inline="javascript">
console.log([[${index}]])
script>
<a th:href="@{order(id=${id})}">indexa>
<div th:each="its,iterStat:${list}">
<p th:text="${its}">p>
div>
<div th:include="copy::copy">div>
<div th:replace="copy::copy">div>
参考工程:spring-boot-ssm
<properties>
<swagger.version>2.9.2swagger.version>
properties>
<dependencies>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-classicartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.10version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.1.0version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
<version>${swagger.version}version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
<version>${swagger.version}version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-generatorartifactId>
<version>3.1.0version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.apache.velocitygroupId>
<artifactId>velocity-engine-coreartifactId>
<version>2.0version>
<scope>testscope>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<scope>testscope>
dependency>
dependencies>
编写启动类
@SpringBootApplication
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class);
}
}
application.yml配置
server:
port: 8080
# servlet:
# context-path: /
spring:
application:
name: ssm
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.100.101:3306/dbcp?useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.iweb.model
global-config:
db-config:
id-type: id_worker_str # 分布式全局唯一id
configuration:
map-underscore-to-camel-case: false # 驼峰是否转下划线
cache-enabled: true # 全局缓存开关
lazy-loading-enabled: true # 延迟加载
multiple-result-sets-enabled: true # 开启延时加载,否则按需加载 属性
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印sql语句
使用mybatis plus生成 mapper.xml、model、mapper接口,这里取消了 controller和service的生成,自己来完成代码的编写
MyBatisGenerate类代码(根据自己的实际情况修改)
package com.iweb;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class MyBatisGenerate {
@Test
public void generate() {
String url = "jdbc:mysql://192.168.100.101:3306/dbcp?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull";
// 基本包
String parentPackage = "com.iweb";
String baseDir = System.getProperty("user.dir");
String driverClassName = "com.mysql.cj.jdbc.Driver";
String username = "root";
String password = "123456";
// 表 前缀
String[] tablePrefix = new String[]{"tb_"};
String[] tableNames = new String[]{"tb_user"};
/*数据源*/
DataSourceConfig dsc = new DataSourceConfig();
dsc.setDbType(DbType.MYSQL);
dsc.setUrl(url);
dsc.setDriverName(driverClassName);
dsc.setUsername(username);
dsc.setPassword(password);
/*全局配置*/
GlobalConfig gc = new GlobalConfig();
gc.setOutputDir(baseDir + "/src/main/java");
gc.setFileOverride(true);
gc.setActiveRecord(true);
gc.setEnableCache(false);// XML 二级缓存
gc.setBaseResultMap(true);// XML ResultMap
gc.setBaseColumnList(true);// XML columList
gc.setAuthor("jack");
gc.setMapperName("%sMapper");
gc.setXmlName("%sMapper");
gc.setServiceName("%sService");
gc.setServiceImplName("%sServiceImpl");
gc.setControllerName("%sController");
/*生成策略*/
StrategyConfig strategy = new StrategyConfig();
strategy.setTablePrefix(tablePrefix);// 此处可以修改为您的表前缀
strategy.setNaming(NamingStrategy.underline_to_camel);// 字段名生成策略
strategy.setInclude(tableNames); // 需要生成的表
strategy.setEntityLombokModel(true);
strategy.setEntityTableFieldAnnotationEnable(true);
/*生成文件包配置*/
PackageConfig pc = new PackageConfig();
pc.setParent(parentPackage);
pc.setController("controller");
pc.setService("service");
pc.setServiceImpl("service.impl");
pc.setEntity("model");
pc.setMapper("mapper");
AutoGenerator mpg = new AutoGenerator();
/*xml文件配置*/
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// nothing
}
};
//xml生成路径
List<FileOutConfig> focList = new ArrayList<>();
focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return baseDir + "/src/main/resources/" + "/mapper/" + tableInfo.getEntityName() + "Mapper.xml";
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
// 关闭默认 xml 生成,调整生成 至 根目录
TemplateConfig tc = new TemplateConfig();
tc.setXml(null);
tc.setController(""); // 禁止生成controller
tc.setService("");
tc.setServiceImpl("");
mpg.setDataSource(dsc); //数据源配置
mpg.setGlobalConfig(gc); //全局配置
mpg.setStrategy(strategy); //生成策略配置
mpg.setPackageInfo(pc); //包配置
mpg.setCfg(cfg); //xml配置
mpg.setTemplate(tc); //
// 执行生成
mpg.execute();
}
}
配置配置类
MyBatisConfig
@Configuration
@MapperScan("com.iweb.mapper")
public class MyBatisConfig {
// 配置分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
AppConfig
@EnableTransactionManagement
@Configuration
public class AppConfig {
}
SwaggerConfig
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.pathMapping("/")// 请求的路径
.select()
.apis(RequestHandlerSelectors.basePackage("com.iweb"))
.paths(PathSelectors.any())
.build().apiInfo(new ApiInfoBuilder()
.title("项目统一接口")
.description("微服务restful接口")
.version("1.0")
.contact(new Contact("jack", "https://www.baidu.com", "[email protected]"))
.license("南京艾瑞职业培训学校")
.licenseUrl("http://www.baidu.com")
.build());
}
}
控制器代码
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
// 查询所有的用户
@GetMapping
public List<User> findAll() {
List<User> users = userService.findAll();
return users;
}
// 更具id查询
@GetMapping("{id}")
public User findById(@PathVariable String id) {
User user = userService.findById(id);
return user;
}
// 更具id修改
@ApiOperation("根据id修改用户")
@PutMapping("{id}")
public User updateById(@PathVariable String id, @RequestBody User user) {
user.setId(id);
User dataUser = userService.updateById(user);
return dataUser;
}
// 根据id删除
@DeleteMapping("{id}")
public Object deleteById(@PathVariable String id) {
userService.deleteById(id);
return null;
}
// 新增用户
@PostMapping
public User addUser(@RequestBody User user) {
user = userService.addUser(user);
return user;
}
// 分页
@GetMapping("{current}/{size}")
public List<User> findUsersByPage(@PathVariable Integer current, @PathVariable Integer size) {
List<User> users = userService.findUsersByPage(current, size);
return users;
}
// 条件查询
@PostMapping("findByUser")
public List<User> findByUser(@RequestBody User user) {
List<User> users = userService.findByUser(user);
return users;
}
}
服务层代码
@Service
public class UserService {
@Resource
private UserMapper userMapper;
public List<User> findAll() {
return userMapper.selectList(null);
}
public User findById(String id) {
return userMapper.selectById(id);
}
public User updateById(User user) {
userMapper.updateById(user);
return userMapper.selectById(user.getId());
}
public void deleteById(String id) {
userMapper.deleteById(id);
}
@Transactional(rollbackFor = RuntimeException.class)
public User addUser(User user) {
// id使用分布式唯一id
userMapper.insert(user);
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username", user.getUsername());
Integer count = userMapper.selectCount(queryWrapper);
if (count > 1) {
throw new RuntimeException("用户重复");
}
return user;
}
public List<User> findUsersByPage(Integer current, Integer size) {
IPage<User> page = new Page<>(current, size);
IPage<User> userIPage = userMapper.selectPage(page, null);
System.out.println("总条数:" + userIPage.getTotal());
return userIPage.getRecords();
}
public List<User> findByUser(User user) {
Wrapper<User> queryWrapper = new QueryWrapper<>(user);
// 非 == 比较
// QueryWrapper queryWrapper = new QueryWrapper<>();
// queryWrapper.like("数据库的列名", user.getPassword());
List<User> users = userMapper.selectList(queryWrapper);
return users;
}
}
测试统一使用postman测试,这里不截图了。这里除了简单的增删改查测试还有一个事务的回滚测试。