天天看點

SSM+redis+Thymeleaf整合,基于Java配置(其實哪種友善哪種來,說不定xml+Java配置會有一個意想不到的效果呢,雖然你可能最後會喜歡上springboot)pom.xmlConfig類

------看完了《Spring In Action》,對于spring提供的Java配置有自己一定的了解,它能讓你更好的了解運作機制。至于方不友善,見人見智。

目錄結構如下圖

------entity用于存放實體類,model用于存放一些業務pojo

SSM+redis+Thymeleaf整合,基于Java配置(其實哪種友善哪種來,說不定xml+Java配置會有一個意想不到的效果呢,雖然你可能最後會喜歡上springboot)pom.xmlConfig類

pom.xml

------不止于ssm、redis和thymeleaf的依賴,還有諸如druid、fastjson、flyway(資料庫版本管理工具)依賴

<properties>
    <webVersion>3.1</webVersion>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <javaee-api.version>7.0</javaee-api.version>
    <jstl.version>1.2.2</jstl.version>
    <junit.version>4.11</junit.version>
    <thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
    <thymeleaf.layout.version>1.2.3</thymeleaf.layout.version>
    <spring.version>4.3.18.RELEASE</spring.version>
    <mybatis.version>3.2.1</mybatis.version>
    <mybatis.spring.version>1.2.0</mybatis.spring.version>
    <mybatis.generator.version>1.3.5</mybatis.generator.version>
    <mysql.version>8.0.12</mysql.version>
    <alibaba.druid.version>1.0.16</alibaba.druid.version>
    <flyway.version>4.0.3</flyway.version>
    <slf4j.version>1.7.7</slf4j.version>
    <log4j.version>1.2.12</log4j.version>
    <logback.version>1.1.2</logback.version>
    <logback.spring.version>0.1.1</logback.spring.version>
    <alibaba.fastjson.version>1.2.31</alibaba.fastjson.version>
    <jackson.version>2.8.7</jackson.version>
    <redis.jedis.version>2.9.0</redis.jedis.version>
    <spring.data.redis>1.8.0.RELEASE</spring.data.redis>
  </properties>
  
  <dependencies>
    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>${javaee-api.version}</version>
      <scope>provided</scope>
    </dependency>
    <!-- jstl依賴 -->
    <dependency>
      <groupId>org.glassfish.web</groupId>
      <artifactId>javax.servlet.jsp.jstl</artifactId>
      <version>${jstl.version}</version>
    </dependency>
    <!-- junit依賴 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
    <!-- thymeleaf依賴 -->
    <dependency>
      <groupId>org.thymeleaf</groupId>
      <artifactId>thymeleaf</artifactId>
      <version>${thymeleaf.version}</version>
    </dependency>
    <dependency>
      <groupId>org.thymeleaf</groupId>
      <artifactId>thymeleaf-spring4</artifactId>
      <version>${thymeleaf.version}</version>
    </dependency>
    <!-- thymeleaf布局依賴 -->
    <dependency>
       <groupId>nz.net.ultraq.thymeleaf</groupId>
       <artifactId>thymeleaf-layout-dialect</artifactId>
       <version>${thymeleaf.layout.version}</version>
	</dependency>
    <!-- 添加spring依賴 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- spring單元測試依賴 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
      <scope>test</scope>
    </dependency>
    <!-- springmvc依賴 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- mybatis依賴 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>${mybatis.version}</version>
    </dependency>
    <!-- mybatis/spring依賴-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>${mybatis.spring.version}</version>
    </dependency>
    <!-- MyBatis逆向工程 -->
	<dependency>
		<groupId>org.mybatis.generator</groupId>
		<artifactId>mybatis-generator-core</artifactId>
		<version>${mybatis.generator.version}</version>
	</dependency>
    <!-- mysql驅動依賴 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
    </dependency>
    <!-- druid datasource依賴 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>${alibaba.druid.version}</version>
    </dependency>
    <dependency>
    <groupId>org.flywaydb</groupId>
      <artifactId>flyway-core</artifactId>
      <version>${flyway.version}</version>
	</dependency>
    <!-- fastjson依賴 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>${alibaba.fastjson.version}</version>
    </dependency>
    <!-- logback依賴 -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j.version}</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>${logback.version}</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>${logback.version}</version>
    </dependency>
    <dependency>
      <groupId>org.logback-extensions</groupId>
      <artifactId>logback-ext-spring</artifactId>
      <version>${logback.spring.version}</version>
    </dependency>
    <dependency>
    <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>${redis.jedis.version}</version>
	</dependency>
	<dependency>
   	  <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-redis</artifactId>
      <version>${spring.data.redis}</version>
	</dependency>
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-core</artifactId>
		<version>${jackson.version}</version>
	</dependency>
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-databind</artifactId>
		<version>${jackson.version}</version>
	</dependency>
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-annotations</artifactId>
		<version>${jackson.version}</version>
	</dependency>	
  </dependencies>
           

Config類

TinyHelpWebAppInitializer.java

-------Servlert3.0後規範允許取消web.xml配置,可以隻使用注解。在Servlet3.0環境中,容器會在classpath下查找實作了ServletContainerInitializer接口的類,如果能發現了,就會用它來配置Servlet容器。Spring提供了接口的實作類SpringServletContainerInitializer,這個類又會查找實作了WebApplicationInitializer接口的類并将配置任務交給它們完成,WebApplicationInitializer與實作類關系如下圖:

SSM+redis+Thymeleaf整合,基于Java配置(其實哪種友善哪種來,說不定xml+Java配置會有一個意想不到的效果呢,雖然你可能最後會喜歡上springboot)pom.xmlConfig類
package com.tinyhelp.config;

import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration.Dynamic;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class TinyHelpWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

	// 設定檔案上傳配置
	// 存儲檔案的臨時位置
	private static final String LOCATION = "/temp";
	// 最大檔案大小,5MB
    private static final long MAX_FILE_SIZE = 5242880;
    // 最大請求大小,20MB
    private static final long MAX_REQUEST_SIZE = 20971520;
    // 如果檔案大小達到了一個指定的最大容量,将會寫入臨時檔案。預設0,上傳的檔案都寫入磁盤上。
    private static final int FILE_SIZE_THRESHOLD = 0; 
    
	@Override
	protected Class<?>[] getRootConfigClasses() {
		return new Class<?>[]{ RootConfig.class };
	}

	@Override
	protected Class<?>[] getServletConfigClasses() {
		return new Class<?>[]{ WebConfig.class };
	}

	//将DispatcherServlet映射到“/”
	@Override
	protected String[] getServletMappings() {
		return new String[]{ "/" };
	}

	@Override
	protected void customizeRegistration(Dynamic registration) {
		//配置檔案上傳
		registration.setMultipartConfig(new MultipartConfigElement(LOCATION,MAX_FILE_SIZE,MAX_REQUEST_SIZE,FILE_SIZE_THRESHOLD));
	}

}
           

WebConfig.java

-------這個類主要是用來配置Web元件的Bean,如控制器。Spring5後,WebMvcConfigurerAdapter已被廢棄,官方推薦實作WebMvcConfigurer接口。

[email protected](basePackageClasses = { BasePackageWeb.class }),元件掃描選擇掃描一個空接口類,它放在放Controller和Servlet的Web包裡,這樣spring就會掃描到它和它的同級包與子包。接下的配置遵從這樣的規則,因為掃描一個String類型不安全,掃描接口的話,能便于重構等。

package com.tinyhelp.config;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.thymeleaf.spring4.ISpringTemplateEngine;

import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.tinyhelp.web.BasePackageWeb;

@Configuration
@EnableWebMvc
@ComponentScan(basePackageClasses = { BasePackageWeb.class })
@Import({ThymeleafConfig.class, MultipartResolverConfig.class})
public class WebConfig implements WebMvcConfigurer {

	@Override
	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void addCorsMappings(CorsRegistry arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void addFormatters(FormatterRegistry arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void addInterceptors(InterceptorRegistry arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		//增加資源控制器,并設定資源映射路徑和資源路徑,通路WEB-INF下的靜态資源
		registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/static/");
	}

	@Override
	public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void addViewControllers(ViewControllerRegistry arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void configureAsyncSupport(AsyncSupportConfigurer arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void configureContentNegotiation(ContentNegotiationConfigurer arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		//開啟靜态資源的預設處理器
		configurer.enable();
	}

	@Override
	public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
		//隻配置fastjson消息轉換器
		FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
		//配置資訊
		FastJsonConfig fastJsonConfig = new FastJsonConfig();
		fastJsonConfig.setCharset(Charset.forName("UTF-8"));
		fastJsonConfig.setDateFormat("yyyy-MM-dd hh:mm:ss");
		fastJsonConverter.setFastJsonConfig(fastJsonConfig);
		//設定支援的Media類型轉換
		ArrayList<MediaType> mediaTypes = new ArrayList<>();
		mediaTypes.add(MediaType.TEXT_PLAIN);
		mediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
		fastJsonConverter.setSupportedMediaTypes(mediaTypes);
		//添加fastjsonConverter到Converters
		converters.add(fastJsonConverter);
	}

	@Override
	public void configurePathMatch(PathMatchConfigurer arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		// TODO Auto-generated method stub
	}

	public ISpringTemplateEngine templateEngine() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void extendMessageConverters(List<HttpMessageConverter<?>> arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public MessageCodesResolver getMessageCodesResolver() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Validator getValidator() {
		// TODO Auto-generated method stub
		return null;
	}

}

           

ThymeleafConfig.java

-------這個類是用來配置模闆解釋器、模闆引擎和thymeleaf視圖解釋器。

package com.tinyhelp.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ITemplateResolver;

@Configuration
public class ThymeleafConfig {

	//模闆解釋器
	@Bean
	public ITemplateResolver templateResolver(){
		SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
		templateResolver.setPrefix("/WEB-INF/templates/");
		templateResolver.setSuffix(".html");
		templateResolver.setTemplateMode(TemplateMode.HTML);
		//解決中文亂碼
		templateResolver.setCharacterEncoding("UTF-8");
		//開發環境關閉緩存便于調試,生産環境采用緩存
		templateResolver.setCacheable(false);
		return templateResolver;
	}
	
	//模闆引擎
	@Bean
	public TemplateEngine templateEngine(ITemplateResolver templateResolver){
		SpringTemplateEngine templateEngine = new SpringTemplateEngine();
		templateEngine.setTemplateResolver(templateResolver);
		return templateEngine;
	}
	
	//thymeleaf視圖解釋器
	@Bean
	public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
		ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
		viewResolver.setTemplateEngine(templateEngine);
		//解決中文亂碼
		viewResolver.setCharacterEncoding("UTF-8");
		return viewResolver;
	}
	
}

           

MultipartResolverConfig.java

-------這個類是用來配置配置檔案上傳解釋器的。沒有用CommonsMultipartResolver,因為依賴于第三方實作。能依賴于Servlet本身是最好的了。

package com.tinyhelp.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;

@Configuration
public class MultipartResolverConfig {

	//配置依賴Servlet3.0對multipart請求的支援
	@Bean
    public MultipartResolver multipartResolver(){
		return new StandardServletMultipartResolver();
	}
}

           

RootConfig.java

--------這個類主要是用來配置除Web元件的Bean外其它的配置Bean,如資料源等。

package com.tinyhelp.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import com.tinyhelp.entity.BasePackageEntity;
import com.tinyhelp.service.impl.BasePackageServiceImpl;

@Configuration
@ComponentScan(basePackageClasses = { BasePackageServiceImpl.class, BasePackageEntity.class })
@Import({DataBaseConfig.class, RedisConfig.class})
public class RootConfig {

}
           

DataBaseConfig.java

--------這個類主要是用來配置druid資料源、mybatis和事務管理器的。事務使用注解事務,使用時在業務類或方法上加@Transaction注解。

--------其中注釋的代碼是關于flyway的。如果要應用啟動的時候實作資料庫遷移,将注釋代碼打開即好。如果不需要啟動的時候實作資料庫遷移,樓主選擇了另一種方法,使用flyway的maven插件。

package com.tinyhelp.config;

import java.io.IOException;
import java.util.ArrayList;

import javax.sql.DataSource;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.logging.Log4jFilter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.wall.WallFilter;
import com.tinyhelp.dao.BasePackageDao;

@Configuration
@PropertySource("classpath:/jdbc.properties")
@MapperScan(basePackageClasses = { BasePackageDao.class } )
@EnableTransactionManagement
public class DataBaseConfig {
  
    private String driverClassName;
    private String url;   
    private String username;    
    private String password;      
    private int initialSize;    
    private int minIdle;    
    private int maxActive;    
    private int maxWait;    
    private int timeBetweenEvictionRunsMillis;    
    private int minEvictableIdleTimeMillis;    
    private String validationQuery;    
    private boolean testWhileIdle;    
    private boolean testOnBorrow;   
    private boolean testOnReturn;  
    private boolean poolPreparedStatements;   
    private int maxPoolPreparedStatementPerConnectionSize;        
    private String connectionProperties;

    @Value("${spring.datasource.driverClassName}")
	public void setDriverClassName(String driverClassName) {
		this.driverClassName = driverClassName;
	}
    @Value("${spring.datasource.url}")  
	public void setUrl(String url) {
		this.url = url;
	}
    @Value("${spring.datasource.username}")
	public void setUsername(String username) {
		this.username = username;
	}
    @Value("${spring.datasource.password}")
	public void setPassword(String password) {
		this.password = password;
	}
    @Value("${spring.datasource.initialSize}")
	public void setInitialSize(int initialSize) {
		this.initialSize = initialSize;
	}
    @Value("${spring.datasource.minIdle}")
	public void setMinIdle(int minIdle) {
		this.minIdle = minIdle;
	}
    @Value("${spring.datasource.maxActive}")
	public void setMaxActive(int maxActive) {
		this.maxActive = maxActive;
	}
    @Value("${spring.datasource.maxWait}")
	public void setMaxWait(int maxWait) {
		this.maxWait = maxWait;
	}
    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
	public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
		this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
	}
    @Value("${spring.datasource.minEvictableIdleTimeMillis}")
	public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
		this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
	}
    @Value("${spring.datasource.validationQuery}")
	public void setValidationQuery(String validationQuery) {
		this.validationQuery = validationQuery;
	}
    @Value("${spring.datasource.testWhileIdle}")
	public void setTestWhileIdle(boolean testWhileIdle) {
		this.testWhileIdle = testWhileIdle;
	}
    @Value("${spring.datasource.testOnBorrow}")
	public void setTestOnBorrow(boolean testOnBorrow) {
		this.testOnBorrow = testOnBorrow;
	}
    @Value("${spring.datasource.testOnReturn}")
	public void setTestOnReturn(boolean testOnReturn) {
		this.testOnReturn = testOnReturn;
	}
    @Value("${spring.datasource.poolPreparedStatements}")
	public void setPoolPreparedStatements(boolean poolPreparedStatements) {
		this.poolPreparedStatements = poolPreparedStatements;
	}
    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
	public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
		this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
	}
    @Value("${spring.datasource.connectionProperties}")
	public void setConnectionProperties(String connectionProperties) {
		this.connectionProperties = connectionProperties;
	}  
    
    //配置flyway資料庫初始化,在項目啟動時遷移資料庫
    /*@Bean(initMethod="migrate")
    public Flyway flyway() {
    	Flyway flyway = new Flyway();
    	flyway.setDataSource(dataSource());
    	flyway.setEncoding("UTF-8");
    	//sql存放位置
    	flyway.setLocations("db/migration");
    	flyway.setBaselineOnMigrate(true);
    	flyway.setPlaceholderReplacement(false);
    	//設定開始的版本
    	flyway.setBaselineVersion(MigrationVersion.fromVersion("1"));
		return flyway;
	}*/
    
    //druid監控配置
    @Bean
    public StatFilter statFilter() {
		return new StatFilter();
	}
    //druid防火牆配置
    @Bean
    public WallFilter wallFilter() {
    	WallFilter wallFilter = new WallFilter();
    	//放行flyway配置
    	/*WallConfig wallConfig = new WallConfig();
		wallConfig.setVariantCheck(false);
		wallConfig.setNoneBaseStatementAllow(true);
		wallConfig.setCommentAllow(true);
		wallConfig.setMultiStatementAllow(true);    	
    	wallFilter.setConfig(wallConfig);*/
		return wallFilter;
	}
    //druid日志配置
    @Bean
    public Log4jFilter log4jFilter() {
		return new Log4jFilter();
	}
    
    //druid連接配接池配置
    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);  
        dataSource.setUsername(username);  
        dataSource.setPassword(password);    
        dataSource.setInitialSize(initialSize);  
        dataSource.setMinIdle(minIdle);  
        dataSource.setMaxActive(maxActive);  
        dataSource.setMaxWait(maxWait);  
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);  
        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);  
        dataSource.setValidationQuery(validationQuery);  
        dataSource.setTestWhileIdle(testWhileIdle);  
        dataSource.setTestOnBorrow(testOnBorrow);  
        dataSource.setTestOnReturn(testOnReturn);  
        dataSource.setPoolPreparedStatements(poolPreparedStatements);  
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);       
        //代理stat,wall,log4j
        ArrayList<Filter> filterList = new ArrayList<>();
        filterList.add(statFilter());
        filterList.add(wallFilter());
        filterList.add(log4jFilter());
        dataSource.setProxyFilters(filterList);
        dataSource.setConnectionProperties(connectionProperties);  
        return dataSource;  
    }
    
    //mybatis配置
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean() throws IOException{
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        //設定連接配接池
        sqlSessionFactoryBean.setDataSource(dataSource());
        //設定映射檔案位置
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*.xml"));
        //别名,讓*Mapper.xml實體類映射可以不加上具體包名
        sqlSessionFactoryBean.setTypeAliasesPackage("com.tinyhelp.model");
        return sqlSessionFactoryBean;
    }
    
    //配置事務管理器
    @Bean(name = "transactionManager")
    public DataSourceTransactionManager dataSourceTransactionManager(){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource());
        return dataSourceTransactionManager;
    }
      
}

           

jdbc.properties

--------url,username,password,修改成自己的

#連接配接池基本資訊
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
#連接配接池配置
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
#連接配接等待逾時時間
spring.datasource.maxWait=60000
#配置隔多久進行一次檢測(檢測可以關閉的空閑連接配接)
spring.datasource.timeBetweenEvictionRunsMillis=60000
#配置連接配接在池中的最小生存時間
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
# 打開PSCache,并且指定每個連接配接上PSCache的大小
spring.datasource.poolPreparedStatements=false
spring.datasource.maxPoolPreparedStatementPerConnectionSize=-1
# 配置監控統計攔截的filters,去掉後監控界面sql無法統計,'wall'用于防火牆
# spring.datasource.filters=stat,wall,log4j ,在DataBaseConfig定制stat,wall,log4j,兩者同時配置是交集(避免)
# 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
spring.datasource.connectionProperties=druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
           

RedisConfig.java

--------這個類主要是用來配置redisTemplate和redis緩存的。

package com.tinyhelp.config;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import redis.clients.jedis.JedisPoolConfig;

@Configuration
@PropertySource("classpath:/redis.properties")
@EnableCaching
public class RedisConfig {

	@Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.port}")
    private Integer port;
	@Value("${spring.redis.maxTotal}")
    private Integer maxTotal;
	@Value("${spring.redis.maxIdle}")
	private Integer maxIdle;
	@Value("${spring.redis.minIdle}")
	private Integer minIdle;
	@Value("${spring.redis.maxWait}")
	private Integer maxWaitMillis;
	@Value("${spring.redis.testOnBorrow}")
	private Boolean testOnBorrow;
	@Value("${spring.redis.testOnReturn}")
	private Boolean testOnReturn;

	/**
	 * jedisPoolConfig
	 */
	@Bean
	public JedisPoolConfig jedisPoolConfig() {
		JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
		jedisPoolConfig.setMaxTotal(maxTotal);
		jedisPoolConfig.setMaxIdle(maxIdle);
		jedisPoolConfig.setMinIdle(minIdle);
		jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
		jedisPoolConfig.setTestOnBorrow(testOnBorrow);
		jedisPoolConfig.setTestOnReturn(testOnReturn);
		return jedisPoolConfig;
	}
 
 
	/**
	 * redisConnectionFactory
	 */
	@Bean
	public RedisConnectionFactory redisConnectionFactory() {
		JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
		jedisConnectionFactory.setHostName(host);
		jedisConnectionFactory.setPort(port);
		jedisConnectionFactory.setPoolConfig(jedisPoolConfig());		
		return jedisConnectionFactory;
	}

    /**
     * 配置redisTemplate
    */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        
	    /** Redis 序列化器.
	    *
	    * RedisTemplate 預設的系列化類是 JdkSerializationRedisSerializer,用JdkSerializationRedisSerializer序列化的話, 被序列化的對象必須實作Serializable接口。在存儲内容時,除了屬性的内容外還存了其它内容在裡面,總長度長,且不容易閱讀。
	    *
	    * Jackson2JsonRedisSerializer 和 GenericJackson2JsonRedisSerializer,兩者都能系列化成 json, 但是後者會在 json 中加入 @class 屬性,類的全路徑包名,友善反系列化。前者如果存放了 List 則在反系列化的時候如果沒指定,TypeReference 則會報錯 java.util.LinkedHashMap cannot be cast to
	    */
        RedisSerializer<?> genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        RedisSerializer<?> stringRedisSerializer = new StringRedisSerializer();
        // 定義RedisTemplate,并設定連接配接工程
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        // key 的序列化采用 StringRedisSerializer
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        // value 值的序列化采用 GenericJackson2JsonRedisSerializer
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
        // 設定連接配接工廠
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        return redisTemplate;
    }

    //配置redis緩存管理器
    @Bean
    public CacheManager redisCacheManager(RedisTemplate<Object,Object> redisTempate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTempate);
        // 設定預設逾時時間,為30分鐘
        cacheManager.setDefaultExpiration(1800);
        // 設定緩存管理器名稱
        List<String> cacheNames = new ArrayList<String>();
        cacheNames.add("redisCacheManager");
        cacheManager.setCacheNames(cacheNames);
        return cacheManager;
    }
}
           

redis.properties

--------host,post,修改成自己的

#連接配接池基本資訊
spring.redis.maxTotal=200
spring.redis.maxIdle=20 
spring.redis.minIdle=5  
spring.redis.maxWait=3000
spring.redis.testOnBorrow=true
spring.redis.testOnReturn=true
#連接配接工廠
spring.redis.host=
spring.redis.port=
           

以下是其它配置檔案

------以下兩個java檔案是用于配置druid監控器的,配置完後可以通路http://localhost:8080/{項目名}/druid/index.html,檢視監控。

DruidMonitorServlet.java

package com.tinyhelp.web;


import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;

import com.alibaba.druid.support.http.StatViewServlet;

@WebServlet(name="druidMonitorServlet", urlPatterns="/druid/*", initParams={
		@WebInitParam(name="allow", value="127.0.0.1"),// IP白名單(沒有配置或者為空,則允許所有通路)
        @WebInitParam(name="loginUsername", value="admin"),
        @WebInitParam(name="loginPassword", value="123456"),
        @WebInitParam(name="resetEnable", value="false")// 禁用HTML頁面上的“Reset All”功能
})
public class DruidMonitorServlet extends StatViewServlet {

	/**
	 * Druid監控服務連接配接器
	 */
	private static final long serialVersionUID = -425013362240213511L;
}

           

DruidStatFilter.java

package com.tinyhelp.web;


import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;

import com.alibaba.druid.support.http.WebStatFilter;

@WebFilter(filterName="druidStatFilter", urlPatterns="/*", initParams={
        @WebInitParam(name="exclusions", value="*.css,*.js,*.gif,*.jpg,*.png,*.ico,/druid/*")//忽略資源
})
public class DruidStatFilter extends WebStatFilter {

	/**
	 * Druid監控過濾器
	 */
}

           

logback.xml

-------日志配置xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://www.padual.com/java/logback.xsd"
    debug="false" scan="true" scanPeriod="30 second">
 
    <property name="PROJECT" value="iorder" /> 
    <property name="ROOT" value="logs/${PROJECT}/" />
    <property name="FILESIZE" value="50MB" />
    <property name="MAXHISTORY" value="100" />
    <timestamp key="DATETIME" datePattern="yyyy-MM-dd HH:mm:ss" />
    <!-- 控制台列印 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder charset="utf-8">
            <pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
            </pattern>
        </encoder>
    </appender>
    <!-- ERROR 輸入到檔案,按日期和檔案大小 -->
    <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder charset="utf-8">
            <pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
            </pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${ROOT}%d/error.%i.log</fileNamePattern>
            <maxHistory>${MAXHISTORY}</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${FILESIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
    
    <!-- WARN 輸入到檔案,按日期和檔案大小 -->
    <appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder charset="utf-8">
            <pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
            </pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${ROOT}%d/warn.%i.log</fileNamePattern>
            <maxHistory>${MAXHISTORY}</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${FILESIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
    
    <!-- INFO 輸入到檔案,按日期和檔案大小 -->
    <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder charset="utf-8">
            <pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
            </pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${ROOT}%d/info.%i.log</fileNamePattern>
            <maxHistory>${MAXHISTORY}</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${FILESIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
    <!-- DEBUG 輸入到檔案,按日期和檔案大小 -->
    <appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder charset="utf-8">
            <pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
            </pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${ROOT}%d/debug.%i.log</fileNamePattern>
            <maxHistory>${MAXHISTORY}</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${FILESIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
    <!-- TRACE 輸入到檔案,按日期和檔案大小 -->
    <appender name="TRACE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder charset="utf-8">
            <pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
            </pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>TRACE</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy
            class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${ROOT}%d/trace.%i.log</fileNamePattern>
            <maxHistory>${MAXHISTORY}</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${FILESIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
    
    <!-- SQL相關日志輸出-->
    <logger name="org.apache.ibatis" level="INFO" additivity="false" />
    <logger name="org.mybatis.spring" level="INFO" additivity="false" />
    <logger name="com.github.miemiedev.mybatis.paginator" level="INFO" additivity="false" />
    
    <!-- Logger 根目錄 -->
    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="DEBUG" />  
        <appender-ref ref="ERROR" />
        <appender-ref ref="WARN" />
        <appender-ref ref="INFO" /> 
        <appender-ref ref="TRACE" />
    </root>
</configuration>
           

generatorConfig.xml

--------mybatis逆向工程,使用maven插件,這是配置檔案

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

	<properties resource="jdbc.properties" />

	<context id="DBTables" targetRuntime="MyBatis3">

		<commentGenerator>
			<!-- 是否去除自動生成的注釋 true:是 : false:否 -->
			<property name="suppressAllComments" value="true" />
		</commentGenerator>

		<jdbcConnection driverClass="${spring.datasource.driverClassName}"
			connectionURL="${spring.datasource.url}" userId="${spring.datasource.username}" password="${spring.datasource.password}">
			<property name="nullCatalogMeansCurrent" value="true"/>
		</jdbcConnection>

		<!-- 預設false,把JDBC DECIMAL 和 NUMERIC 類型解析為 Integer,為 true時把JDBC DECIMAL 和 
            NUMERIC 類型解析為java.math.BigDecimal -->
		<javaTypeResolver>
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver>

		<!-- targetProject:生成PO類的位置 -->
		<javaModelGenerator targetPackage="com.tinyhelp.entity" targetProject="./src/main/java">
			<!-- enableSubPackages:是否讓schema作為包的字尾 -->
			<property name="enableSubPackages" value="true" />
			<!-- 從資料庫傳回的值被清理前後的空格 -->
			<property name="trimStrings" value="true" />
		</javaModelGenerator>

		<!-- targetProject:mapper映射檔案生成的位置 -->
		<sqlMapGenerator targetPackage="mappers" targetProject="./src/main/resources">
			<!-- enableSubPackages:是否讓schema作為包的字尾 -->
			<property name="enableSubPackages" value="true" />
		</sqlMapGenerator>

		<!-- targetPackage:mapper接口生成的位置 -->
		<javaClientGenerator type="XMLMAPPER"
			targetPackage="com.tinyhelp.dao" targetProject="./src/main/java">
			<!-- enableSubPackages:是否讓schema作為包的字尾 -->
			<property name="enableSubPackages" value="true" />
		</javaClientGenerator>

		<!-- 指定資料庫表,注釋的已經生成過了 -->
		<!-- <table tableName="th_sys_user" domainObjectName="User"></table> -->
		<!-- <table tableName="th_sys_admin" domainObjectName="Admin"></table> -->
		<table tableName=""></table>

	</context>
</generatorConfiguration>
           

繼續閱讀