SpringBoot 集成SpringBatch 批处理框架分析

访客 阅读:177 2021-03-31 16:56:29 评论:0

SpringBatch 核心组件简介:

 1)JobRepository:用来注册Job容器,设置数据库相关属性。
 2)JobLauncher:用来启动Job的接口
 3)Job:我们要实际执行的任务,包含一个或多个
 4)Step:即步骤,包括:ItemReader->ItemProcessor->ItemWriter
 5)ItemReader:用来读取数据,做实体类与数据字段之间的映射。比如读取csv文件中的人员数据,之后对应实体AuthUser的字段做mapper
 6)ItemProcessor:用来处理数据的接口,同时可以做数据校验(设置校验器,使用JSR-303(hibernate-validator)注解)
 7)ItemWriter:用来输出数据的接口,设置数据库源。编写预处理SQL插入语句

使用说明:在自定义的SpringBatch配置对象中一一实列化七大组件,[email protected]

package com.zzg.batch; 
 
import org.mybatis.spring.annotation.MapperScan; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.boot.builder.SpringApplicationBuilder; 
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 
import org.springframework.transaction.annotation.EnableTransactionManagement; 
 
@SpringBootApplication 
@EnableTransactionManagement 
@MapperScan("com.zzg.batch.mapper") 
public class Application extends SpringBootServletInitializer{ 
 
	public static void main(String[] args) { 
		SpringApplication.run(Application.class, args); 
		System.out.println("============= SpringBoot gcxt-system-provider Service Start Success ============="); 
 
	} 
 
	@Override 
	protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { 
		// 注意这里要指向原先用main方法执行的Application启动类 
		return builder.sources(Application.class); 
	} 
} 

SpringBatch 批处理流程图:

SpringBatch 实践

第一步:依赖核心jar文件:

<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.zzg</groupId> 
	<artifactId>jreport</artifactId> 
	<version>0.0.1-SNAPSHOT</version> 
	<packaging>pom</packaging> 
 
	<parent> 
		<groupId>org.springframework.boot</groupId> 
		<artifactId>spring-boot-starter-parent</artifactId> 
		<version>2.1.1.RELEASE</version> 
	</parent> 
 
	<properties> 
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 
		<java.version>1.8</java.version> 
		<mybatis-spring-boot-starter.version>1.3.2</mybatis-spring-boot-starter.version> 
		<mysql-connector-java.version>8.0.11</mysql-connector-java.version> 
		<com.alibaba.druid.version>1.1.9</com.alibaba.druid.version> 
		<commons-lang.version>2.6</commons-lang.version> 
		<commons-codec.version>1.10</commons-codec.version> 
		<commons-lang3.version>3.8.1</commons-lang3.version> 
		<commons-net.version>3.6</commons-net.version> 
		<commons-io.version>2.6</commons-io.version> 
		<commons-collections.version>3.2.1</commons-collections.version> 
		<common-fileupload.version>1.3.1</common-fileupload.version> 
		<fastjson.version>1.2.48</fastjson.version> 
		<jasperreports.version>6.10.0</jasperreports.version> 
	</properties> 
 
 
	<dependencies> 
		<!-- SpringWeb模块 --> 
		<dependency> 
			<groupId>org.springframework.boot</groupId> 
			<artifactId>spring-boot-starter-web</artifactId> 
		</dependency> 
 
		<!--springboot 集成测试框架 --> 
		<dependency> 
			<groupId>org.springframework.boot</groupId> 
			<artifactId>spring-boot-starter-test</artifactId> 
			<scope>test</scope> 
		</dependency> 
 
 
		<!--lombok插件 --> 
		<dependency> 
			<groupId>org.projectlombok</groupId> 
			<artifactId>lombok</artifactId> 
			<version>${lombok.version}</version> 
			<scope>provided</scope> 
		</dependency> 
 
 
		<!-- mysql 连接 --> 
		<dependency> 
			<groupId>org.mybatis.spring.boot</groupId> 
			<artifactId>mybatis-spring-boot-starter</artifactId> 
			<version>${mybatis-spring-boot-starter.version}</version> 
		</dependency> 
		<dependency> 
			<groupId>mysql</groupId> 
			<artifactId>mysql-connector-java</artifactId> 
			<version>${mysql-connector-java.version}</version> 
			<scope>runtime</scope> 
		</dependency> 
		<dependency> 
			<groupId>com.alibaba</groupId> 
			<artifactId>druid-spring-boot-starter</artifactId> 
			<version>${com.alibaba.druid.version}</version> 
		</dependency> 
		<!-- 分页控件 --> 
		<dependency> 
			<groupId>com.github.pagehelper</groupId> 
			<artifactId>pagehelper</artifactId> 
			<version>4.1.6</version> 
		</dependency> 
 
		<!--common-lang 常用工具包 --> 
		<dependency> 
			<groupId>commons-lang</groupId> 
			<artifactId>commons-lang</artifactId> 
			<version>${commons-lang.version}</version> 
		</dependency> 
		<!--commons-lang3 工具包 --> 
		<dependency> 
			<groupId>org.apache.commons</groupId> 
			<artifactId>commons-lang3</artifactId> 
			<version>${commons-lang3.version}</version> 
		</dependency> 
 
		<!--commons-codec 加密工具包 --> 
		<dependency> 
			<groupId>commons-codec</groupId> 
			<artifactId>commons-codec</artifactId> 
			<version>${commons-codec.version}</version> 
		</dependency> 
		<!--commons-net 网络工具包 --> 
		<dependency> 
			<groupId>commons-net</groupId> 
			<artifactId>commons-net</artifactId> 
			<version>${commons-net.version}</version> 
		</dependency> 
		<!--common-io 工具包 --> 
		<dependency> 
			<groupId>commons-io</groupId> 
			<artifactId>commons-io</artifactId> 
			<version>${commons-io.version}</version> 
		</dependency> 
		<!--common-collection 工具包 --> 
		<dependency> 
			<groupId>commons-collections</groupId> 
			<artifactId>commons-collections</artifactId> 
			<version>${commons-collections.version}</version> 
		</dependency> 
		<!--common-fileupload 工具包 --> 
		<dependency> 
			<groupId>commons-fileupload</groupId> 
			<artifactId>commons-fileupload</artifactId> 
			<version>${common-fileupload.version}</version> 
		</dependency> 
 
		<!-- Swagger2 --> 
		<dependency> 
			<groupId>io.springfox</groupId> 
			<artifactId>springfox-swagger2</artifactId> 
			<version>2.7.0</version> 
		</dependency> 
		<dependency> 
			<groupId>io.springfox</groupId> 
			<artifactId>springfox-swagger-ui</artifactId> 
			<version>2.7.0</version> 
		</dependency> 
 
		<!-- fastjson --> 
		<dependency> 
			<groupId>com.alibaba</groupId> 
			<artifactId>fastjson</artifactId> 
			<version>${fastjson.version}</version> 
		</dependency> 
 
	    <!-- 集成springboot batch 批处理 --> 
		<dependency> 
			<groupId>org.springframework.boot</groupId> 
			<artifactId>spring-boot-starter-batch</artifactId> 
		</dependency> 
 
 
	</dependencies> 
	 
</project>

第二步:application.properties 配置文件

# 指定服务端口 
server.port=7090 
# 指定服务 名称 
# server.context-path=/jreport 
#mybatis xml 文件配置 
mybatis.mapper-locations=classpath*:mapper/batch/*Mapper.xml 
mybatis.type-aliases-package=com.zzg.batch.domain 
# MyBatis mysql8 配置 
spring.datasource.url=jdbc:mysql://192.168.1.**:3306/boot-security?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true&allowMultiQueries=true 
spring.datasource.username=** 
spring.datasource.password=** 
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 
# Druid 配置 
# 初始化时建立物理连接的个数 
spring.datasource.druid.initial-size=5 
# 最大连接池数量 
spring.datasource.druid.max-active=30 
# 最小连接池数量 
spring.datasource.druid.min-idle=5 
# 获取连接时最大等待时间,单位毫秒 
spring.datasource.druid.max-wait=60000 
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 
spring.datasource.druid.time-between-eviction-runs-millis=60000 
# 连接保持空闲而不被驱逐的最小时间 
spring.datasource.druid.min-evictable-idle-time-millis=300000 
# 用来检测连接是否有效的sql,要求是一个查询语句 
spring.datasource.druid.validation-query=SELECT 1 FROM DUAL 
# 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 
spring.datasource.druid.test-while-idle=true 
# 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 
spring.datasource.druid.test-on-borrow=false 
# 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 
spring.datasource.druid.test-on-return=false 
# 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。 
spring.datasource.druid.pool-prepared-statements=true 
# 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。 
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=50 
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计 
#spring.datasource.druid.filters=stat,wall 
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录 
spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500 
# 合并多个DruidDataSource的监控数据 
spring.datasource.druid.use-global-data-source-stat=true 
# 配置sql 注入方式 
spring.datasource.druid.filters=stat 
# 日志文件配置 
logging.config=classpath:logback.xml 
 
# springboot 批处理配置 
spring.batch.job.enabled=false 
spring.batch.initialize-schema=always

第三步:配置类

package com.zzg.batch.config; 
 
import javax.sql.DataSource; 
import org.springframework.batch.core.Job; 
import org.springframework.batch.core.Step; 
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; 
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; 
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; 
import org.springframework.batch.core.launch.support.RunIdIncrementer; 
import org.springframework.batch.core.launch.support.SimpleJobLauncher; 
import org.springframework.batch.core.repository.JobRepository; 
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; 
import org.springframework.batch.item.ItemProcessor; 
import org.springframework.batch.item.ItemReader; 
import org.springframework.batch.item.ItemWriter; 
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider; 
import org.springframework.batch.item.database.JdbcBatchItemWriter; 
import org.springframework.batch.item.file.FlatFileItemReader; 
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper; 
import org.springframework.batch.item.file.mapping.DefaultLineMapper; 
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.core.io.ClassPathResource; 
import org.springframework.transaction.PlatformTransactionManager; 
import com.zzg.batch.domain.AuthUser; 
import com.zzg.batch.processor.CVSItemProcessor; 
import com.zzg.batch.processor.listener.CSVJobListener; 
import com.zzg.batch.processor.validator.BeanValidator; 
/** 
 * springboot batch 配置类 
 * @author zzg 
 * 
 */ 
@Configuration 
@EnableBatchProcessing // 开启批处理的支持 
public class BatchConfig { 
	 
	@Autowired 
	private DataSource dataSource; 
	 
	@Autowired 
	private PlatformTransactionManager transactionManager; 
	 
	 
	/** 
     * ItemReader定义:读取文件数据+entirty映射 
     * @return 
     */ 
    @Bean 
    public ItemReader<AuthUser> reader(){ 
        // 使用FlatFileItemReader去读cvs文件,一行即一条数据 
        FlatFileItemReader<AuthUser> reader = new FlatFileItemReader<>(); 
        // 设置文件处在路径 
        reader.setResource(new ClassPathResource("user.csv")); 
        // entity与csv数据做映射 
        reader.setLineMapper(new DefaultLineMapper<AuthUser>() { 
            { 
                setLineTokenizer(new DelimitedLineTokenizer() { 
                    { 
                        setNames(new String[]{"id", "password"}); 
                    } 
                }); 
                setFieldSetMapper(new BeanWrapperFieldSetMapper<AuthUser>() { 
                    { 
                        setTargetType(AuthUser.class); 
                    } 
                }); 
            } 
        }); 
        return reader; 
    } 
     
    /** 
     * 注册ItemProcessor: 处理数据 
     * @return 
     */ 
    @Bean 
    public ItemProcessor<AuthUser, AuthUser> processor(){ 
    	CVSItemProcessor cvsItemProcessor = new CVSItemProcessor(); 
    	cvsItemProcessor.setValidator(new BeanValidator<AuthUser>()); 
        return cvsItemProcessor; 
    } 
     
    /** 
     * ItemWriter定义:指定datasource,设置批量插入sql语句,写入数据库 
     * @param dataSource 
     * @return 
     */ 
    @Bean 
    public ItemWriter<AuthUser> writer(){ 
        // 使用jdbcBcatchItemWrite写数据到数据库中 
        JdbcBatchItemWriter<AuthUser> writer = new JdbcBatchItemWriter<>(); 
        // 设置有参数的sql语句 
        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<AuthUser>()); 
        String sql = "insert into auth_user (id, password)" + " values(:id, :password)"; 
        writer.setSql(sql); 
        writer.setDataSource(dataSource); 
        return writer; 
    } 
     
    /** 
     * JobRepository定义:设置数据库,注册Job容器 
     * @param dataSource 
     * @param transactionManager 
     * @return 
     * @throws Exception 
     */ 
    @Bean 
    public JobRepository cvsJobRepository() throws Exception{ 
        JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean(); 
        jobRepositoryFactoryBean.setDatabaseType("mysql"); 
        jobRepositoryFactoryBean.setTransactionManager(transactionManager); 
        jobRepositoryFactoryBean.setDataSource(dataSource); 
        return jobRepositoryFactoryBean.getObject(); 
    } 
     
    /** 
     * jobLauncher定义: 
     * @param dataSource 
     * @param transactionManager 
     * @return 
     * @throws Exception 
     */ 
    @Bean 
    public SimpleJobLauncher csvJobLauncher() throws Exception{ 
        SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); 
        // 设置jobRepository 
        jobLauncher.setJobRepository(cvsJobRepository()); 
        return jobLauncher; 
    } 
     
    /** 
     * 定义job 
     * @param jobs 
     * @param step 
     * @return 
     */ 
    @Bean 
    public Job importJob(JobBuilderFactory jobs, Step step){ 
        return jobs.get("importCsvJob") 
                .incrementer(new RunIdIncrementer()) 
                .flow(step) 
                .end() 
                .listener(csvJobListener()) 
                .build(); 
    } 
 
    /** 
     * 注册job监听器 
     * @return 
     */ 
    @Bean 
    public CSVJobListener csvJobListener(){ 
        return new CSVJobListener(); 
    } 
     
    /** 
     * step定义:步骤包括ItemReader->ItemProcessor->ItemWriter 即读取数据->处理校验数据->写入数据 
     * @param stepBuilderFactory 
     * @param reader 
     * @param writer 
     * @param processor 
     * @return 
     */ 
    @Bean 
    public Step step(StepBuilderFactory stepBuilderFactory, ItemReader<AuthUser> reader, 
                     ItemWriter<AuthUser> writer, ItemProcessor<AuthUser, AuthUser> processor){ 
        return stepBuilderFactory 
                .get("step") 
                .<AuthUser, AuthUser>chunk(65000) // Chunk的机制(即每次读取一条数据,再处理一条数据,累积到一定数量后再一次性交给writer进行写入操作) 
                .reader(reader) 
                .processor(processor) 
                .writer(writer) 
                .build(); 
    } 
} 
package com.zzg.batch.config; 
 
import java.util.HashMap; 
import java.util.Map; 
 
import org.springframework.boot.web.servlet.FilterRegistrationBean; 
import org.springframework.boot.web.servlet.ServletRegistrationBean; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
 
import com.alibaba.druid.support.http.StatViewServlet; 
import com.alibaba.druid.support.http.WebStatFilter; 
/** 
 * druid 监控配置 
 * @author zzg 
 * 
 */ 
@Configuration 
public class DruidConfig { 
	 	@Bean 
	    public ServletRegistrationBean druidServletRegistrationBean() { 
	        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(); 
	        servletRegistrationBean.setServlet(new StatViewServlet()); 
	        servletRegistrationBean.addUrlMappings("/druid/*"); 
	        servletRegistrationBean.addInitParameter("allow", ""); 
	        servletRegistrationBean.addInitParameter("deny", ""); 
	        servletRegistrationBean.addInitParameter("loginUsername", "admin"); 
	        servletRegistrationBean.addInitParameter("loginPassword", "admin"); 
	        return servletRegistrationBean; 
	    } 
 
	    /** 
	     * 注册DruidFilter拦截 
	     * 
	     * @return 
	     */ 
	    @Bean 
	    public FilterRegistrationBean duridFilterRegistrationBean() { 
	        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); 
	        filterRegistrationBean.setFilter(new WebStatFilter()); 
	        Map<String, String> initParams = new HashMap<String, String>(); 
	        //设置忽略请求 
	        initParams.put("exclusions", "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"); 
	        filterRegistrationBean.setInitParameters(initParams); 
	        filterRegistrationBean.addUrlPatterns("/*"); 
	        return filterRegistrationBean; 
	    } 
} 
package com.zzg.batch.config; 
 
import java.util.Properties; 
 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
 
import com.github.pagehelper.PageHelper; 
 
/** 
 * mybatis 配置对象 
 * @author zzg 
 * 
 */ 
@Configuration 
public class MyBatisConfig { 
	/** 
	 * 分页对象实列化 
	 * @return 
	 */ 
	@Bean 
	public PageHelper pageHelper() { 
		PageHelper pageHelper = new PageHelper(); 
		Properties p = new Properties(); 
		p.setProperty("offsetAsPageNum", "true"); 
		p.setProperty("rowBoundsWithCount", "true"); 
		p.setProperty("reasonable", "true"); 
		p.setProperty("dialect", "mysql"); 
		pageHelper.setProperties(p); 
		return pageHelper; 
	} 
}
package com.zzg.batch.config; 
 
import java.util.ArrayList; 
import java.util.List; 
 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
 
import io.swagger.annotations.ApiOperation; 
import springfox.documentation.builders.ApiInfoBuilder; 
import springfox.documentation.builders.ParameterBuilder; 
import springfox.documentation.builders.PathSelectors; 
import springfox.documentation.builders.RequestHandlerSelectors; 
import springfox.documentation.schema.ModelRef; 
import springfox.documentation.service.ApiInfo; 
import springfox.documentation.service.Contact; 
import springfox.documentation.service.Parameter; 
import springfox.documentation.spi.DocumentationType; 
import springfox.documentation.spring.web.plugins.Docket; 
import springfox.documentation.swagger2.annotations.EnableSwagger2; 
 
@Configuration 
@EnableSwagger2 
public class SwaggerConfig { 
	@Bean 
	public Docket buildDocket() { 
 
		ParameterBuilder tokenPar = new ParameterBuilder(); 
		List<Parameter> pars = new ArrayList<Parameter>(); 
		tokenPar.name("X-CSRF-TOKEN").description("令牌").modelRef(new ModelRef("string")).parameterType("header") 
				.required(false).build(); 
		pars.add(tokenPar.build()); 
 
		return new Docket(DocumentationType.SWAGGER_2).select() 
				.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any()) 
				.build().globalOperationParameters(pars).apiInfo(buildApiInf()); 
	} 
 
	private ApiInfo buildApiInf() { 
		return new ApiInfoBuilder().title("****").termsOfServiceUrl("http://www.baidu.cn/") 
				.description("API接口") 
				.contact(new Contact("baidu", "http://www.baidu.cn/", "[email protected]")) 
				.version("2.0").build(); 
 
	} 
} 

业务逻辑层代码:model、service、mapper层的相关代码:

package com.zzg.batch.domain; 
 
import java.util.Date; 
 
public class AuthUser { 
    private Integer id; 
 
    private String password; 
 
    private Date lastLogin; 
 
    private String isSuperuser; 
 
    private String username; 
 
    private String firstName; 
 
    private String lastName; 
 
    private String email; 
 
    private String isStaff; 
 
    private String isActive; 
 
    private Date dateJoined; 
 
    public Integer getId() { 
        return id; 
    } 
 
    public void setId(Integer id) { 
        this.id = id; 
    } 
 
    public String getPassword() { 
        return password; 
    } 
 
    public void setPassword(String password) { 
        this.password = password == null ? null : password.trim(); 
    } 
 
    public Date getLastLogin() { 
        return lastLogin; 
    } 
 
    public void setLastLogin(Date lastLogin) { 
        this.lastLogin = lastLogin; 
    } 
 
    public String getIsSuperuser() { 
        return isSuperuser; 
    } 
 
    public void setIsSuperuser(String isSuperuser) { 
        this.isSuperuser = isSuperuser; 
    } 
 
    public String getUsername() { 
        return username; 
    } 
 
    public void setUsername(String username) { 
        this.username = username == null ? null : username.trim(); 
    } 
 
    public String getFirstName() { 
        return firstName; 
    } 
 
    public void setFirstName(String firstName) { 
        this.firstName = firstName == null ? null : firstName.trim(); 
    } 
 
    public String getLastName() { 
        return lastName; 
    } 
 
    public void setLastName(String lastName) { 
        this.lastName = lastName == null ? null : lastName.trim(); 
    } 
 
    public String getEmail() { 
        return email; 
    } 
 
    public void setEmail(String email) { 
        this.email = email == null ? null : email.trim(); 
    } 
 
    public String getIsStaff() { 
        return isStaff; 
    } 
 
    public void setIsStaff(String isStaff) { 
        this.isStaff = isStaff; 
    } 
 
    public String getIsActive() { 
        return isActive; 
    } 
 
    public void setIsActive(String isActive) { 
        this.isActive = isActive; 
    } 
 
    public Date getDateJoined() { 
        return dateJoined; 
    } 
 
    public void setDateJoined(Date dateJoined) { 
        this.dateJoined = dateJoined; 
    } 
}
package com.zzg.batch.mapper; 
 
import java.util.List; 
import java.util.Map; 
import com.zzg.batch.domain.AuthUser; 
 
public interface AuthUserMapper { 
    int deleteByPrimaryKey(Integer id); 
 
    int insert(AuthUser record); 
 
    int insertSelective(AuthUser record); 
 
    AuthUser selectByPrimaryKey(Integer id); 
 
    int updateByPrimaryKeySelective(AuthUser record); 
 
    int updateByPrimaryKey(AuthUser record); 
     
    // 方法梳理 
    List<AuthUser> selectAll(Map<String, Object> paramter); 
}
package com.zzg.batch.service; 
 
import java.util.List; 
import java.util.Map; 
import com.zzg.batch.domain.AuthUser; 
import com.zzg.jreport.common.BaseService; 
import com.zzg.jreport.common.page.PageData; 
import com.zzg.jreport.common.page.PageParam; 
 
public interface AuthUserService extends BaseService<AuthUser> { 
	 // 方法梳理 
    List<AuthUser> selectAll(Map<String, Object> paramter); 
     
    PageData<AuthUser> selectAllPage(Map<String,Object> parame, PageParam rb); 
     
    // 事务测试 
    void transaction(); 
 
} 
package com.zzg.batch.service.impl; 
 
import java.util.List; 
import java.util.Map; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; 
import org.springframework.transaction.annotation.Isolation; 
import org.springframework.transaction.annotation.Propagation; 
import org.springframework.transaction.annotation.Transactional; 
import com.github.pagehelper.PageHelper; 
import com.github.pagehelper.PageInfo; 
import com.zzg.batch.domain.AuthUser; 
import com.zzg.batch.mapper.AuthUserMapper; 
import com.zzg.batch.service.AuthUserService; 
import com.zzg.jreport.common.convert.SimpleTypeConverterUtil; 
import com.zzg.jreport.common.page.PageData; 
import com.zzg.jreport.common.page.PageParam; 
 
@Service 
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class) 
public class AuthUserServiceImpl implements AuthUserService { 
	@Autowired 
	private AuthUserMapper mapper; 
 
	@Override 
	public Long insert(AuthUser entity) { 
		// TODO Auto-generated method stub 
		Integer num = mapper.insertSelective(entity); 
		return Long.valueOf(num); 
	} 
 
	@Override 
	public void updateByPrimaryKeySelective(AuthUser entity) { 
		// TODO Auto-generated method stub 
		mapper.updateByPrimaryKeySelective(entity); 
	} 
 
	@Override 
	public AuthUser selectByPrimaryKey(String sid) { 
		// TODO Auto-generated method stub 
		return mapper.selectByPrimaryKey(SimpleTypeConverterUtil.convertIfNecessary(sid, int.class)); 
	} 
 
	@Override 
	public void deleteByPrimaryKey(String sid) { 
		// TODO Auto-generated method stub 
		mapper.deleteByPrimaryKey(SimpleTypeConverterUtil.convertIfNecessary(sid, int.class)); 
	} 
 
	@Override 
	public List<AuthUser> selectAll(Map<String, Object> paramter) { 
		// TODO Auto-generated method stub 
		return mapper.selectAll(paramter); 
	} 
 
	@Override 
	public PageData<AuthUser> selectAllPage(Map<String, Object> parame, PageParam rb) { 
		// TODO Auto-generated method stub 
		PageData<AuthUser> pageData = new PageData<AuthUser>(); 
 
		PageHelper.startPage(rb.getPageNo(), rb.getLimit()); 
		List<AuthUser> rs = mapper.selectAll(parame); 
 
		PageInfo<AuthUser> pageInfo = new PageInfo<AuthUser>(rs); 
		pageData.setData(pageInfo.getList()); 
		pageData.setPageNum(pageInfo.getPageNum()); 
		pageData.setPageSize(pageInfo.getPageSize()); 
		pageData.setTotalCount(pageInfo.getTotal()); 
		return pageData; 
	} 
 
	@Override 
	public void transaction() { 
		// TODO Auto-generated method stub 
		AuthUser admin = new AuthUser(); 
		admin.setId(1); 
		admin.setUsername("admin"); 
		mapper.updateByPrimaryKeySelective(admin); 
		 
		int a = 1 / 0; 
		 
		AuthUser superMan = new AuthUser(); 
		superMan.setId(2); 
		superMan.setUsername("superMan"); 
		mapper.updateByPrimaryKeySelective(superMan); 
		 
		 
	} 
 
} 
package com.zzg.batch.controller; 
 
import java.util.List; 
import java.util.Map; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestBody; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.ResponseBody; 
import com.alibaba.fastjson.JSONObject; 
import com.zzg.batch.domain.AuthUser; 
import com.zzg.batch.service.AuthUserService; 
import com.zzg.jreport.common.controller.AbstractController; 
import com.zzg.jreport.common.page.PageData; 
import com.zzg.jreport.common.page.PageParam; 
import com.zzg.jreport.response.JreportResponse; 
import io.swagger.annotations.Api; 
import io.swagger.annotations.ApiImplicitParam; 
import io.swagger.annotations.ApiImplicitParams; 
import io.swagger.annotations.ApiOperation; 
import io.swagger.annotations.ApiParam; 
 
@Controller 
@RequestMapping("/api/auth/user") 
@Api(value = "用户Controlle", tags = "用户操作服务") 
public class AuthUserController extends AbstractController { 
 
	@Autowired 
	private AuthUserService service; 
	 
	@ApiOperation(httpMethod = "POST", value = "用户对象保存") 
	@RequestMapping(value = "/insert", method = { RequestMethod.POST }, produces = "application/json;charset=UTF-8") 
	@ResponseBody 
	public JreportResponse insert( 
			@RequestBody @ApiParam(name = "用户对象", value = "json格式对象", required = true) AuthUser entity) { 
		Long engSid = service.insert(entity); 
		return JreportResponse.ok(engSid); 
		 
	} 
	 
	@ApiOperation(httpMethod = "POST", value = "用户对象更新") 
	@RequestMapping(value = "/update", method = { RequestMethod.POST }, produces = "application/json;charset=UTF-8") 
	@ResponseBody 
	public JreportResponse update( 
			@RequestBody @ApiParam(name = "用户对象", value = "json格式对象", required = true) AuthUser entity) { 
		service.updateByPrimaryKeySelective(entity); 
		return JreportResponse.ok(); 
	} 
	 
	@RequestMapping(value="/find", method={RequestMethod.POST}, produces = "application/json;charset=UTF-8") 
	@ResponseBody 
	@ApiOperation(httpMethod = "POST", value = "用户查询") 
	@ApiImplicitParams({ 
		@ApiImplicitParam(name = "id", value = "主键", required = false, dataType = "Integer", paramType = "query"), 
		@ApiImplicitParam(name = "username", value = "用户名称", required = false, dataType = "String", paramType = "query"), 
		@ApiImplicitParam(name = "email", value = "用户邮箱", required = false, dataType = "String", paramType = "query"), 
		@ApiImplicitParam(name = "isStaff", value = "是否在职:1 在职、2:离职", required = false, dataType = "Integer", paramType = "query"), 
		@ApiImplicitParam(name = "isActive", value = "激活状态:1 已激活、2:未激活", required = false, dataType = "Integer", paramType = "query") 
	}) 
	public JreportResponse find(@RequestBody @ApiParam(name = "用户对象", value = "json格式对象", required = true) JSONObject entity) { 
		Map<String, Object> param = JSONObject.toJavaObject(entity, Map.class); 
		List<AuthUser> list = service.selectAll(param); 
		return JreportResponse.ok(list); 
	} 
	 
	 
	@RequestMapping(value="/findByPage", method={RequestMethod.POST}, produces = "application/json;charset=UTF-8") 
	@ResponseBody 
	@ApiOperation(httpMethod = "POST", value = "用户分页查询") 
	@ApiImplicitParams({ 
		@ApiImplicitParam(name = "id", value = "主键", required = false, dataType = "Integer", paramType = "query"), 
		@ApiImplicitParam(name = "username", value = "用户名称", required = false, dataType = "String", paramType = "query"), 
		@ApiImplicitParam(name = "email", value = "用户邮箱", required = false, dataType = "String", paramType = "query"), 
		@ApiImplicitParam(name = "isStaff", value = "是否在职:1 在职、2:离职", required = false, dataType = "Integer", paramType = "query"), 
		@ApiImplicitParam(name = "isActive", value = "激活状态:1 已激活、2:未激活", required = false, dataType = "Integer", paramType = "query") 
	}) 
	public JreportResponse findByPage(@RequestBody @ApiParam(name = "用户对象", value = "json格式对象", required = true) JSONObject entity) { 
 
		Map<String, Object> param = JSONObject.toJavaObject(entity, Map.class); 
		PageParam rb = super.initPageBounds(param); 
		PageData<AuthUser> pageList = service.selectAllPage(param, rb); 
		return JreportResponse.ok(pageList); 
	} 
 
	 
	 
	 
} 
package com.zzg.batch.controller; 
 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.batch.core.Job; 
import org.springframework.batch.core.JobParameters; 
import org.springframework.batch.core.JobParametersBuilder; 
import org.springframework.batch.core.launch.support.SimpleJobLauncher; 
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.RequestMethod; 
import org.springframework.web.bind.annotation.ResponseBody; 
 
import com.zzg.batch.processor.listener.CSVJobListener; 
 
import io.swagger.annotations.Api; 
import io.swagger.annotations.ApiOperation; 
 
 
@Controller 
@RequestMapping("/api/batch") 
@Api(value = "批处理Controlle", tags = "批处理操作服务") 
public class BatchController { 
	// 日志服务处理 
	private Logger logger = LoggerFactory.getLogger(BatchController.class); 
	 
	@Autowired 
	private SimpleJobLauncher  launcher; 
	@Autowired 
	private Job job; 
	 
	@ApiOperation(httpMethod = "POST", value = "用户对象保存") 
	@RequestMapping(value = "/init", method = { RequestMethod.POST }, produces = "application/json;charset=UTF-8") 
	@ResponseBody 
	public void insert() { 
		// 后置参数:使用JobParameters中绑定参数 
		try{ 
			JobParameters jobParameters = new JobParametersBuilder().addLong("time", System.currentTimeMillis()) 
					.toJobParameters(); 
			launcher.run(job, jobParameters); 
			 
		} catch(Exception e){ 
			e.printStackTrace(); 
			logger.error(e.getMessage()); 
		} 
	} 
 
} 
package com.zzg.batch.controller; 
 
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.RequestMethod; 
import org.springframework.web.bind.annotation.ResponseBody; 
import com.zzg.batch.service.AuthUserService; 
import io.swagger.annotations.Api; 
import io.swagger.annotations.ApiOperation; 
 
@Controller 
@RequestMapping("/api/trans") 
@Api(value = "事务处理Controlle", tags = "事务处理操作服务") 
public class TransactionController { 
 
	@Autowired 
	private AuthUserService service; 
	 
	@ApiOperation(httpMethod = "POST", value = "事务功能测试") 
	@RequestMapping(value = "/init", method = { RequestMethod.POST }, produces = "application/json;charset=UTF-8") 
	@ResponseBody 
	public void init() { 
		service.transaction(); 
	} 
 
} 
<?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.zzg.batch.mapper.AuthUserMapper"> 
	<resultMap id="BaseResultMap" type="com.zzg.batch.domain.AuthUser"> 
		<id column="id" jdbcType="INTEGER" property="id" /> 
		<result column="password" jdbcType="VARCHAR" property="password" /> 
		<result column="last_login" jdbcType="TIMESTAMP" property="lastLogin" /> 
		<result column="is_superuser" jdbcType="VARCHAR" property="isSuperuser" /> 
		<result column="username" jdbcType="VARCHAR" property="username" /> 
		<result column="first_name" jdbcType="VARCHAR" property="firstName" /> 
		<result column="last_name" jdbcType="VARCHAR" property="lastName" /> 
		<result column="email" jdbcType="VARCHAR" property="email" /> 
		<result column="is_staff" jdbcType="VARCHAR" property="isStaff" /> 
		<result column="is_active" jdbcType="VARCHAR" property="isActive" /> 
		<result column="date_joined" jdbcType="TIMESTAMP" property="dateJoined" /> 
	</resultMap> 
	<sql id="Base_Column_List"> 
		id, password, last_login, is_superuser, username, 
		first_name, last_name, 
		email, is_staff, 
		is_active, date_joined 
	</sql> 
	<sql id="condition"> 
		<if test="id != null"> 
			and id = #{id} 
		</if> 
		<if test="username != null and username != ''"> 
			and username = #{username} 
		</if> 
		<if test="email != null and email !=''"> 
			and email = #{email} 
		</if> 
		<if test="isStaff != null"> 
			and is_staff = #{isStaff} 
		</if> 
		<if test="isActive != null"> 
			and is_active = #{isActive} 
		</if> 
	</sql> 
	<!-- 方法梳理 --> 
	<select id="selectAll" parameterType="java.util.Map" resultMap="BaseResultMap"> 
		select 
		<include refid="Base_Column_List" /> 
		from auth_user 
		where 1 = 1 
		<include refid="condition"></include> 
	</select> 
 
	<select id="selectByPrimaryKey" parameterType="java.lang.Integer" 
		resultMap="BaseResultMap"> 
		select 
		<include refid="Base_Column_List" /> 
		from auth_user 
		where id = #{id,jdbcType=INTEGER} 
	</select> 
	<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer"> 
		delete from 
		auth_user 
		where id = #{id,jdbcType=INTEGER} 
	</delete> 
	<insert id="insert" parameterType="com.zzg.batch.domain.AuthUser"> 
		insert into auth_user (id, 
		password, last_login, 
		is_superuser, username, first_name, 
		last_name, 
		email, is_staff, 
		is_active, date_joined) 
		values (#{id,jdbcType=INTEGER}, 
		#{password,jdbcType=VARCHAR}, 
		#{lastLogin,jdbcType=TIMESTAMP}, 
		#{isSuperuser,jdbcType=VARCHAR}, #{username,jdbcType=VARCHAR}, 
		#{firstName,jdbcType=VARCHAR}, 
		#{lastName,jdbcType=VARCHAR}, 
		#{email,jdbcType=VARCHAR}, 
		#{isStaff,jdbcType=VARCHAR}, 
		#{isActive,jdbcType=VARCHAR}, #{dateJoined,jdbcType=TIMESTAMP}) 
	</insert> 
	<insert id="insertSelective" parameterType="com.zzg.batch.domain.AuthUser"> 
		insert into auth_user 
		<trim prefix="(" suffix=")" suffixOverrides=","> 
			<if test="id != null"> 
				id, 
			</if> 
			<if test="password != null"> 
				password, 
			</if> 
			<if test="lastLogin != null"> 
				last_login, 
			</if> 
			<if test="isSuperuser != null"> 
				is_superuser, 
			</if> 
			<if test="username != null"> 
				username, 
			</if> 
			<if test="firstName != null"> 
				first_name, 
			</if> 
			<if test="lastName != null"> 
				last_name, 
			</if> 
			<if test="email != null"> 
				email, 
			</if> 
			<if test="isStaff != null"> 
				is_staff, 
			</if> 
			<if test="isActive != null"> 
				is_active, 
			</if> 
			<if test="dateJoined != null"> 
				date_joined, 
			</if> 
		</trim> 
		<trim prefix="values (" suffix=")" suffixOverrides=","> 
			<if test="id != null"> 
				#{id,jdbcType=INTEGER}, 
			</if> 
			<if test="password != null"> 
				#{password,jdbcType=VARCHAR}, 
			</if> 
			<if test="lastLogin != null"> 
				#{lastLogin,jdbcType=TIMESTAMP}, 
			</if> 
			<if test="isSuperuser != null"> 
				#{isSuperuser,jdbcType=VARCHAR}, 
			</if> 
			<if test="username != null"> 
				#{username,jdbcType=VARCHAR}, 
			</if> 
			<if test="firstName != null"> 
				#{firstName,jdbcType=VARCHAR}, 
			</if> 
			<if test="lastName != null"> 
				#{lastName,jdbcType=VARCHAR}, 
			</if> 
			<if test="email != null"> 
				#{email,jdbcType=VARCHAR}, 
			</if> 
			<if test="isStaff != null"> 
				#{isStaff,jdbcType=VARCHAR}, 
			</if> 
			<if test="isActive != null"> 
				#{isActive,jdbcType=VARCHAR}, 
			</if> 
			<if test="dateJoined != null"> 
				#{dateJoined,jdbcType=TIMESTAMP}, 
			</if> 
		</trim> 
	</insert> 
	<update id="updateByPrimaryKeySelective" parameterType="com.zzg.batch.domain.AuthUser"> 
		update auth_user 
		<set> 
			<if test="password != null"> 
				password = #{password,jdbcType=VARCHAR}, 
			</if> 
			<if test="lastLogin != null"> 
				last_login = #{lastLogin,jdbcType=TIMESTAMP}, 
			</if> 
			<if test="isSuperuser != null"> 
				is_superuser = #{isSuperuser,jdbcType=VARCHAR}, 
			</if> 
			<if test="username != null"> 
				username = #{username,jdbcType=VARCHAR}, 
			</if> 
			<if test="firstName != null"> 
				first_name = #{firstName,jdbcType=VARCHAR}, 
			</if> 
			<if test="lastName != null"> 
				last_name = #{lastName,jdbcType=VARCHAR}, 
			</if> 
			<if test="email != null"> 
				email = #{email,jdbcType=VARCHAR}, 
			</if> 
			<if test="isStaff != null"> 
				is_staff = #{isStaff,jdbcType=VARCHAR}, 
			</if> 
			<if test="isActive != null"> 
				is_active = #{isActive,jdbcType=VARCHAR}, 
			</if> 
			<if test="dateJoined != null"> 
				date_joined = #{dateJoined,jdbcType=TIMESTAMP}, 
			</if> 
		</set> 
		where id = #{id,jdbcType=INTEGER} 
	</update> 
	<update id="updateByPrimaryKey" parameterType="com.zzg.batch.domain.AuthUser"> 
		update auth_user 
		set password = #{password,jdbcType=VARCHAR}, 
		last_login = 
		#{lastLogin,jdbcType=TIMESTAMP}, 
		is_superuser = 
		#{isSuperuser,jdbcType=VARCHAR}, 
		username = #{username,jdbcType=VARCHAR}, 
		first_name = #{firstName,jdbcType=VARCHAR}, 
		last_name = 
		#{lastName,jdbcType=VARCHAR}, 
		email = #{email,jdbcType=VARCHAR}, 
		is_staff = #{isStaff,jdbcType=VARCHAR}, 
		is_active = 
		#{isActive,jdbcType=VARCHAR}, 
		date_joined = 
		#{dateJoined,jdbcType=TIMESTAMP} 
		where id = #{id,jdbcType=INTEGER} 
	</update> 
</mapper>

SpringBatch批处理涉及:批处理类、批处理监听器、批处理校验器

package com.zzg.batch.processor; 
 
import org.springframework.batch.item.validator.ValidatingItemProcessor; 
import org.springframework.batch.item.validator.ValidationException; 
 
import com.zzg.batch.domain.AuthUser; 
 
public class CVSItemProcessor extends ValidatingItemProcessor<AuthUser> { 
	 
	// 局部常量 
//	public static final String YES = "1"; 
//	public static final String NO = "2"; 
 
	@Override 
	public AuthUser process(AuthUser item) throws ValidationException { 
		// TODO Auto-generated method stub 
		super.process(item); 
//		if("是".equalsIgnoreCase(item.getIsSuperuser())){ 
//			item.setIsSuperuser(YES); 
//		} else { 
//			item.setIsSuperuser(NO); 
//		} 
//		 
//		if("是".equalsIgnoreCase(item.getIsActive())){ 
//			item.setIsActive(YES); 
//		} else { 
//			item.setIsActive(NO); 
//		} 
//		 
//		if("是".equalsIgnoreCase(item.getIsStaff())){ 
//			item.setIsStaff(YES); 
//		} else { 
//			item.setIsStaff(NO); 
//		} 
		return item; 
	} 
	 
} 
package com.zzg.batch.processor.listener; 
 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.batch.core.JobExecution; 
import org.springframework.batch.core.JobExecutionListener; 
 
public class CSVJobListener implements JobExecutionListener { 
	private Logger logger = LoggerFactory.getLogger(CSVJobListener.class); 
	 
	private long startTime; 
    private long endTime; 
	@Override 
	public void afterJob(JobExecution arg0) { 
		// TODO Auto-generated method stub 
		 endTime = System.currentTimeMillis(); 
	     logger.info("job process end..."); 
	     logger.info("spend time: " + (endTime - startTime) + "ms"); 
	} 
 
	@Override 
	public void beforeJob(JobExecution arg0) { 
		// TODO Auto-generated method stub 
		 startTime = System.currentTimeMillis(); 
	     logger.info("job process start..."); 
	} 
 
} 
package com.zzg.batch.processor.validator; 
 
 
import org.springframework.batch.item.validator.ValidationException; 
import org.springframework.batch.item.validator.Validator; 
import org.springframework.beans.factory.InitializingBean; 
 
public class BeanValidator<T> implements Validator<T>, InitializingBean { 
 
 
	@Override 
	public void afterPropertiesSet() throws Exception { 
	} 
 
	@Override 
	public void validate(T value) throws ValidationException { 
	} 
 
} 

项目整体结构截图:

补全日志配置文件、数据库脚本和测试数据:

<?xml version="1.0" encoding="UTF-8"?>  
   
<!-- 从高到地低 OFF 、 FATAL 、 ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE 、 ALL -->   
<!-- 日志输出规则  根据当前ROOT 级别,日志输出时,级别高于root默认的级别时  会输出 -->   
<!-- 以下  每个配置的 filter 是过滤掉输出文件里面,会出现高级别文件,依然出现低级别的日志信息,通过filter 过滤只记录本级别的日志-->   
   
   
<!-- 属性描述 scan:性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位, 
默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。    
    debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->   
<configuration scan="true" scanPeriod="60 seconds" debug="false">   
    <!-- 定义日志文件 输入位置 -->   
    <property name="log_dir" value="/logs/system-provider" />   
    <!-- 日志最大的历史 30天 -->   
    <property name="maxHistory" value="30"/>   
   
   
    <!-- ConsoleAppender 控制台输出日志 -->   
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">   
        <!-- 对日志进行格式化 -->   
        <encoder>   
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger -%msg%n</pattern>   
        </encoder>   
    </appender>   
       
       
    <!-- ERROR级别日志 -->   
    <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 RollingFileAppender-->   
    <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">   
        <!-- 过滤器,只记录WARN级别的日志 -->   
        <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>${log_dir}/%d{yyyy-MM-dd}/neo4j-error-log.log</fileNamePattern>   
            <!-- 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件假设设置每个月滚动,且<maxHistory>是6,   
            则只保存最近6个月的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除-->   
            <maxHistory>${maxHistory}</maxHistory>   
        </rollingPolicy>   
           
        <!-- 按照固定窗口模式生成日志文件,当文件大于20MB时,生成新的日志文件。窗口大小是1到3,当保存了3个归档文件后,将覆盖最早的日志。    
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">      
          <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/.log.zip</fileNamePattern>      
          <minIndex>1</minIndex>      
          <maxIndex>3</maxIndex>      
        </rollingPolicy>   -->   
        <!-- 查看当前活动文件的大小,如果超过指定大小会告知RollingFileAppender 触发当前活动文件滚动    
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">      
            <maxFileSize>5MB</maxFileSize>      
        </triggeringPolicy>   -->   
           
        <encoder>   
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>   
        </encoder>   
    </appender>   
       
       
    <!-- WARN级别日志 appender -->   
    <appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">   
        <!-- 过滤器,只记录WARN级别的日志 -->   
        <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>${log_dir}/%d{yyyy-MM-dd}/neo4j-warn-log.log   
            </fileNamePattern>   
            <maxHistory>${maxHistory}</maxHistory>   
        </rollingPolicy>   
        <encoder>   
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>   
        </encoder>   
    </appender>   
       
       
    <!-- INFO级别日志 appender -->   
    <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">   
        <!-- 过滤器,只记录INFO级别的日志 -->   
        <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>${log_dir}/%d{yyyy-MM-dd}/neo4j-info-log.log   
            </fileNamePattern>   
            <maxHistory>${maxHistory}</maxHistory>   
        </rollingPolicy>   
        <encoder>   
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>   
        </encoder>   
    </appender>   
       
       
    <!-- DEBUG级别日志 appender -->   
    <appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">   
        <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>${log_dir}/%d{yyyy-MM-dd}/neo4j-debug-log.log   
            </fileNamePattern>   
            <maxHistory>${maxHistory}</maxHistory>   
        </rollingPolicy>   
        <encoder>   
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>   
        </encoder>   
    </appender>   
     
    <logger name="java.sql.PreparedStatement" value="DEBUG" />     
    <logger name="java.sql.Connection" value="DEBUG" />     
    <logger name="java.sql.Statement" value="DEBUG" />     
    <logger name="com.ibatis" value="DEBUG" />     
    <logger name="com.ibatis.common.jdbc.SimpleDataSource" value="DEBUG" />     
    <logger name="com.ibatis.common.jdbc.ScriptRunner" level="DEBUG"/>     
    <logger name="com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate" value="DEBUG" />     
    <logger name="org.springframework.web" level="DEBUG"/> 
    <logger name="com.zzg.jreport" level="DEBUG"/> 
		 
       
    <!-- root级别   DEBUG -->   
    <root level="ERROR">   
        <!-- 控制台输出 -->   
        <appender-ref ref="STDOUT" />   
        <!-- 文件输出 -->   
        <appender-ref ref="ERROR" />   
        <appender-ref ref="INFO" />   
        <appender-ref ref="WARN" />   
        <appender-ref ref="DEBUG" />   
    </root>   
</configuration>

声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

发表评论
搜索
排行榜
关注我们

一个IT知识分享的公众号