1.SpringBoot日志支持
1.1市面上常见日志框架:
1.SpringBoot中底层使用SLF4J来做门面,实现层默认是Logback,这里推荐使用log4j2来做实现。要想使用log4j2就必须先导入包。
首先在pom中导入log4j2的包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
2.接着使用exclusions排除SpringBoot默认的日志支持
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!--排除logback-->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
这部操作做完,导包操作即完成
3.在resources文件夹中创建log4j2的配置文件log4j2-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="WARN" monitorInterval="30">
<!--先定义所有的appender-->
<appenders>
<!--这个输出控制台的配置-->
<console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式-->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
</console>
<!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
<File name="log" fileName="log/test.log" append="false">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
<!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log"
filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<RollingFile name="RollingFileWarn" fileName="${sys:user.home}/logs/warn.log"
filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
<DefaultRolloverStrategy max="20"/>
</RollingFile>
<RollingFile name="RollingFileError" fileName="${sys:user.home}/logs/error.log"
filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
</appenders>
<!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
<loggers>
<!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
<logger name="org.springframework" level="INFO"></logger>
<logger name="org.mybatis" level="INFO"></logger>
<root level="all">
<appender-ref ref="Console"/>
<appender-ref ref="log"/>
<appender-ref ref="RollingFileInfo"/>
<appender-ref ref="RollingFileWarn"/>
<appender-ref ref="RollingFileError"/>
</root>
</loggers>
</configuration>
用户可根据自己需要自行设置日志等级与开发环境
及日志的输出位置
4.用户若想测试日志的输出结果,写一个测试类,获取logger即可
@RestController
public class HelloController {
Logger logger = LoggerFactory.getLogger(this.getClass());
@RequestMapping("/hello")
public String hello(){
logger.trace("trace");
logger.debug("debug");
logger.info("info");
logger.warn("warn");
logger.error("error");
return "HelloSpringboot";
}
}
2.SpringBoot整合SpringMVC
2.1返回json形式
下面依次最原始的为返回的字符串,对象以及数组形式
package com.penny.springboot05.controller;
import com.penny.springboot05.domain.Person;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@Controller
@RequestMapping("/json01")
public class JsonController01 {
/**
* 返回字符串
* @return
*/
@RequestMapping("/str")
@ResponseBody
public String str(){
return "i'm string";
}
/**
* 返回对象
* @return
*/
@RequestMapping("/obj")
@ResponseBody
public Person obj(){
Person zz = new Person(1L, "zz");
zz.setDate(new Date());
return zz;
}
/**
* 返回数组
* @return
*/
@RequestMapping("/arr")
@ResponseBody
public List<Person> arr(){
return Arrays.asList(new Person(2L,"cc"),new Person(3L,"bb"));
}
}
但每个方法上都要写@ResponseBody显得过于繁琐笨重,于是SpringBoot提供了一个组合注解@RestController,此注解是由@Controller+@ResponseBody组合而成的。以后只需在类上加上该注解,即可返回json格式的数据
package com.penny.springboot05.controller;
import com.penny.springboot05.domain.Person;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@RestController
@RequestMapping("/json02")
public class JsonController02 {
/**
* 返回字符串
* @return
*/
@RequestMapping("/str")
public String str(){
return "i'm string";
}
/**
* 返回对象
* @return
*/
@RequestMapping("/obj")
public Person obj(){
Person zz = new Person(1L, "zz");
zz.setDate(new Date());
return zz;
}
/**
* 返回数组
* @return
*/
@RequestMapping("/arr")
public List<Person> arr(){
return Arrays.asList(new Person(2L,"cc"),new Person(3L,"bb"));
}
}
}
2.2返回页面形式
在页面返回上,SpringBoot推荐使用Thymeleaf模板引擎,不推荐使用jsp。
要想使用Thymeleaf,首先就得导入它的包。
首先在pom中导入如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
然后将thymeleaft的版本切换至如下:
<properties>
<!--切换thymeleaf版本-->
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
<!-- 布局功能的支持程序 thymeleaf3主程序 layout2以上版本 -->
<!-- thymeleaf2 layout1-->
<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
</properties>
随后即可使用。
创建一个thymeleaft页面,他们默认都是.html结尾的。并且,所有的页面文件都是放在resources下的templates文件夹中,只要在该文件夹下创建thymeleaft模板,SpringBoot就会自动读取它。
<!DOCTYPE html>
<!--导入命名空间 -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>成功!</h1>
<!--使用语法th:text 将div里面的文本内容设置为 -->
<div th:text="${hello}">这是显示欢迎信息</div>
</body>
</html>
此处仅创建一个简单的模板,至于thymeleaft具体的语法详情,可参照该篇帖子
创建完页面后,再提供一个页面跳转的接口
@Controller
public class HelloController {
@RequestMapping("/hello")
public String hello(Model model){
model.addAttribute("hello","yhptest");
return "hello";
}
}
随后启动SpringBoot后,在浏览器输入/hello即可看到页面效果
如果想在页面里面引入像jquery等前端框架,只需要在pom文件里加上如下
<!--引入jquery-webjar 在访问的时候只需要写webjars下面资源的名称即可-->
<dependency>
<groupId>org.webjars.bower</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1</version>
</dependency>
然后在页面文件里按此格式引入即可
<!DOCTYPE html>
<!--导入命名空间 -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>入门thymeleaf</title>
<!-- 引入js-->
<script th:src="@{/webjars/jquery/3.3.1/dist/jquery.js}"></script>
<script>
alert($);
</script>
</head>
<body>
<!--jquery juquery.js-->
<h1>成功!</h1>
<!--使用语法th:text 将div里面的文本内容设置为 -->
<div th:text="${msg}">欢迎欢迎~</div>
</body>
</html>
2.3静态资源
在SpringBoot中,所有静态文件资源都放在一个统一的文件夹下进行管理,官方推荐以下几种方法:
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
"/":当前项目的根路径
这里我就拿static举例
只要是放在resources下static下的静态资源,都可以在浏览器里输入资源地址直接进行访问 。
2.4SpringMVC自动配置
SpringBoot对SpringMVC已经是自动配置好了的。但如果我们想对其进行个性化支持,只需创建一个配置类,让它继承WebMvcConfigurerAdapter类,然后覆写其中的方法即可。
比如我想个性化控制视图解析器跳转,只需在该配置类中,通过继承WebMvcConfigurerAdapter,覆写addViewControllers方法即可。
@Configuration
//@EnableWebMvc 开启后则取消mvc自动配置,改为手动
public class MymvcConfig extends WebMvcConfigurerAdapter {
//跳转页面用
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/hello").setViewName("hello");
}
}
}
当然,在该配置类中,也可以进行拦截拓展配置。
比如手动创建一个拦截
package com.penny.springboot05.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class LoginInterceptor implements HandlerInterceptor {
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("post....");
}
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("pre....");
return true;
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
然后在之前创建的配置类中,通过调用addInterceptors方法就能拓展拦截器了
@Configuration
//@EnableWebMvc 开启后则取消mvc自动配置,改为手动
public class MymvcConfig extends WebMvcConfigurerAdapter {
@Autowired
private LoginInterceptor loginInterceptor;
//拓展拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
}
}
这里注意一点,如果加了@EnableWebMvc 该注解,SpringBoot的SpringMVC自动配置就会失效,千万注意!!!
3.SpringBoot整合Mybatis
要想使用mybatis,首先在pom中导入包
<!-- mysql 数据库驱动. -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
随后在applicaion,yml中配置数据库连接相关操作
server:
port: 80
spring:
datasource:
url: jdbc:mysql:///springboottest
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
mybatis:
type-aliases-package: com.penny.springboot06.domain,com.penny.springboot06.query
此处type-aliases-package:是简化包名用的。这里只要配置了以后,xml中就不用再写全限定名的类了。
随后一次创建mapper,mapper.xml,service,做测试即可。
mapper层:
package com.penny.springboot06.mapper;
import com.penny.springboot06.domain.User;
import java.util.List;
public interface UserMapper {
/**
* 新增一条数据
* @param u
*/
void save(User u);
/**
* 查询所有数据
* @return
*/
List<User> findAll();
}
service层:
package com.penny.springboot06.service;
import com.penny.springboot06.domain.User;
import java.util.List;
public interface UserService {
/**
* 新增一条数据
* @param u
*/
void save(User u);
/**
* 查询所有数据
* @return
*/
List<User> findAll();
}
service实现层:
package com.penny.springboot06.service.impl;
import com.penny.springboot06.domain.User;
import com.penny.springboot06.mapper.UserMapper;
import com.penny.springboot06.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;
public void save(User u) {
userMapper.save(u);
}
public List<User> findAll() {
return userMapper.findAll();
}
}
mapper.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.penny.springboot06.mapper.UserMapper">
<insert id="save" parameterType="User" useGeneratedKeys="true"
keyColumn="id"
keyProperty="id">
insert into t_user(name) values(#{name})
</insert>
<select id="findAll" resultType="com.penny.springboot06.domain.User">
select * from t_user
</select>
</mapper>
值得注意的是,mapper与mapper.xml文件编译后一定要在同一文件夹下,否则程序将会报错
最后,在SpringBoot启动类上,加上@MapperScan注解,扫描你的mapper所在包即可
@SpringBootApplication
@MapperScan("com.penny.springboot06.mapper")
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
当然,SpringBoot整合的Mybatis拥有更加简便的分页功能系统,从此以后再也不用谢limit语句,只需在pom中导入该分页插件
<!-- 分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.0</version>
</dependency>
然后创建一个配置类,直接复制如下代码
package com.penny.springboot07.config;
import com.github.pagehelper.PageHelper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
@Configuration
public class MyBatisConfiguration {
@Bean
public PageHelper pageHelper() {
System.out.println("MyBatisConfiguration.pageHelper()");
PageHelper pageHelper = new PageHelper();
Properties p = new Properties();
p.setProperty("offsetAsPageNum", "true");
p.setProperty("rowBoundsWithCount", "true");
p.setProperty("reasonable", "true");
pageHelper.setProperties(p);
return pageHelper;
}
}
然后在sservice实现层需要分页的方法上输入PageHelper,接下来便可使用里面的所有方法
public List<User> findAll() {
PageHelper.startPage(0, 5);
return userMapper.findAll();
}
在做一些比较简单的sql时,用于测试sql语句是否能够正常运行,也可以使用注解的方式测试
public interface UserMapper {
/**
* 新增一条数据
* @param u
*/
@Insert("insert into t_user (name) values(#{name})")
@Options(useGeneratedKeys = true,keyColumn = "id",keyProperty = "id")
void save(User u);
/**
* 查询所有数据
* @return
*/
@Select("select * from t_user")
List<User> findAll();
这里仅测试环境使用,正是开发还是最好使用mapper.xml的形式