Spring Boot 学习笔记之Web开发

静态文件映射规则

Spring Boot对于静态文件的映射主要在WebMvcAuotConfiguration 中进行匹配处理。

WebMvcAuotConfiguration :

public static class WebMvcAutoConfigurationAdapter extends WebMvcConfigurerAdapter {
     public void addResourceHandlers(ResourceHandlerRegistry registry) {
                if (!this.resourceProperties.isAddMappings()) {
                    logger.debug("Default resource handling disabled");
                    return;
                }
                Integer cachePeriod = this.resourceProperties.getCachePeriod();
                if (!registry.hasMappingForPattern("/webjars/**")) {
                    customizeResourceHandlerRegistration(
                            registry.addResourceHandler("/webjars/**")
                                    .addResourceLocations(
                                            "classpath:/META-INF/resources/webjars/")
                            .setCachePeriod(cachePeriod));
                }
                String staticPathPattern = this.mvcProperties.getStaticPathPattern();
         	    //静态资源文件夹映射
                if (!registry.hasMappingForPattern(staticPathPattern)) {
                    customizeResourceHandlerRegistration(
                            registry.addResourceHandler(staticPathPattern)
                                    .addResourceLocations(
                                            this.resourceProperties.getStaticLocations())
                            .setCachePeriod(cachePeriod));
                }
       }
        //配置欢迎页映射
        @Bean
        public WelcomePageHandlerMapping welcomePageHandlerMapping(
        ResourceProperties resourceProperties) {
            return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
            this.mvcProperties.getStaticPathPattern());
        }
   
}

静态文件映射配置ResourceProperties

ResourceProperties:

public class ResourceProperties implements ResourceLoaderAware {
		private static final String[] SERVLET_RESOURCE_LOCATIONS = { "/" };

	private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
			"classpath:/META-INF/resources/", "classpath:/resources/",
			"classpath:/static/", "classpath:/public/" };

	private static final String[] RESOURCE_LOCATIONS;

	static {
		RESOURCE_LOCATIONS = new String[CLASSPATH_RESOURCE_LOCATIONS.length
				+ SERVLET_RESOURCE_LOCATIONS.length];
		System.arraycopy(SERVLET_RESOURCE_LOCATIONS, 0, RESOURCE_LOCATIONS, 0,
				SERVLET_RESOURCE_LOCATIONS.length);
		System.arraycopy(CLASSPATH_RESOURCE_LOCATIONS, 0, RESOURCE_LOCATIONS,
				SERVLET_RESOURCE_LOCATIONS.length, CLASSPATH_RESOURCE_LOCATIONS.length);
	}
    private String[] staticLocations = RESOURCE_LOCATIONS;
    /**
     * 静态路径的列表
     */
    public String[] getStaticLocations() {
		return this.staticLocations;
	}
    /**
     * 静态欢迎页面的列表
     */
	private String[] getStaticWelcomePageLocations() {
		String[] result = new String[this.staticLocations.length];
		for (int i = 0; i < result.length; i++) {
			String location = this.staticLocations[i];
			if (!location.endsWith("/")) {
				location = location + "/";
			}
			result[i] = location + "index.html";
		}
		return result;
	}
}

从上面的代码中可以看出:

(1)所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源;

http://www.webjars.org/

webjars:以jar包的方式引入静态资源;

例如:

<!‐‐引入jquery‐webjar‐‐>在访问的时候只需要写webjars下面资源的名称即可
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.3.1</version>
</dependency>

引入后可以使用http://localhost:8080/webjars/jquery/3.3.1/jquery.js进行访问

(2)其它静态资源映射

"classpath:/META‐INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
"/":当前项目的根路径

(3)欢迎页

静态资源文件夹下的所有index.html页面;被"/**"映射;

例如:http://localhost:8080 会查找index.html页面

(4)所有的 **/favicon.ico 都是在静态资源文件下找;

模板引擎

thymeleaf引入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring‐boot‐starter‐thymeleaf</artifactId>
</dependency>

切换thymeleaf版本

<properties>
   <thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
    <!‐‐ 布局功能的支持程序 thymeleaf3主程序 layout2以上版本 ‐‐>
    <!‐‐ thymeleaf2 layout1‐‐>
    <thymeleaf‐layout‐dialect.version>2.2.2</thymeleaf‐layout‐dialect.version>
</properties>

Thymeleaf 应用

@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {
    private static final Charset DEFAULT_ENCODING = Charset.forName("UTF‐8");
    private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");
    public static final String DEFAULT_PREFIX = "classpath:/templates/";
    public static final String DEFAULT_SUFFIX = ".html";
}

把HTML页面放在classpath:/templates/,thymeleaf就能自动渲染;

使用步骤:

1 导入thymeleaf的名称空间

<html lang="en" xmlns:th="http://www.thymeleaf.org">

2 使用thymeleaf语法;

<!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>

关闭缓存

spring.thymeleaf.cache=false

Thymeleaf语法规则

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#dialects-the-standard-dialect

${...}:获取变量值;OGNL;
1)、获取对象的属性、调用方法
2)、使用内置的基本对象
3)、内置的一些工具对象
*{...}:选择表达式:和${}在功能上是一样;例外:配合 th:object="${session.user}",*{firstName}可以表示${session.user.firstName}
<div th:object="${session.user}">
    <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
    <p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
    <p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
</div>
#{...}:获取国际化内容
@{...}:定义URL;
~{...}:片段引用表达式

thymeleaf公共页面

1、抽取公共片段

<div th:fragment="copy">
&copy; 2011 The Good Thymes Virtual Grocery
</div>

2、引入公共片段

<div th:insert="~{footer :: copy}"></div>
~{templatename::selector}:模板名::选择器
~{templatename::fragmentname}:模板名::片段名

3、默认效果

insert的公共片段在div标签中
如果使用th:insert等属性进行引入,可以不用写~{}:
行内写法可以加上:[[~{}]];[(~{})];

三种引入公共片段的th属性:
th:insert:将公共片段整个插入到声明引入的元素中
th:replace:将声明引入的元素替换为公共片段
th:include:将被引入的片段的内容包含进这个标签中

片段一:

templates下footer.html

<div th:fragment="copy">
&copy; 2011 The Good Thymes Virtual Grocery
</div>

引入方式:

<div th:insert="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
<div th:include="footer :: copy"></div>

片段二:

commons/bar.html

<div id="sidebar">
    <div class="nav‐link active" th:class="${activeUri=='main'?'nav‐link active':'nav‐link'}">
    </div>
</div>

引用方式:

<div th:replace="commons/bar::#sidebar(activeUri='emps')"></div>

Web配置

web的所有自动场景在org.springframework.boot.autoconfigure.web下。

https://docs.spring.io/spring-boot/docs/1.5.10.RELEASE/reference/htmlsingle/#boot-features-developingweb-applications

Spring MVC自动配置

Spring Boot 自动配置好了SpringMVC,WebMvcAutoConfiguration是SpringBoot对SpringMVC的默认配置。

(1)默认包含ContentNegotiatingViewResolver 和BeanNameViewResolver

ContentNegotiatingViewResolver :组合所有的视图解析器(可以给容器中添加一个视图解析器;自动的将其组合进来)

(2)静态资源文件夹路径,webjars

(3)index.html静态首页访问

(4)Favicon支持的favicon.ico

(5)自动注册Converter , GenericConverter , Formatter

Converter:转换器,例如类型转换。

Formatter: 格式化器;例如日期格式化。

添加的格式化器转换器,只需要放在容器中即可。

(6)Http请求和响应数据转换

SpringMVC用HttpMessageConverter转换Http请求和响应的;Object—Json;
HttpMessageConverters 是从容器中确定;获取所有的HttpMessageConverter;
自己给容器中添加HttpMessageConverter,只需要将自己的组件注册容器中。

(7)MessageCodesResolver定义错误代码生成规则

(8)ConfigurableWebBindingInitializer数据绑定

初始化WebDataBinder,用来将请求数据绑定JavaBean上;

(9)如果想保持Spring Boot MVC特性,并且想添加MVC 配置(interceptors, formatters, view controllers),可以在实现了WebMvcConfigurerAdapter 类上添加@Configuration,但是不能添加@EnableWebMvc。

//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // super.addViewControllers(registry);
        //浏览器发送 /hello 请求来到 success
        registry.addViewController("/hello").setViewName("success");
    }
}	

如果期望添加自定义RequestMappingHandlerMapping , RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver,需要在继承了WebMvcRegistrationsAdapter的类上添加@Configuration。

如果想完全控制Spring MVC,需要同时添加@Configuration和@EnableWebMvc。

Spring Boot 的WebMvcConfigurerAdapter 原理

WebMvcAutoConfiguration是SpringMVC的自动配置类。

WebMvcAutoConfigurationAdapter会导入@Import(EnableWebMvcConfiguration.class)

@Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
}
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {

	private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();

	@Autowired(required = false)
	public void setConfigurers(List<WebMvcConfigurer> configurers) {
		if (!CollectionUtils.isEmpty(configurers)) {
			this.configurers.addWebMvcConfigurers(configurers);
		}
	}
}

容器中所有的WebMvcConfigurer都会一起起作用;SpringMVC的自动配置和我们的扩展配置都会起作用;

全面接管SpringMVC

如果不需要SpringBoot对SpringMVC的自动配置,需要在配置类上添加@EnableWebMvc注解。

例如:

@EnableWebMvc
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // super.addViewControllers(registry);
        //浏览器发送 /hello 请求来到 success
        registry.addViewController("/hello").setViewName("success");
    }
}	

原理:

(1)@EnableWebMvc入口

@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

(2)DelegatingWebMvcConfiguration分析

@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
}

(3)WebMvc自动配置类

@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
		WebMvcConfigurerAdapter.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
		ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
}

通过@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)可以看出,容器中没有这个组件的时候,这个自动配置类才生效。

但自定义导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能。

国际化

基本知识

例如:

在spring boot中配置spring.messages.basename=i18n.message

SpringBoot自动配置好了管理国际化资源文件的组件:

@ConfigurationProperties(prefix = "spring.messages")
public class MessageSourceAutoConfiguration {
	private String basename = "messages";
	/**
	 * 获取国际化资源的MessageSource
	 */
	@Bean
	public MessageSource messageSource() {
		ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
		if (StringUtils.hasText(this.basename)) {
			messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(
					StringUtils.trimAllWhitespace(this.basename)));
		}
		if (this.encoding != null) {
			messageSource.setDefaultEncoding(this.encoding.name());
		}
		messageSource.setFallbackToSystemLocale(this.fallbackToSystemLocale);
		messageSource.setCacheSeconds(this.cacheSeconds);
		messageSource.setAlwaysUseMessageFormat(this.alwaysUseMessageFormat);
		return messageSource;
	}
}

在页面中thymeleaf通过#{key}获取国际化类容。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8">
        <meta name="viewport" content="width=device‐width, initial‐scale=1, shrink‐tofit=
        no">
        <meta name="description" content="">
        <meta name="author" content="">
        <title>Signin Template for Bootstrap</title>
        <!‐‐ Bootstrap core CSS ‐‐>
        <link href="asserts/css/bootstrap.min.css"
        th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet">
        <!‐‐ Custom styles for this template ‐‐>
        <link href="asserts/css/signin.css" th:href="@{/asserts/css/signin.css}"
        rel="stylesheet">
    </head>
    <body class="text‐center">
    	<label class="sr‐only" th:text="#{key}">key</label>
   </body>
</html>

原理:

@Configuration
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
public static class WebMvcAutoConfigurationAdapter extends WebMvcConfigurerAdapter {
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
    public LocaleResolver localeResolver() {
        if (this.mvcProperties
            .getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
            return new FixedLocaleResolver(this.mvcProperties.getLocale());
        }
        AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
        localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
        return localeResolver;
    }
}

通过上面代码可以看出SpringBoot自动配置会默认注入AcceptHeaderLocaleResolver组件。

public class AcceptHeaderLocaleResolver implements LocaleResolver {
    @Override
	public Locale resolveLocale(HttpServletRequest request) {
		Locale defaultLocale = getDefaultLocale();
		if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
			return defaultLocale;
		}
		Locale requestLocale = request.getLocale();
		if (isSupportedLocale(requestLocale)) {
			return requestLocale;
		}
		Locale supportedLocale = findSupportedLocale(request);
		if (supportedLocale != null) {
			return supportedLocale;
		}
		return (defaultLocale != null ? defaultLocale : requestLocale);
	}
}

AcceptHeaderLocaleResolver通过获取头中语言类型才能进行国际化资源指定。

手动切换国际化

public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        String l = request.getParameter("l");
        Locale locale = Locale.getDefault();
        if(!StringUtils.isEmpty(l)){
            String[] split = l.split("_");
            locale = new Locale(split[0],split[1]);
    	}
    	return locale;
    }
    @Override
    public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale
    locale) {
    }
}

错误处理机制

SpringBoot默认的错误处理机制

1)、浏览器,返回一个默认的错误页面

2)、有的客户端,默认响应一个json数据

原理:

ErrorMvcAutoConfiguration

@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class })
// Load before the main WebMvcAutoConfiguration so that the error View is available
@AutoConfigureBefore(WebMvcAutoConfiguration.class)
@EnableConfigurationProperties(ResourceProperties.class)
public class ErrorMvcAutoConfiguration {
    //默认错误属性
    @Bean
    @ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
    public DefaultErrorAttributes errorAttributes() {
        return new DefaultErrorAttributes();
    }
    //基本错误控制器 /error
    @Bean
    @ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
    public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) {
        return new BasicErrorController(errorAttributes, this.serverProperties.getError(),
                                        this.errorViewResolvers);
    }
    //系统出现错误以后来到error请求进行处理;(web.xml注册的错误页面规则)
    @Bean
    public ErrorPageCustomizer errorPageCustomizer() {
        return new ErrorPageCustomizer(this.serverProperties);
    }
    @Configuration
    static class DefaultErrorViewResolverConfiguration {
        //默认错误视图解析器
        @Bean
        @ConditionalOnBean(DispatcherServlet.class)
        @ConditionalOnMissingBean
        public DefaultErrorViewResolver conventionErrorViewResolver() {
            return new DefaultErrorViewResolver(this.applicationContext,
                                                this.resourceProperties);
        }
    }
}

定制错误响应

(1)有模板引擎的情况下;error/状态码; 【将错误页面命名为 错误状态码.html 放在模板引擎文件夹里面的
error文件夹下】,发生此状态码的错误就会来到 对应的页面;

可以使用4xx和5xx作为错误页面的文件名来匹配这种类型的所有错误,精确优先(优先寻找精确的状态
码.html);

页面能获取的信息:
timestamp:时间戳
status:状态码
error:错误提示
exception:异常对象
message:异常消息
errors:JSR303数据校验的错误都在这里

(2)没有模板(模板引擎找不到这个错误页面),静态资源文件夹下找;

(3)以上都没有错误页面,就是默认来到SpringBoot默认的错误提示页面;

定制错误的json数据

(1)自定义异常处理&返回定制json数据;

@ControllerAdvice
public class MyExceptionHandler {
    @ResponseBody
    @ExceptionHandler(UserNotExistException.class)
    public Map<String,Object> handleException(Exception e){
        Map<String,Object> map = new HashMap<>();
        map.put("code","user.notexist");
        map.put("message",e.getMessage());
        return map;
	}
}

(2)转发到/error进行自适应响应效果处理

@ExceptionHandler(UserNotExistException.class)
public String handleException(Exception e, HttpServletRequest request){
    Map<String,Object> map = new HashMap<>();
    //传入我们自己的错误状态码 4xx 5xx,否则就不会进入定制错误页面的解析流程
    //Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
    request.setAttribute("javax.servlet.error.status_code",500);
    map.put("code","user.notexist");
    map.put("message",e.getMessage());
    //转发到/error
    return "forward:/error";
}

(3)定制数据

//给容器中加入我们自己定义的ErrorAttributes
@Component
public class MyErrorAttributes extends DefaultErrorAttributes {
    @Override
    public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes,
    boolean includeStackTrace) {
        Map<String, Object> map = super.getErrorAttributes(requestAttributes,
        includeStackTrace);
        map.put("company","sdfsdf");
        return map;
    }
}

配置嵌入式Servlet容器

SpringBoot默认使用Tomcat作为嵌入式的Servlet容器;

定制和修改Servlet容器的相关配置

1 修改和server有关的配置(ServerProperties【也是EmbeddedServletContainerCustomizer】)

server.port=8081
server.context‐path=/crud
server.tomcat.uri‐encoding=UTF‐8
//通用的Servlet容器设置
server.xxx
//Tomcat的设置
server.tomcat.xxx

2 编写一个EmbeddedServletContainerCustomizer:嵌入式的Servlet容器的定制器;来修改Servlet容器的
配置

@Bean //一定要将这个定制器加入到容器中
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
    return new EmbeddedServletContainerCustomizer() {
        //定制嵌入式的Servlet容器相关的规则
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            container.setPort(8083);
        }
    };
}

注册Servlet三大组件【Servlet、Filter、Listener】

注册三大组件方式

ServletRegistrationBean:

//注册三大组件
@Bean
public ServletRegistrationBean myServlet(){
    ServletRegistrationBean registrationBean = new ServletRegistrationBean(new
    MyServlet(),"/myServlet");
    return registrationBean;
}

FilterRegistrationBean:

@Bean
public FilterRegistrationBean myFilter(){
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    registrationBean.setFilter(new MyFilter());
    registrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet"));
    return registrationBean;
}

ServletListenerRegistrationBean:

@Bean
public ServletListenerRegistrationBean myListener(){
    ServletListenerRegistrationBean<MyListener> registrationBean = new
    ServletListenerRegistrationBean<>(new MyListener());
    return registrationBean;
}

替换为其他嵌入式Servlet容器

Tomcat(默认使用)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring‐boot‐starter‐web</artifactId>
    <!--引入web模块默认就是使用嵌入式的Tomcat作为Servlet容器;-->
</dependency>

Jetty

<!‐‐ 引入web模块 ‐‐>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring‐boot‐starter‐web</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>spring‐boot‐starter‐tomcat</artifactId>
            <groupId>org.springframework.boot</groupId>
        </exclusion>
    </exclusions>
</dependency>
<!‐‐引入其他的Servlet容器‐‐>
<dependency>
    <artifactId>spring‐boot‐starter‐jetty</artifactId>
    <groupId>org.springframework.boot</groupId>
</dependency>

Undertow

<!‐‐ 引入web模块 ‐‐>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐web</artifactId>
<exclusions>
    <exclusion>
        <artifactId>spring‐boot‐starter‐tomcat</artifactId>
        <groupId>org.springframework.boot</groupId>
    </exclusion>
</exclusions>
</dependency>
<!--引入其他的Servlet容器-->
<dependency>
    <artifactId>spring‐boot‐starter‐undertow</artifactId>
    <groupId>org.springframework.boot</groupId>
</dependency>

使用外置的Servlet容器

嵌入式Servlet容器

应用打成可执行的jar。

优点:简单、便携;
缺点:默认不支持JSP、优化定制比较复杂(使用定制器【ServerProperties、自定义
EmbeddedServletContainerCustomizer】,自己编写嵌入式Servlet容器的创建工厂
【EmbeddedServletContainerFactory】);

外置的Servlet容器

外面安装Tomcat—应用war包的方式打包;

1)、必须创建一个war项目;(利用idea创建好目录结构)
2)、将嵌入式的Tomcat指定为provided;

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring‐boot‐starter‐tomcat</artifactId>
	<scope>provided</scope>
</dependency>

3)、必须编写一个SpringBootServletInitializer的子类,并调用configure方法

public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
//传入SpringBoot应用的主程序
return application.sources(SpringBoot04WebJspApplication.class);
}
}

4)、启动服务器就可以使用;

SpringBoot数据库访问

JDBC

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring‐boot‐starter‐jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql‐connector‐java</artifactId>
    <scope>runtime</scope>
</dependency>

配置:

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://192.168.15.22:3306/jdbc
    driver‐class‐name: com.mysql.jdbc.Driver

默认是用org.apache.tomcat.jdbc.pool.DataSource作为数据源;
数据源的相关配置都在DataSourceProperties里面;
自动配置原理(org.springframework.boot.autoconfigure.jdbc包):

1、参考DataSourceConfiguration,根据配置创建数据源,默认使用Tomcat连接池;可以使用
spring.datasource.type指定自定义的数据源类型;

2、SpringBoot默认可以支持;

org.apache.tomcat.jdbc.pool.DataSource、HikariDataSource、BasicDataSource、

3、自定义数据源类型

@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type")
static class Generic {
    @Bean
    public DataSource dataSource(DataSourceProperties properties) {
        //使用DataSourceBuilder创建数据源,利用反射创建响应type的数据源,并且绑定相关属性
        return properties.initializeDataSourceBuilder().build();
    }
}

4、DataSourceInitializer:ApplicationListener;

作用:
1)、runSchemaScripts();运行建表语句;
2)、runDataScripts();运行插入数据的sql语句;
默认只需要将文件命名为:

schema‐*.sql、data‐*.sql
默认规则:schema.sql,schema‐all.sql;
可以使用
    schema:
     ‐ classpath:department.sql
	 指定位置

5、操作数据库:自动配置了JdbcTemplate操作数据库

整合Druid数据源

@Configuration
public class DruidConfig {
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druid(){
        return new DruidDataSource();
    }
    //配置Druid的监控
    //1、配置一个管理后台的Servlet
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(),
                                                                   "/druid/*");
        Map<String,String> initParams = new HashMap<>();
        initParams.put("loginUsername","admin");
        initParams.put("loginPassword","123456");
        initParams.put("allow","");//默认就是允许所有访问
        initParams.put("deny","192.168.15.21");
        bean.setInitParameters(initParams);
        return bean;
    }
    //2、配置一个web监控的filter
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
        Map<String,String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.css,/druid/*");
        bean.setInitParameters(initParams);
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }
}

整合MyBatis

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis‐spring‐boot‐starter</artifactId>
    <version>1.3.1</version>
</dependency>

Mapper创建:

@Mapper
public interface DepartmentMapper {
    @Select("select * from department where id=#{id}")
    public Department getDeptById(Integer id);
    @Delete("delete from department where id=#{id}")
    public int deleteDeptById(Integer id);
    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into department(departmentName) values(#{departmentName})")
    public int insertDept(Department department);
    @Update("update department set departmentName=#{departmentName} where id=#{id}")
    public int updateDept(Department department);
}

自定义MyBatis的配置规则;给容器中添加一个ConfigurationCustomizer;

@Configuration
public class MyBatisConfig {
	@Bean
	public ConfigurationCustomizer configurationCustomizer(){
		return new ConfigurationCustomizer(){
            @Override
            public void customize(Configuration configuration) {
            	configuration.setMapUnderscoreToCamelCase(true);
            }
         };
   }
}	

使用MapperScan批量扫描所有的Mapper接口;

@MapperScan(value = "com.springboot.mapper")
@SpringBootApplication
public class SpringBootDataMybatisApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBoot06DataMybatisApplication.class, args);
    }
}

配置文件配置

mybatis:
  config‐location: classpath:mybatis/mybatis‐config.xml 指定全局配置文件的位置
  mapper‐locations: classpath:mybatis/mapper/*.xml 指定sql映射文件的位置

整合SpringData JPA

application.yml配置:

spring:
  datasource:
    url: jdbc:mysql://192.168.15.22/jpa
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
    hibernate:
#     更新或者创建数据表结构
      ddl-auto: update
#    控制台显示SQL
    show-sql: true

Entity:

//使用JPA注解配置映射关系
@Entity //告诉JPA这是一个实体类(和数据表映射的类)
@Table(name = "tbl_user") //@Table来指定和哪个数据表对应;如果省略默认表名就是user;
public class User {

    @Id //这是一个主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)//自增主键
    private Integer id;

    @Column(name = "last_name",length = 50) //这是和数据表对应的一个列
    private String lastName;
    @Column //省略默认列名就是属性名
    private String email;
}

Repository:

//继承JpaRepository来完成对数据库的操作
public interface UserRepository extends JpaRepository<User,Integer> {
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流光影下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值