`
ccxw1983
  • 浏览: 27024 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

文本日志中解析数据库表名,以及表名的自动名称映射

阅读更多
工具的开发背景:
crm系统以ework为基础改造而来,以前简单起见和ework混合了代码和表的,现在需要分析,就需要重新分析,哪些是共用的,哪些是私有的。
通过日志中打印的表名,可以分析出哪些表是crm独有的。
通过pdm文件表的创建记录确定哪些表是新表,新的表少,再除去crm独有的,所以方便人工检查哪些是crm专有的。

另外分析了us系统那边用到的表(那边用到的就肯定不能公用),
cas、权限、用户、组织单位、数据字典的肯定是公用的。
另外考虑以前开发中折中,偷懒,有些方法混合了ework、crm一方使用无需用到的表,目前一时没法剥离,需要确定备忘。

总体思路:
日志(或初始化sql脚本)或pdm中分析出来的表名列表结果分别存到集合包里面,通过里面的CollectionTool.java做集合的运算、打印(打印表名、编码、pdm中所属包方便人工判断)、保存。

工具编写匆忙,可能有少量bug和注释不统一的地方,不懂的请研究代码,恕不做技术支持。

工具一共分3部分,这是 日志(或初始化sql脚本) 解析表名的部分。
package chenxiaowen.tool.logs;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeMap;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.MatchResult;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternCompiler;
import org.apache.oro.text.regex.PatternMatcher;
import org.apache.oro.text.regex.PatternMatcherInput;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;

import chenxiaowen.tool.collections.CollectionTool;

/**
 * 解析日志文件,打印表名<br>
 * 表名统一小写
 * 
 * @author 陈小稳 33881270@qq.com
 * 
 */
public class TablesInLogAnalysis {
	public TreeMap<String, Integer> tableTimes = new TreeMap<String, Integer>();
	public String encoding = "UTF-8";

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws Exception {
		TablesInLogAnalysis tool = new TablesInLogAnalysis();
		File baseLogFile = new File("D:\\tomcat\\logs");
		// File baseLogFile = new File("D:\\tomcat\\logs\\test.log");
		tool.analysisAndSaveResultToCollectionFile(baseLogFile, "c.crm.txt");
	}

	/**
	 * 解析日志文件所在目录的日志或单个日志文件,把表名写入集合文件<br>
	 * 如果文件很大导致内存溢出,请配置运行的vm参数,如:-Xms400m -Xmx1024m
	 * 
	 * @param logFile 支持单文件也支持目录
	 * @param recFileName
	 * @throws Exception
	 */
	public void analysisAndSaveResultToCollectionFile(File logFile,
			String recFileName) throws Exception {
		tableTimes.clear();
		analysisTablesInLogDir(logFile);
		StringBuffer b = new StringBuffer();
		for (Iterator iterator = tableTimes.keySet().iterator(); iterator
				.hasNext();) {
			String tbcode = (String) iterator.next();
			b.append(tbcode);
			b.append(",");
		}
		File recFile = new File(CollectionTool.getCollectionDir(), "c.ami.txt");
		if (recFile.exists()) {
			System.out.println("删除已存在日志文件 " + recFile.getAbsolutePath());
			recFile.delete();
		}
		System.out.println("保存日志文件 " + recFile.getAbsolutePath());
		System.out.println("表:");
		System.out.println(b.toString());
		FileUtils.writeStringToFile(recFile, b.toString(), encoding);
	}

	/**
	 * 打印解析的表名
	 * 
	 * @throws IOException
	 */
	public void printTables() throws IOException {
		for (Iterator iterator = tableTimes.keySet().iterator(); iterator
				.hasNext();) {
			String tbcode = (String) iterator.next();
			System.out.println(tbcode + ",");
		}
	}

	/**
	 * 解析目录
	 * 
	 * @param f
	 * @throws IOException
	 */
	public void analysisTablesInLogDir(File f) throws Exception {
		if (f.isDirectory()) {
			File[] fs = f.listFiles();
			for (int i = 0; i < fs.length; i++) {
				analysisTablesInLogDir(fs[i]);
			}
		} else {
			System.out.println("读取解析 " + f.getAbsolutePath());
			String txt = getTextFormFile(f);
			addTableByAnalysis(txt);
		}
	}

	public String getTextFormFile(File f) throws IOException {
		String txt = FileUtils.readFileToString(f, encoding);
		return txt;
	}

	/**
	 * getTextFormFile("test.log")
	 * 
	 * @param filename
	 * @return
	 * @throws IOException
	 */
	public String getTextFormFile(String filename) throws IOException {
		InputStream in = TablesInLogAnalysis.class
				.getResourceAsStream(filename);
		String txt = IOUtils.toString(in, encoding);
		return txt;
	}

	/**
	 * 分析文本内容,添加表到记录
	 * 
	 * @param txt
	 * @throws IOException
	 */
	public void addTableByAnalysis(String txt) throws Exception {
		String regx = "(^|[\\s,])" // 表名前面的间隔符:\s指的空格,可能直接以表名开头,可能是逗号
				+ "((t_|rpt_|dic_)[a-z0-9_]+)"// 表名(pdm叫code)
				+ ""// 后面的不管了
		;
		int[] groupidxs = new int[] { 2 };
		ArrayList<String[]> findstrs = findAllWithGroup(txt, regx, groupidxs);
		for (String[] strs : findstrs) {
			String tbcode = strs[0].toLowerCase();// 统一小写
			tbcode = TableNameProxy.getTranslateTableName(tbcode);// 表名编码映射,如t_a_12
			// 映射t_a_01
			Integer times = tableTimes.get(tbcode);
			if (times == null) {
				tableTimes.put(tbcode, 1);
			} else {
				times++;
				tableTimes.put(tbcode, times);
			}
		}
	}

	/**
	 * 从文件中用正则表达式查找出所有匹配的内容,匹配成功后返回指定组的字符串
	 * 
	 * @param txt
	 * @param regx
	 * @param groupidxs
	 * @return
	 * @throws IOException
	 */
	public static ArrayList<String[]> findAllWithGroup(String txt, String regx,
			int[] groupidxs) throws IOException {
		PatternCompiler compiler = new Perl5Compiler();
		Pattern pattern = null;
		ArrayList<String[]> findstrs = new ArrayList<String[]>();
		try {
			pattern = compiler.compile(regx,
					Perl5Compiler.CASE_INSENSITIVE_MASK);// 大小写不敏感
			PatternMatcher matcher = new Perl5Matcher();
			PatternMatcherInput input = new PatternMatcherInput(txt);
			while (matcher.contains(input, pattern)) {
				MatchResult result = matcher.getMatch();
				String[] rst = new String[groupidxs.length];
				for (int i = 0; i < groupidxs.length; i++) {
					rst[i] = result.group(groupidxs[i]);
				}
				findstrs.add(rst);
			}
		} catch (MalformedPatternException e) {
			e.printStackTrace();
		}

		return findstrs;
	}
}


package chenxiaowen.tool.logs;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternCompiler;
import org.apache.oro.text.regex.PatternMatcher;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;

/**
 * 特殊的表名的映射
 * @author 陈小稳 33881270@qq.com
 *
 */
public class TableNameProxy {

	public static ArrayList<String[]> tableSpecialTranslate = new ArrayList<String[]>();
	// <regx,Pattern>
	public static HashMap<String, Pattern> patternsMap = new HashMap<String, Pattern>();
	// 正规表达式比较批配对象
	public static PatternMatcher matcher = new Perl5Matcher();

	static {
		//TODO 设置这里
		tableSpecialTranslate.add(new String[] { "^T_SET_LOG_\\d\\d$", "t_set_log_01,t_set_log_02" });
		tableSpecialTranslate.add(new String[] { "^T_SET_LOG_MM$", "t_set_log_01,t_set_log_02" });
		
		// 用于定义正规表达式对象模板类型
		PatternCompiler compiler = new Perl5Compiler();
		for (Iterator iterator = tableSpecialTranslate.iterator(); iterator
				.hasNext();) {
			String[] setting = (String[]) iterator.next();
			String regstr = setting[0];
			try {
				// 实例大小写不敏感的正规表达式模板
				Pattern pattern = compiler.compile(regstr,
						Perl5Compiler.CASE_INSENSITIVE_MASK/* 去掉这个参数则敏感 */);
				patternsMap.put(regstr, pattern);
			} catch (MalformedPatternException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * @param args
	 * @throws MalformedPatternException
	 */
	public static void main(String[] args) throws MalformedPatternException {
		String tbstr = "t_1,t_1,t_set_log_02,t_set_log_01,t_set_log_03";
		String[] tbs = tbstr.split(",");
		HashSet<String> distinct = new HashSet<String>();
		
		for (int i = 0; i < tbs.length; i++) {
			String tb = tbs[i];
			tb = getTranslateTableName(tb);
			if(!distinct.contains(tb)){
				distinct.add(tb);
			}
		}

		for (Iterator iterator = distinct.iterator(); iterator.hasNext();) {
			String tb = (String) iterator.next();
			System.out.println(tb);
		}		
	}

	/**
	 * 表名匹配翻译
	 * @param tableName
	 * @return
	 * @throws MalformedPatternException
	 */
	public static String getTranslateTableName(String tableName)
			throws MalformedPatternException {
		for (Iterator iterator = tableSpecialTranslate.iterator(); iterator
				.hasNext();) {
			String[] setting = (String[]) iterator.next();
			String regstr = setting[0];
			Pattern pattern = patternsMap.get(regstr);
			if (matcher.contains(tableName, pattern)) {
				return setting[1].toLowerCase();
			}
		}

		return tableName;
	}

}

分享到:
评论

相关推荐

    kettle批量解析多个xml文件

    在本场景中,我们关注的是如何通过Kettle解析大量XML文件并将数据导入到Oracle数据库。 描述中提到的“批量数据导入”是ETL流程中的关键环节,尤其在生产环境中,数据的高效处理和准确导入至关重要。Kettle提供了...

    纯真IP数据库导入MS SQL SERVER

    这里`IPTable`是你的IP数据库表名,`IPAddress`是IP地址字段名。 2. **性能优化**: 如果需要处理大量查询,可以考虑使用存储过程,或者利用SQL Server的缓存机制,以提高查询效率。 3. **IP范围查询**: 对于IP...

    批量删除文本 很好用

    根据提供的文件信息,我们可以深入探讨与“批量删除文本”相关的知识点,这不仅包括具体的数据库操作,还涉及到了XML配置文件中的SQL映射语句,特别是MyBatis框架中的动态SQL元素。 ### 批量删除文本:概念与应用...

    mysql-slow-log-import-to-elasticsearch:将mysql慢查询日志导入elasticsearch进行分析

    总的来说,"mysql-slow-log-import-to-elasticsearch"项目是数据库性能优化的一个实践,结合了MySQL的日志分析、Awk文本处理、Elasticsearch的存储和检索能力以及Kibana的可视化功能,为企业提供了全面的SQL性能监控...

    DM7_dmfldr使用手册

    - `-controlfile`: 指定控制文件的位置,控制文件用于描述数据文件的结构以及如何将数据加载到数据库中。 - `-datafile`: 指定数据文件的位置,用于装载或导出操作。 - `-log`: 指定日志文件的位置,记录操作过程...

    SQLLOADER

    它可以高效地将外部文件中的数据加载到数据库表中,支持多种数据格式,如文本文件、二进制文件等。SQLLoader 的使用能够极大地提高数据导入的速度,并且可以处理非常大的数据量。 #### 二、SQLLoader 的主要功能 1....

    ORACLE数据导入导出-操作手册.docx

    4. **数据转换**:将Excel中的数据连同表头一同复制到CSV文件中,在此之前需要将Excel中的单元格格式设置为文本格式,以防数据被误解析。 5. **导入操作**:完成上述步骤后,通过Sql Developer的导入功能完成数据...

    discuz 获取xml数据并导入MySQL小插件

    最后,为了确保“能成功使用”,插件可能提供配置选项,让用户自定义数据源、目标表名、处理规则等,以及日志和错误报告功能,便于调试和排查问题。 总的来说,“获取xml数据并导入MySQL小插件”是一个实用工具,它...

    oracle最强大的sqlldr上传工具

    它能够高效地处理文本文件,将数据快速转化为数据库表中的记录,极大地提升了数据导入的效率。SQL*Loader通常用于大规模的数据迁移、数据库初始化或者数据仓库的构建等场景。 1. SQL*Loader的工作原理: SQL*...

    sqluldr2超详细使用教程.7z

    其中,`username/password@database` 是数据库连接信息,`CONTROL=export.ctl` 指定了控制文件,`LOG=export.log` 设置了日志文件。 控制文件(如`export.ctl`)是SQLULDR2的核心,它定义了导出的具体细节,包括...

    大数据技术之hive学习文档

    2. **元数据**:Metastore 存储关于表的元信息,如表名、数据库、字段、表类型和数据路径,推荐使用 MySQL 存储。 3. **Hadoop**:HDFS 存储数据,MapReduce 进行计算。 4. **驱动器**:Driver 包括解析器、编译器、...

    JFIANL学习文档

    根据给定的文件信息,以下是对“JFinal学习文档”中的关键知识点的详细解析: ### JFinal框架概览 JFinal是一款专为Java开发者设计的轻量级、高性能的Web和ORM框架,由詹波于2013年发布。其核心设计理念在于提升...

    华为大数据认证HCIP-Big Data Developer H13-723大数据题库

    从给出的文件信息中,我们可以看出,这些内容是关于华为大数据认证HCIP-Big Data Developer H13-723考试题库的知识点,接下来我将对这些知识点进行详细解析。 1. HBase数据写入接口类:在HBase中写入数据时,我们...

    hive课件.rar

    Hive是由Facebook开发的一个基于Hadoop的数据仓库工具,它可以将结构化的数据文件映射为一张数据库表,并提供SQL(HQL,Hive Query Language)接口进行查询。Hive的设计理念是将SQL语句转化为MapReduce任务,使得非...

    CsvToSql

    只需设置好目标表名、列映射以及数据源,然后调用`WriteToServer`方法即可。 为了确保数据的准确性和完整性,还应考虑错误处理和异常捕获。在读取CSV文件时,可能会遇到格式错误、文件损坏等问题;在写入数据库时,...

Global site tag (gtag.js) - Google Analytics