文章目录
SpringBoot基础入门
1 创建SpringBoot项目
1.1 通过pom继承parent
通过parent标签指定pom项目的父工程
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ali</groupId>
<artifactId>springBoot_test_01</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
创建controller及启动类
controller层:
package com.zi.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class FirstController {
@ResponseBody
@RequestMapping("/first")
public String firstController(){
return "hello SpringBoot...";
}
}
package com.zi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
启动类需要与controller层、service层等包同层级【SpringBoot默认扫描启动类所在包及其子包】
1.2 通过依赖管理导入SpringBoot依赖【dependencyManagement】
在工作中我们有可能遇到我们的maven项目已经要继承一个parent项目了,此时应该使用dependencyManagement来创建SpringBoot项目
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ali</groupId>
<artifactId>springBoot_test_01</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<!--<parent>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-parent</artifactId>-->
<!-- <version>2.5.4</version>-->
<!--</parent>-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.1</version>
</dependency>
</dependencies>
</project>
1.3 通过可视化界面
2 SpringBoot中的配置文件与资源访问
SpringBoot中的配置文件只能是以application开头【application*】
2.1 properties
# 设置端口
server.port=8081
# 设置上下文路径
server.servlet.context-path=/springboot02
2.2 yml
# yml格式的文件,区分大小写,且层级之间要有两个空格;
# 属性与值之间要留一个空格
server:
port: 8888
servlet:
context-path: /springboot02
注意:
①yml也可以配置数组或者json格式的数据;
②如果同时存在properties与yml文件,如果存在冲突,以properties为准
2.3 访问static或public资源
访问路径上不需要加/static或者/public【并且二者之间可以互相访问】
a.html代码:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<img src="logo.jpg"/>
</body>
</html>
2.4 访问templates资源
类似于JavaWeb中的WEB-INF里面的内容,属于私密内容,外界无法直接访问,只能通过内部跳转访问
【FreeMarker thymeleaf 页面所在目录 】
SpringBoot的项目结构中不同于以前的JavaWeb项目,没有webapp目录【只有需要用到jsp技术,才会有该目录】
3 SpringBoot整合MyBatis
3.1 导入jar包并创建对应包结构
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
</dependencies>
对应包结构:
3.2 创建User类
package com.zi.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User implements Serializable {
private Integer id;
private String name;
private Integer age;
private String email;
}
3.3 创建UserMapper接口与UserMapper.xml
UserMapper接口:
package com.zi.mapper;
import com.zi.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserMapper {
/**
* 查询所有用户
* @return
*/
List<User> selectAll();
}
UserMapper.xml
<?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.zi.mapper.UserMapper">
<!--List<User> selectAll();-->
<select id="selectAll" resultType="user">
select * from t_user
</select>
</mapper>
3.4 创建UserService与UserServiceImpl
UserService:
package com.zi.service;
import com.zi.pojo.User;
import java.util.List;
public interface UserService {
List<User> findAll();
}
UserServiceImpl:
package com.zi.service.impl;
import com.zi.mapper.UserMapper;
import com.zi.pojo.User;
import com.zi.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public List<User> findAll() {
return userMapper.selectAll();
}
}
3.5 创建UserController
package com.zi.controller;
import com.zi.pojo.User;
import com.zi.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@ResponseBody
@RequestMapping("/findAll")
public List<User> findAll(){
return userService.findAll();
}
}
3.6 最终结果
地址栏内容:
最终数据:
4 SpringBoot整合logback(日志)
logback的依赖,我们不需要亲自引入,spring-boot-starter或者spring-boot-starter-web中已经包含了Logback的依赖。
在resources目录下创建logback.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="${catalina.base}/logs/"/>
<!-- 控制台输出 -->
<appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志输出格式 -->
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程
名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行
符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</layout>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="RollingFile"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/server.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程
名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行
符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}
[%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
<!--日志文件最大的大小-->
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 日志输出级别 -->
<root level="info">
<appender-ref ref="Stdout"/>
<appender-ref ref="RollingFile"/>
</root>
<logger name="com.zi.mapper" level="DEBUG"/>
<!--日志异步到数据库 -->
<!--<appender name="DB"
class="ch.qos.logback.classic.db.DBAppender">
日志异步到数据库
<connectionSource
class="ch.qos.logback.core.db.DriverManagerConnectionSource">
连接池
<dataSource
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<driverClass>com.mysql.jdbc.Driver</driverClass>
<url>jdbc:mysql://127.0.0.1:3306/databaseName</url>
<user>root</user>
<password>root</password>
</dataSource>
</connectionSource>
</appender> -->
</configuration>
5 SpringBoot整合PageHelper
5.1 导入启动依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
5.2 定义EmpController
@Controller
@RequestMapping("/emp")
public class EmpController {
@Autowired
private EmpService empService;
@ResponseBody
@RequestMapping("/findByPage/{pageNum}/{pageSize}")
public List<Emp> findAll(@PathVariable("pageNum") Integer pageNum, @PathVariable("pageSize") Integer pageSize){
return empService.findByPage(pageNum, pageSize);
}
}
5.3 定义EmpMapper及EmpMapper.xml
EmpMapper:
@Mapper
public interface EmpMapper {
List<Emp> findAll();
}
EmpMapper.xml:
<?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.zi.mapper.EmpMapper">
<select id="findAll" resultType="emp">
select * from emp
</select>
</mapper>
5.4 定义EmpService及实现类
EmpService:
public interface EmpService {
List<Emp> findAll();
List<Emp> findByPage(Integer pageNum, Integer pageSize);
}
EmpServiceImpl:
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
@Override
public List<Emp> findAll() {
return empMapper.findAll();
}
@Override
public List<Emp> findByPage(Integer pageNum, Integer pageSize) {
Page<Emp> page = PageHelper.startPage(pageNum, pageSize);
List<Emp> emps = empMapper.findAll();
PageInfo<Emp> pi =new PageInfo<>(emps);
System.out.println("当前页"+pi.getPageNum());
System.out.println("总页数"+pi.getPages());
System.out.println("页大小"+pi.getSize());
System.out.println("总记录数"+pi.getTotal());
System.out.println("当前页数据"+pi.getList());
return emps;
}
}
5.5 测试
①地址栏中输入:
②响应结果:
6 SpringBoot小妙招
①注入静态变量
@Component
public class CommonUtils {
private static AdminMapper adminMapper;
private static StringRedisTemplate redisTemplate;
@Autowired
public void setProper(AdminMapper adminMapper, StringRedisTemplate redisTemplate){
CommonUtils.adminMapper = adminMapper;
CommonUtils.redisTemplate = redisTemplate;
}
②测试类自动注入失败
通过@Autowired自动注入失败
加上:@RunWith(SpringRunner.class)即可
@SpringBootTest
@RunWith(SpringRunner.class)
public class DataCountTest {
@Autowired
private DataCountMapper dataCountMapper;
@Test
public void test(){
List<DataCount> allDataCount = dataCountMapper.getAllDataCount();
System.out.println(allDataCount);
}
}
拓展(xml与JavaConfig)
Spring配置整合bean通常由两种方式:①xml ②JavaConfig(配置类+注解)
- xml方式:
@ContextConfiguration("/spring.xml")
指定配置文件位置- JavaConfig:
@ContextConfiguration(classes = SpringDataJPAConfig.class)
指定具体的配置类
例如:我们在使用Junit单元测试的时候,如果使用的是junit4
- 导入依赖
<!-- junit4 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
- 配置bean
1)通过xml方式,例如:
测试类中通过
@ContextConfiguration("/spring.xml")
指定配置文件位置,这样在测试类中才能通过@Autowired注入对应的bean
// 基于junit4 spring单元测试
//指定配置文件位置【只有指定】
@ContextConfiguration("/spring.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringdataJpaTest {
// jdk动态代理的实例
@Autowired
CustomerRepository repository;
@Test
public void testR(){
Optional<Customer> byId = repository.findById(20L);
System.out.println(byId.orElse(null));
}
}
2)通过JavaConfig(配置类+注解)
配置与上面的xml方式类似,只不过换成了代码和注解,例如:直接通过@Bean为IOC容器注入一个dataSource
SpringDataJPAConfig:
@Configuration // 标记当前类为配置类 =xml配文件
@EnableJpaRepositories(basePackages="com.zi.repositories") // 启动jpa <jpa:repositories
@EnableTransactionManagement // 开启事务
public class SpringDataJPAConfig {
/*
* <!--数据源-->
<bean class="com.alibaba.druid.pool.DruidDataSource" name="dataSource">
<property name="username" value="root"/>
<property name="password" value="123456"/>
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/springdata_jpa?characterEncoding=UTF-8"/>
</bean>
* */
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername("root");
dataSource.setPassword("123456");
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/springdata_jpa?characterEncoding=UTF-8");
return dataSource;
}
/*
* <!--EntityManagerFactory-->
<bean name="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter">
<!--Hibernate实现-->
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!--生成数据库表-->
<property name="generateDdl" value="true"></property>
<property name="showSql" value="true"></property>
</bean>
</property>
<!--设置实体类的包-->
<property name="packagesToScan" value="com.tuling.pojo"></property>
<property name="dataSource" ref="dataSource" ></property>
</bean>
* */
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setShowSql(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.zi.pojo");
factory.setDataSource(dataSource());
return factory;
}
/*
* <bean class="org.springframework.orm.jpa.JpaTransactionManager" name="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
* */
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory);
return txManager;
}
}
测试类使用:
通过
@ContextConfiguration(classes = SpringDataJPAConfig.class)
指定具体的配置类
// 基于junit4 spring单元测试
//@ContextConfiguration("/spring.xml")
@ContextConfiguration(classes = SpringDataJPAConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringdataJpaTest {
// jdk动态代理的实例
@Autowired
CustomerRepository repository;
@Test
public void testR(){
Optional<Customer> byId = repository.findById(20L);
System.out.println(byId.orElse(null));
}
}
③使用@PostMapping获取不到值
今天在测试的使用使用@PostMapping访问成功,但是却获取不到值
使用Postman测试写的接口时,发现错误,请求可以接收,但是参数为空
@RestController
@RequestMapping("/testApi")
public class CompareController {
@PostMapping("/test1")
public String getTestPost1(@RequestParam(name="id",required = false) String id, @RequestParam(name="name",required = false) String name){
System.out.println(id+name);
return "success";
}
// @PostMapping("test3")
// public String getTestPost3(String id, String name){
// System.out.println(id+name);//23jack 【x-www-form-urlencoded】
// return "success";
// }
@PostMapping("/test2")
public String getTestPost2(@RequestBody UserInfo userInfo){
System.out.println(userInfo.toString());
return "success";
}
@Data
public class UserInfo {
private String id;
private String name;
}
}
- 调用第一个接口,请求成功,始终拿不到值,Postman请求参数
将 Postman 的传参改为 x-www-form-urlencoded 就可以了。
是因为 @RequestParam 接受JSON时,PostMan的body应选择 x-www-form-urlencoded ,否则使用 json 格式,会导致数据为 null,正确做法:
- 调用第二个接口,提示如下
:non-static inner classes like this can only by instantiated using default,
no-argument constructor
json转内部类对象时出错。像这样的非静态内部类只能通过使用默认的无参数构造函数实例化
因此会导致,请求成功了,但是参数信息没有发送过来。
将 非静态内部类转为静态内部类,添加 static 关键字即可。
@Data
public static class UserInfo {
private String id;
private String name;
}
④测试@Value注解
@SpringBootApplication
public class ContentApplication {
@Value("${test_config.a}")
String a;
@Value("${test_config.b}")
String b;
@Value("${test_config.c}")
String c;
@Value("${test_config.d}")
String d;
@Bean
public Integer getTest(){
System.out.println("a="+a);
System.out.println("b="+b);
System.out.println("c="+c);
System.out.println("d="+d);
return new Integer(1);
}
public static void main(String[] args) {
SpringApplication.run(ContentApplication.class, args);
}
}
springboot项目下的测试包:
@SpringBootTest
class XcPlusContentServiceApplicationTests {
@Autowired
private CourseBaseMapper courseBaseMapper;
@Test
void contextLoads() {
CourseBase courseBase = courseBaseMapper.selectById(22);
System.out.println(courseBase);
}
}
如果要引用bean,可以直接复制一个application启动类过来
⑤修改启动banner图片
直接修改配置文件即可,Spring2已经支持了图片
# banner图标设置
spring.banner.image.location=classpath:banner.jpg
参考文章
https://blog.csdn.net/qq_41610498/article/details/120845672