距离开始使用 Spring Batch 有一段时间了,一直没有时间整理,现在项目即将完结,整理下这段时间学习和使用经历。

官网地址:http://projects.spring.io/spring-batch/

一、定义与特点

A lightweight, comprehensive batch framework designed to enable the development of robust batch applications vital for the daily operations of enterprise systems.

Spring Batch provides reusable functions that are essential in processing large volumes of records, including logging/tracing, transaction management, job processing statistics, job restart, skip, and resource management. It also provides more advanced technical services and features that will enable extremely high-volume and high performance batch jobs through optimization and partitioning techniques. Simple as well as complex, high-volume batch jobs can leverage the framework in a highly scalable manner to process significant volumes of information.

Features

  • Transaction management
  • Chunk based processing
  • Declarative I/O
  • Start/Stop/Restart
  • Rety/Skip
  • Web based administration interface (Spring Batch Admin)

二、简介

Spring Batch 是一个依托 Spring,面向批处理的框架,可以应用于企业级数据处理系统。通过阅读官网文档,可以知道 Spring Batch 的核心组件包括 Job、Step 等。Spring Batch 不仅提供了统一的读写接口、丰富的任务处理方式、灵活的事务管理及并发处理,同时还支持日志、监控、任务重启与跳过等特性,大大简化了批处理应用开发,将开发人员从复杂的任务配置管理过程中解放出来,使他们可以更多地去关注核心的业务处理过程。

使用场景

  • Commit batch process periodically
  • Concurrent batch processing: parallel processing of a job
  • Staged, enterprise message-driven processing
  • Massively parallel batch processing
  • Manual or scheduled restart after failure
  • Sequential processing of dependent steps (with extensions to workflow-driven batches)
  • Partial processing: skip records (e.g. on rollback)
  • Whole-batch transaction: for cases with a small batch size or existing stored procedures/scripts

三、HelloWorld

程序简介:从指定路径的文本文件中逐行读取,获取用户的姓和名,并在处理器中拼接用户的姓名,最后输出用户的姓名。

操作系统:Win7 x64 旗舰版

开发环境:Eclipse 4.3 、JDK1.6

步骤:

1. 搭建开发工程

打开Eclipse, 新建 Java Project ,本例使用 SpringBatchTest 为项目名。

新建 lib 文件夹,导入 SpringBatch 的 Jar 包和其他依赖包。建立相关 package 和 class ,得到结构如下图:

其中 包 和 类 定义:

acc 存放访问控制类(本例准备存放作业测试类)

batch.listener 存放批处理监听器

batch.processor 存放 ItemProcessor实现类

batch.reader 存放 ItemReader 实现类

batch.writer 存放 ItemWriter 实现类

batch.mapper 存放逻辑对象映射处理类(本例准备存放文本行于文本行对象映射处理类)

batch.data 存放批处理过程中使用的逻辑对象

BatchServer.java 定义批处理任务方法接口

配置文件 定义:

spring-application-batch.xml  定义spring batch 核心组件和自定义作业

spring-application-resource.xml  定义spring 组件

spring-application-context.xml  根配置文件,引入使用的配置文件,并控制配置文件引入顺序

2. 编写配置文件和对应的程序代码

由于开发过程中,配置文件和程序是并行书写的,所以以下内容无特定顺序

(1) Spring Batch 配置文件及其中定义的组件实例

spring-application-batch.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:batch="http://www.springframework.org/schema/batch"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  7. http://www.springframework.org/schema/batch
  8. http://www.springframework.org/schema/batch/spring-batch-2.2.xsd"
  9. default-autowire="byName">
  10.  
  11. <!-- Spring Batch 内存模型 -->
  12. <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean" />
  13. <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
  14. <property name="jobRepository" ref="jobRepository" />
  15. </bean>
  16. <bean id="taskExecutor" class="org.springframework.core.task.SyncTaskExecutor" />
  17.  
  18. <!-- 文本行与逻辑对象映射处理 -->
  19. <bean id="customerLineMapper" class="cn.spads.batch.mapper.CustomLineMapper"/>
  20. <bean id="lineTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer" >
  21. <property name="delimiter" value=" "/>
  22. </bean>
  23.  
  24. <!-- Scope = step 变量后绑定固定写法,即可以在对象调用时绑定变量 -->
  25. <bean id="customReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
  26. <property name="lineMapper">
  27. <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
  28. <property name="lineTokenizer" ref="lineTokenizer"/>
  29. <property name="fieldSetMapper" ref="customerLineMapper"/>
  30. </bean>
  31. </property>
  32. <!-- 此处使用单一文件绝对路径 -->
  33. <property name="resource" value="file:#{jobParameters['customFileAbPath']}"/>
  34. </bean>
  35.  
  36. <bean id="customProcessor" class="cn.spads.batch.processor.CustomProcessor"/>
  37. <bean id="customWriter" class="cn.spads.batch.writer.CustomWriter"/>
  38.  
  39. <bean id="customJobListener" class="cn.spads.batch.listener.CustomJobListener"/>
  40. <bean id="customStepListener" class="cn.spads.batch.listener.CustomStepListener"/>
  41.  
  42. <batch:job id="customJob">
  43. <batch:step id="customJob_first_step">
  44. <batch:tasklet>
  45. <batch:chunk reader="customReader" processor="customProcessor"
  46. writer="customWriter" commit-interval="100">
  47. </batch:chunk>
  48. <batch:listeners>
  49. <batch:listener ref="customStepListener" />
  50. </batch:listeners>
  51. </batch:tasklet>
  52. </batch:step>
  53. <batch:listeners>
  54. <batch:listener ref="customJobListener"/>
  55. </batch:listeners>
  56. </batch:job>
  57. </beans>

由于本示例使用Spring Batch 提供 的固定长度文本加载实例(FlatFileItemReader),因此没有自定义 Reader。

LineVo.java

  1. package cn.spads.batch.data;
  2.  
  3. /**
  4. * <b>文本行逻辑对象</b><br>
  5. * @author Gaylen
  6. * @version V1.1.0
  7. * history
  8. * 1.1.0, 2014年11月24日 Gaylen FE
  9. * @since Java 6.0
  10. */
  11. public class LineVo {
  12.  
  13. /** 行号 */
  14. private int id;
  15. /** 名 */
  16. private String givenName;
  17. /** 姓 */
  18. private String familyName;
  19. /** 全名 */
  20. private String fullName;
  21.  
  22. public int getId() {
  23. return id;
  24. }
  25.  
  26. public void setId(int id) {
  27. this.id = id;
  28. }
  29.  
  30. public String getGivenName() {
  31. return givenName;
  32. }
  33.  
  34. public void setGivenName(String givenName) {
  35. this.givenName = givenName;
  36. }
  37.  
  38. public String getFamilyName() {
  39. return familyName;
  40. }
  41.  
  42. public void setFamilyName(String familyName) {
  43. this.familyName = familyName;
  44. }
  45.  
  46. public String getFullName() {
  47. return fullName;
  48. }
  49.  
  50. public void setFullName(String fullName) {
  51. this.fullName = fullName;
  52. }
  53. }

CustomLineMapper.java

  1. package cn.spads.batch.mapper;
  2.  
  3. import org.springframework.batch.item.file.mapping.FieldSetMapper;
  4. import org.springframework.batch.item.file.transform.FieldSet;
  5. import org.springframework.validation.BindException;
  6.  
  7. import cn.spads.batch.data.LineVo;
  8.  
  9. /**
  10. * <b>文本行-逻辑对象映射</b><br>
  11. * @author Gaylen
  12. * @version V1.1.0
  13. * history
  14. * 1.1.0, 2014-11-24 Gaylen FE
  15. * @since Java 6.0
  16. */
  17. public class CustomLineMapper implements FieldSetMapper<LineVo> {
  18.  
  19. /**
  20. * <b>映射处理</b><br>
  21. * @param fieldSet
  22. * @return DelCommandBean
  23. */
  24. @Override
  25. public LineVo mapFieldSet(FieldSet fieldSet) throws BindException {
  26. LineVo lv = new LineVo();
  27. lv.setId(Integer.parseInt(fieldSet.readString(0)));
  28. lv.setGivenName(fieldSet.readString(1));
  29. lv.setFamilyName(fieldSet.readString(2));
  30. return lv;
  31. }
  32. }

CustomProcessor.java

  1. package cn.spads.batch.processor;
  2.  
  3. import org.springframework.batch.item.ItemProcessor;
  4.  
  5. import cn.spads.batch.data.LineVo;
  6.  
  7. /**
  8. * <b>处理器</b><br>
  9. * @author Gaylen
  10. * @version V1.1.0
  11. * history
  12. * 1.1.0, 2014年11月24日 Gaylen FE
  13. * @since Java 6.0
  14. */
  15. public class CustomProcessor implements ItemProcessor<LineVo, LineVo> {
  16.  
  17. @Override
  18. public LineVo process(LineVo item) throws Exception {
  19. if (item == null) {
  20. return null;
  21. }
  22. item.setFullName(new StringBuilder().append(item.getFamilyName() == null ? "*" : item.getFamilyName())
  23. .append(" - ")
  24. .append(item.getGivenName() == null ? "*" : item.getGivenName())
  25. .toString());
  26. return item;
  27. }
  28. }

CustomWriter.java

  1. package cn.spads.batch.writer;
  2.  
  3. import java.util.List;
  4.  
  5. import org.springframework.batch.item.ItemWriter;
  6.  
  7. import cn.spads.batch.data.LineVo;
  8.  
  9. /**
  10. * <b>输出</b><br>
  11. * @author Gaylen
  12. * @version V1.1.0
  13. * history
  14. * 1.1.0, 2014年11月24日 Gaylen FE
  15. * @since Java 6.0
  16. */
  17. public class CustomWriter implements ItemWriter<LineVo> {
  18.  
  19. @Override
  20. public void write(List<? extends LineVo> items) throws Exception {
  21. if (items == null || items.size() == 0) {
  22. System.out.println("error.");
  23. } else {
  24. for (LineVo lv : items) {
  25. System.out.println(lv.getFullName());
  26. }
  27. }
  28.  
  29. }
  30. }

CustomJobListener.javaCustomStepListener.java 本例中只给出空定义。

BatchServer.java

  1. package cn.spads.batch;
  2.  
  3. import java.util.Calendar;
  4. import java.util.Date;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7. import java.util.Map.Entry;
  8.  
  9. import org.springframework.batch.core.Job;
  10. import org.springframework.batch.core.JobExecution;
  11. import org.springframework.batch.core.JobParameter;
  12. import org.springframework.batch.core.JobParameters;
  13. import org.springframework.batch.core.JobParametersInvalidException;
  14. import org.springframework.batch.core.launch.JobLauncher;
  15. import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
  16. import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
  17. import org.springframework.batch.core.repository.JobRestartException;
  18.  
  19. /**
  20. * <b>批处理服务接口</b><br>
  21. * @author Gaylen
  22. * @version V1.1.0
  23. * history
  24. * 1.1.0, 2014年11月24日 Gaylen FE
  25. * @since Java 6.0
  26. */
  27. public class BatchServer {
  28.  
  29. /** 类单例对象 */
  30. private static final BatchServer INSTANCE = new BatchServer();
  31.  
  32. /**
  33. * 单例
  34. * @return
  35. */
  36. public static BatchServer getInstance() {
  37. return INSTANCE;
  38. }
  39.  
  40. /**
  41. * 私有构造方法
  42. */
  43. private BatchServer() {
  44.  
  45. }
  46.  
  47. /**
  48. * <b>测试作业</b><br>
  49. * @param launcher
  50. * @param job
  51. * @param paraMap
  52. */
  53. public void execCustomJob(JobLauncher launcher, Job job, Map<String, Object> paraMap) {
  54. JobExecution result = this.executeBatchJob(launcher, job, this.getJobParameters(paraMap));
  55. System.out.println(result.toString());
  56. }
  57.  
  58. /**
  59. * <b>得到作业选项</b><br>
  60. * 默认配置任务开始时间
  61. * @param paraMap
  62. * @return
  63. */
  64. private JobParameters getJobParameters(Map<String, Object> paraMap) {
  65. HashMap<String, JobParameter> parameters = new HashMap<String, JobParameter>();
  66. parameters.put("time", new JobParameter(Calendar.getInstance().getTimeInMillis()));
  67. String key = null;
  68. Object value = null;
  69.  
  70. if (paraMap == null || paraMap.size() == 0) {
  71. return new JobParameters(parameters);
  72. }
  73.  
  74. for (Entry<String, Object> entry : paraMap.entrySet()) {
  75. if (entry == null) {
  76. continue;
  77. }
  78. key = entry.getKey();
  79. value = entry.getValue();
  80.  
  81. if (value instanceof Date) {
  82. parameters.put(key, new JobParameter((Date) value));
  83. } else if (value instanceof String || value instanceof Integer) {
  84. parameters.put(key, new JobParameter((String) value));
  85. } else if (value instanceof Double) {
  86. parameters.put(key, new JobParameter((Double) value));
  87. } else if (value instanceof Long) {
  88. parameters.put(key, new JobParameter((Long) value));
  89. }
  90. }
  91.  
  92. return new JobParameters(parameters);
  93. }
  94.  
  95. /**
  96. * <b>批处理执行器</b><br>
  97. * @param joblanuncher
  98. * @param job
  99. * @param parameters
  100. */
  101. public JobExecution executeBatchJob(JobLauncher launcher, Job job, JobParameters jobParameters) {
  102. JobExecution result = null;
  103. try {
  104. result = launcher.run(job, jobParameters);
  105. } catch (JobExecutionAlreadyRunningException e) {
  106. e.printStackTrace();
  107. } catch (JobRestartException e) {
  108. e.printStackTrace();
  109. } catch (JobInstanceAlreadyCompleteException e) {
  110. e.printStackTrace();
  111. } catch (JobParametersInvalidException e) {
  112. e.printStackTrace();
  113. }
  114. return result;
  115. }
  116. }

(2) acc 包下 新建测试类 MainTest.java 并在 I盘 新建 SpringBatchTest.txt

  1. package cn.spads.acc;
  2.  
  3. import java.util.HashMap;
  4. import java.util.Map;
  5.  
  6. import org.springframework.batch.core.Job;
  7. import org.springframework.batch.core.launch.JobLauncher;
  8. import org.springframework.context.ApplicationContext;
  9. import org.springframework.context.support.FileSystemXmlApplicationContext;
  10.  
  11. import cn.spads.batch.BatchServer;
  12.  
  13. /**
  14. * <b>批处理测试入口</b><br>
  15. * @author Gaylen
  16. * @version V1.1.0
  17. * history
  18. * 1.1.0, 2014年11月24日 Gaylen FE
  19. * @since Java 6.0
  20. */
  21. public class MainTest {
  22.  
  23. static private String fileLocation = "I:/SpringBatchTest.txt";
  24.  
  25. static private void testCustomJob(ApplicationContext context) {
  26. JobLauncher launcher = (JobLauncher) context.getBean("jobLauncher");
  27. Job job = (Job) context.getBean("customJob");
  28. Map<String, Object> paraMap = new HashMap<String, Object>();
  29. paraMap.put("customFileAbPath", fileLocation);
  30. BatchServer.getInstance().execCustomJob(launcher, job, paraMap);
  31. }
  32.  
  33. public static void main(String[] args) {
  34. ApplicationContext context = new FileSystemXmlApplicationContext("config/spring-application-context.xml");
  35. testCustomJob(context);
  36. }
  37. }
  1. 文本文件(SpringBatchTest.txt)内容如下:
  1. 1
  2. 2
  3. 3
  4. 4

通过以上步骤, project 目录结构应如下图:

3. 至此整个 HelloWorld 项目搭建完成, 可以运行程序,得到输出结果如下: 

  1. 2014-11-25 0:12:28 org.springframework.context.support.FileSystemXmlApplicationContext prepareRefresh
  2. 信息: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@bf32c: startup date [Tue Nov 25 00:12:28 CST 2014]; root of context hierarchy
  3. 2014-11-25 0:12:28 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
  4. 信息: Loading XML bean definitions from file [D:\LocalDEV\workspace43\SpringBatchTest\config\spring-application-context.xml]
  5. 2014-11-25 0:12:28 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
  6. 信息: Loading XML bean definitions from file [D:\LocalDEV\workspace43\SpringBatchTest\config\spring-application-resource.xml]
  7. 2014-11-25 0:12:28 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
  8. 信息: Loading XML bean definitions from file [D:\LocalDEV\workspace43\SpringBatchTest\config\spring-application-batch.xml]
  9. 2014-11-25 0:12:28 org.springframework.beans.factory.support.DefaultListableBeanFactory registerBeanDefinition
  10. 信息: Overriding bean definition for bean 'customJob': replacing [Generic bean: class [org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with [Generic bean: class [org.springframework.batch.core.configuration.xml.JobParserJobFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
  11. 2014-11-25 0:12:28 org.springframework.beans.factory.support.DefaultListableBeanFactory registerBeanDefinition
  12. 信息: Overriding bean definition for bean 'customReader': replacing [Generic bean: class [org.springframework.batch.item.file.FlatFileItemReader]; scope=step; abstract=false; lazyInit=false; autowireMode=1; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\LocalDEV\workspace43\SpringBatchTest\config\spring-application-batch.xml]] with [Root bean: class [org.springframework.aop.scope.ScopedProxyFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in BeanDefinition defined in file [D:\LocalDEV\workspace43\SpringBatchTest\config\spring-application-batch.xml]]
  13. 2014-11-25 0:12:28 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
  14. 信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@157fb52: defining beans [transactionManager,jobRepository,jobLauncher,taskExecutor,customerLineMapper,lineTokenizer,customReader,customProcessor,customWriter,customJobListener,customStepListener,org.springframework.batch.core.scope.internalStepScope,org.springframework.beans.factory.config.CustomEditorConfigurer,org.springframework.batch.core.configuration.xml.CoreNamespacePostProcessor,customJob_first_step,customJob,scopedTarget.customReader]; root of factory hierarchy
  15. 2014-11-25 0:12:28 org.springframework.batch.core.launch.support.SimpleJobLauncher run
  16. 信息: Job: [FlowJob: [name=customJob]] launched with the following parameters: [{time=1416845548796, customFileAbPath=I:/SpringBatchTest.txt}]
  17. 2014-11-25 0:12:28 org.springframework.batch.core.job.SimpleStepHandler handleStep
  18. 信息: Executing step: [customJob_first_step]
  19. -
  20. -
  21. -
  22. -
  23. 2014-11-25 0:12:28 org.springframework.batch.core.launch.support.SimpleJobLauncher run
  24. 信息: Job: [FlowJob: [name=customJob]] completed with the following parameters: [{time=1416845548796, customFileAbPath=I:/SpringBatchTest.txt}] and the following status: [COMPLETED]
  25. JobExecution: id=0, version=2, startTime=Tue Nov 25 00:12:28 CST 2014, endTime=Tue Nov 25 00:12:28 CST 2014, lastUpdated=Tue Nov 25 00:12:28 CST 2014, status=COMPLETED, exitStatus=exitCode=COMPLETED;exitDescription=, job=[JobInstance: id=0, version=0, Job=[customJob]], jobParameters=[{time=1416845548796, customFileAbPath=I:/SpringBatchTest.txt}]

总结:本篇文章简单介绍了 Spring Batch,以及使用 Spring Batch 开发 HelloWorld 程序。

本文中使用 Project 源码可以从此处下载:http://download.csdn.net/detail/driftingshine/8194729

[Spring Batch 系列] 第一节 初识 Spring Batch的更多相关文章

  1. Spring之旅第一篇-初识Spring

    一.概述 只要用框架开发java,一定躲不过spring,Spring是一个轻量级的Java开源框架,存在的目的是用于构建轻量级的J2EE应用.Spring的核心是控制反转(IOC)和面向切面编程(A ...

  2. Spring学习笔记第一篇——初识Spring

    1.简单介绍 spring的ioc底层是先配置xml文件,接着创建工厂,利用dom4j解析配置文件,最后通过反射完成.大概步骤差不多这样,这些具体代码spring帮你完成了.现在我们只需要配置xml和 ...

  3. spring cloud 入门系列一:初识spring cloud

    最近看到微服务很火,也是未来的趋势, 所以就去学习下,在dubbo和spring cloud之间我选择了从spring cloud,主要有如下几种原因: dubbo主要专注于微服务中的一个环节--服务 ...

  4. Spring Boot2 系列教程(二十)Spring Boot 整合JdbcTemplate 多数据源

    多数据源配置也算是一个常见的开发需求,Spring 和 SpringBoot 中,对此都有相应的解决方案,不过一般来说,如果有多数据源的需求,我还是建议首选分布式数据库中间件 MyCat 去解决相关问 ...

  5. spring boot系列(五)spring boot 配置spring data jpa (查询方法)

    接着上面spring boot系列(四)spring boot 配置spring data jpa 保存修改方法继续做查询的测试: 1 创建UserInfo实体类,代码和https://www.cnb ...

  6. 深入理解Spring(一):初识Spring

    深入理解Spring(一):初识Spring 一. Spring介绍        Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnso ...

  7. 第一节 初识RabbitMQ

    原文:第一节 初识RabbitMQ 版权声明:未经本人同意,不得转载该文章,谢谢 https://blog.csdn.net/phocus1/article/details/87280120 1.什么 ...

  8. Spring Boot系列(一) Spring Boot介绍和基础POM文件

    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过 ...

  9. 深入理解javascript对象系列第一篇——初识对象

    × 目录 [1]定义 [2]创建 [3]组成[4]引用[5]方法 前面的话 javascript中的难点是函数.对象和继承,前面已经介绍过函数系列.从本系列开始介绍对象部分,本文是该系列的第一篇——初 ...

随机推荐

  1. 使用 PHPMailer 发邮件

    /** * 发邮件 * * @param array $receiver 接收人信息 * @param array $attachment_info 附件信息 * @param string $is_ ...

  2. (42)C#Stopwatch类(计算程序运行时间)

    引入命名空间 using System.Diagnostics; static void Main(string[] args) { Stopwatch sw = new Stopwatch(); s ...

  3. FZU 2122 又见LKity【字符串/正难则反/KMP/把一个字符串中某个部分替换为另一个部分】

    嗨!大家好,在TempleRun中大家都认识我了吧.我是又笨又穷的猫猫LKity.很高兴这次又与各位FZU的ACMer见面了.最近见到FZU的各位ACMer都在刻苦地集训,整天在日光浴中闲得发慌的我压 ...

  4. ES6之Array.includes()函数

    一.定义 includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false. 二.语法 arr.includes(searchElement) arr.includ ...

  5. POJ 3140 Contestants Division (树dp)

    题目链接:http://poj.org/problem?id=3140 题意: 给你一棵树,问你删去一条边,形成的两棵子树的节点权值之差最小是多少. 思路: dfs #include <iost ...

  6. mysql InnoDb存储引擎索引

    B+树索引:使用B+树索引查找数据时,并不能找到一个给定键值的具体行,只是找到被查找数据行所在的页,然后数据库通过把页读取到内存,再在内存中进行查找,最后得到要查找的数据. 聚集索引:按照表中主键构造 ...

  7. BT原理分析(转)

    BT种子文件结构分析,参考:http://www.cnblogs.com/EasonJim/p/6601047.html BT下载,参考:http://baike.baidu.com/item/BT下 ...

  8. sql-server-next-version-ctp-1-4-now-available

    https://blogs.technet.microsoft.com/dataplatforminsider/2017/03/17/sql-server-next-version-ctp-1-4-n ...

  9. 分享tiny4412,emmc烧录u-boot, 支持fastboot模式烧写emmc

    转载 : http://www.arm9home.net/read.php?tid-83474.html 本人是第一次在此发帖,希望大家多多支持,发帖目的是为了分享,分享的目的是传递开源的精神.Tin ...

  10. NHibernate剖析:Mapping篇之Mapping-By-Code(1):概览

    ModelMapper概述 NHibernate3.2版本号集成Mapping-By-Code(代码映射),其设计思想来源于ConfORM.代码总体构思基于"Loquacious" ...