- 浏览: 616584 次
- 性别:
- 来自: 上海
-
文章分类
最新评论
-
zhunengfei:
THS!
window.open()打开一个子页面,如何在子页面关闭时刷新父页面? -
kevin_liao:
非常感谢,,各种尝试,用了之后就OK了。。世界突然就安静了
android javax.net.ssl.SSLPeerUnverifiedException: No peer certificate -
上官轩:
XML document structures must start and end within the same entity. -
aaron_brothers:
...
C3P0连接池jar,proxool连接池jar 下载 -
单证员:
...
XML document structures must start and end within the same entity.
有一份应用完整的源码,不过就是缺少了表结构,如果让我根据DO对象一个个去慢慢创建,也是个让人头痛的问题,一是因为有几十个表,二是这个东西拷贝粘贴一点技术含量都没有,这真不是我愿意干的活。本来是想在网上搜索一份这样的工具,关键字到是用了一大堆,中文英文都试过了,如“如何根据SqlMap创建表结构”、"How to generate table from sqlmap"等,还是木有找到,毕竟有几个是像我这样有对象源码却木有表结构的,于是就打算自己搞定了。
幸好我对这份应用本身还是比较熟悉,知道用的是什么样的数据库,文件的命名风格是怎么样的等,想来根据对象生成表结构应该不是什么验事。刚开始想的方式是根据DO对象来生成,后来根据找到的MYSQL字段类型与JAVA对象的映射一看,发现一对多的情况有不少,觉得这种不靠谱,于是就放弃这种方案;后面发现SQLMPA配置文件中有对象与字段的映射,这个倒是省事了,直接分析这个文件就OK了,于是乎就有了下面这些代码:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
/**
* 根据Ibatis的SqlMap配置文件,重新生成表结构。<br>
* 要求所有的sqlmap中对应的字段都有jdbcType这个属性。
*
* @author Administrator 2012-7-2 下午09:33:07
*/
public class Sqlmap2Table {
// 默认所有的varchar都是512,可以保证满足绝大多数的字段
private static final String DEFAULT_VARCHAR_LENGTH = "VARCHAR(256)";
public static void main(String[] args) throws JDOMException, IOException {
String sqlMapPath = "I:/Site/proc/xxx_trunk/dal/src/conf";//这里指定你的sqlmap配置文件所在路径
analysis(sqlMapPath);
}
/**
* 根据指定的目录进行遍历分析
*
* @param path
* @throws IOException
* @throws JDOMException
*/
private static void analysis(String path) throws IOException, JDOMException {
File filePath = new File(path);
if (filePath.isDirectory() && !filePath.getName().equals(".svn")) {
File[] fileList = filePath.listFiles();
for (File file : fileList) {
if (file.isDirectory()) {
analysis(file.getAbsolutePath());
} else {
analysisSqlMap(file.getAbsolutePath());
}
}
}
}
/**
* 分析单个的sqlmap配置文件
*
* @param sqlMapFile
* @throws IOException
* @throws JDOMException
*/
private static void analysisSqlMap(String sqlMapFile) throws IOException, JDOMException {
// System.out.println("************"+sqlMapFile);
boolean isNull=false;
/**
* 这里要把sqlmap文件中的这一行去掉:<br>
* <!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd"><br>
* 否则JDom根据文件创建Document对象时,会报找不到www.ibatis.com这个异常,导致渲染不成功。
*/
String xmlString = filterRead(sqlMapFile, "<!DOCTYPE");
Document doc = getDocument(xmlString);
List<Element> resultMap = (List<Element>) XPath.selectNodes(doc, "//resultMap");
for (Element e : resultMap) {
String alias = e.getAttributeValue("type");
String tableName = getTableName(doc, alias);
List<Element> children = e.getChildren();
StringBuilder createTableString = new StringBuilder("create table " + tableName + "(\n\t");
int size = 0;
for (Element child : children) {
String jdbcType = child.getAttributeValue("jdbcType");
if(StringUtils.isEmpty(jdbcType)){
isNull=true;
break;
}
if (jdbcType.toUpperCase().equals("VARCHAR")) {
jdbcType = DEFAULT_VARCHAR_LENGTH;
}
else if (jdbcType.toUpperCase().equals("CHAR")) {
jdbcType = "char(10)";
}
else if (jdbcType.toUpperCase().equals("BIGINT")) {
jdbcType = "bigint(20)";
}
if (jdbcType.toUpperCase().equals("INTEGER")) {
jdbcType = "int(11)";
}
else if (jdbcType.toUpperCase().equals("DECIMAL")) {
jdbcType = "decimal(10,2)";
}
else if (jdbcType.toUpperCase().equals("NUMERIC")) {
jdbcType = "decimal(10,2)";
}
if (jdbcType.toUpperCase().equals("DOUBLE")) {
jdbcType = "double";
}
if (jdbcType.toUpperCase().equals("REAL")) {
jdbcType = "double";
}
if (jdbcType.toUpperCase().equals("BOOLEAN")) {
jdbcType = "tinyint(1)";
}
if (jdbcType.toUpperCase().equals("FLOAT")) {
jdbcType = "float";
}
createTableString.append(child.getAttributeValue("column")).append(" ").append(jdbcType);
if (size < children.size() - 1) {
createTableString.append(",\n\t");
} else {
createTableString.append("\n");
}
size++;
}
if(isNull){
break;
}
createTableString.append(");");
System.out.println(createTableString.toString().toUpperCase());
}
}
private static String getTableName(Document doc, String alias) throws JDOMException {
String tableName = "";
String classPath = null;
// 这里的alias可能是一个别名,也可能是一个java类路径,这里我通过该alias是否有点"."这个符号来区别
if (alias.indexOf(".") > 0) {// 是JAVA类
classPath = alias;
} else {// 是别名,就到配置的别名中去找
Element aliasElement = (Element) XPath.selectSingleNode(doc, "//typeAlias[@alias=\"" + alias + "\"]");
classPath = aliasElement.getAttributeValue("type");
}
String[] classPathArray = classPath.split("\\.");
// 取到DO的名称
classPath = classPathArray[classPathArray.length - 1];
int i = classPath.lastIndexOf("DO");
// 取到根据表名生成的DO名称,无“DO”两个字符
classPath = classPath.substring(0, i);
char[] chars = classPath.toCharArray();
boolean isFirst = Boolean.TRUE;
// 生成真实的表名
for (char c : chars) {
if (!isFirst && c >= 65 && c <= 90) {
tableName += "_";
}
if (isFirst) {
isFirst = Boolean.FALSE;
}
tableName += c;
}
// 表名转换为大写返回
return tableName.toUpperCase();
}
/**
* 过滤性阅读
*
* @param filePath 文件路径
* @param notIncludeLineStartWith 不包括的字符,即某行的开头是这样的字符串,则在读取的时候该行忽略
* @return
* @throws IOException
*/
private static String filterRead(String filePath, String notIncludeLineStartWith) throws IOException {
String result = "";
FileReader fr = new FileReader(filePath);
BufferedReader br = new BufferedReader(fr);
String line = br.readLine();
while (line != null) {
if (!line.startsWith(notIncludeLineStartWith)) {
result += line;
}
line = br.readLine();
if (line != null && !line.startsWith(notIncludeLineStartWith)) {
result += "\n";
}
}
br.close();
fr.close();
return result;
}
/**
* 根据XML 字符串 建立JDom的Document对象
*
* @param xmlString XML格式的字符串
* @return Document 返回建立的JDom的Document对象,建立不成功将抛出异常。
* @throws IOException
* @throws JDOMException
*/
private static Document getDocument(String xmlString) throws JDOMException, IOException {
SAXBuilder builder = new SAXBuilder();
Document anotherDocument = builder.build(new StringReader(xmlString));
return anotherDocument;
}
}
这里需要JDOM的依赖。
不过需要注意几点:
1、这里体现不出主键、外键关系,没办法,这里只有手工补充了;
2、每个sqlmap的文件中,每个resultMap中的result字段,都必须有jdbcType这一行,否则会报找不到属性的空指针异常,当然这里可以搞一个javaType与jdbcType的映射关系,根据javaType去找jdbcType,我这里用不着,就没有弄了;
3、sqlmap的DOCTYPE在读出来的时候要去掉,否则生成对象的时候会报错。
差不多了,我是跑成功了。
代码在附件,请下载查看。
幸好我对这份应用本身还是比较熟悉,知道用的是什么样的数据库,文件的命名风格是怎么样的等,想来根据对象生成表结构应该不是什么验事。刚开始想的方式是根据DO对象来生成,后来根据找到的MYSQL字段类型与JAVA对象的映射一看,发现一对多的情况有不少,觉得这种不靠谱,于是就放弃这种方案;后面发现SQLMPA配置文件中有对象与字段的映射,这个倒是省事了,直接分析这个文件就OK了,于是乎就有了下面这些代码:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
/**
* 根据Ibatis的SqlMap配置文件,重新生成表结构。<br>
* 要求所有的sqlmap中对应的字段都有jdbcType这个属性。
*
* @author Administrator 2012-7-2 下午09:33:07
*/
public class Sqlmap2Table {
// 默认所有的varchar都是512,可以保证满足绝大多数的字段
private static final String DEFAULT_VARCHAR_LENGTH = "VARCHAR(256)";
public static void main(String[] args) throws JDOMException, IOException {
String sqlMapPath = "I:/Site/proc/xxx_trunk/dal/src/conf";//这里指定你的sqlmap配置文件所在路径
analysis(sqlMapPath);
}
/**
* 根据指定的目录进行遍历分析
*
* @param path
* @throws IOException
* @throws JDOMException
*/
private static void analysis(String path) throws IOException, JDOMException {
File filePath = new File(path);
if (filePath.isDirectory() && !filePath.getName().equals(".svn")) {
File[] fileList = filePath.listFiles();
for (File file : fileList) {
if (file.isDirectory()) {
analysis(file.getAbsolutePath());
} else {
analysisSqlMap(file.getAbsolutePath());
}
}
}
}
/**
* 分析单个的sqlmap配置文件
*
* @param sqlMapFile
* @throws IOException
* @throws JDOMException
*/
private static void analysisSqlMap(String sqlMapFile) throws IOException, JDOMException {
// System.out.println("************"+sqlMapFile);
boolean isNull=false;
/**
* 这里要把sqlmap文件中的这一行去掉:<br>
* <!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd"><br>
* 否则JDom根据文件创建Document对象时,会报找不到www.ibatis.com这个异常,导致渲染不成功。
*/
String xmlString = filterRead(sqlMapFile, "<!DOCTYPE");
Document doc = getDocument(xmlString);
List<Element> resultMap = (List<Element>) XPath.selectNodes(doc, "//resultMap");
for (Element e : resultMap) {
String alias = e.getAttributeValue("type");
String tableName = getTableName(doc, alias);
List<Element> children = e.getChildren();
StringBuilder createTableString = new StringBuilder("create table " + tableName + "(\n\t");
int size = 0;
for (Element child : children) {
String jdbcType = child.getAttributeValue("jdbcType");
if(StringUtils.isEmpty(jdbcType)){
isNull=true;
break;
}
if (jdbcType.toUpperCase().equals("VARCHAR")) {
jdbcType = DEFAULT_VARCHAR_LENGTH;
}
else if (jdbcType.toUpperCase().equals("CHAR")) {
jdbcType = "char(10)";
}
else if (jdbcType.toUpperCase().equals("BIGINT")) {
jdbcType = "bigint(20)";
}
if (jdbcType.toUpperCase().equals("INTEGER")) {
jdbcType = "int(11)";
}
else if (jdbcType.toUpperCase().equals("DECIMAL")) {
jdbcType = "decimal(10,2)";
}
else if (jdbcType.toUpperCase().equals("NUMERIC")) {
jdbcType = "decimal(10,2)";
}
if (jdbcType.toUpperCase().equals("DOUBLE")) {
jdbcType = "double";
}
if (jdbcType.toUpperCase().equals("REAL")) {
jdbcType = "double";
}
if (jdbcType.toUpperCase().equals("BOOLEAN")) {
jdbcType = "tinyint(1)";
}
if (jdbcType.toUpperCase().equals("FLOAT")) {
jdbcType = "float";
}
createTableString.append(child.getAttributeValue("column")).append(" ").append(jdbcType);
if (size < children.size() - 1) {
createTableString.append(",\n\t");
} else {
createTableString.append("\n");
}
size++;
}
if(isNull){
break;
}
createTableString.append(");");
System.out.println(createTableString.toString().toUpperCase());
}
}
private static String getTableName(Document doc, String alias) throws JDOMException {
String tableName = "";
String classPath = null;
// 这里的alias可能是一个别名,也可能是一个java类路径,这里我通过该alias是否有点"."这个符号来区别
if (alias.indexOf(".") > 0) {// 是JAVA类
classPath = alias;
} else {// 是别名,就到配置的别名中去找
Element aliasElement = (Element) XPath.selectSingleNode(doc, "//typeAlias[@alias=\"" + alias + "\"]");
classPath = aliasElement.getAttributeValue("type");
}
String[] classPathArray = classPath.split("\\.");
// 取到DO的名称
classPath = classPathArray[classPathArray.length - 1];
int i = classPath.lastIndexOf("DO");
// 取到根据表名生成的DO名称,无“DO”两个字符
classPath = classPath.substring(0, i);
char[] chars = classPath.toCharArray();
boolean isFirst = Boolean.TRUE;
// 生成真实的表名
for (char c : chars) {
if (!isFirst && c >= 65 && c <= 90) {
tableName += "_";
}
if (isFirst) {
isFirst = Boolean.FALSE;
}
tableName += c;
}
// 表名转换为大写返回
return tableName.toUpperCase();
}
/**
* 过滤性阅读
*
* @param filePath 文件路径
* @param notIncludeLineStartWith 不包括的字符,即某行的开头是这样的字符串,则在读取的时候该行忽略
* @return
* @throws IOException
*/
private static String filterRead(String filePath, String notIncludeLineStartWith) throws IOException {
String result = "";
FileReader fr = new FileReader(filePath);
BufferedReader br = new BufferedReader(fr);
String line = br.readLine();
while (line != null) {
if (!line.startsWith(notIncludeLineStartWith)) {
result += line;
}
line = br.readLine();
if (line != null && !line.startsWith(notIncludeLineStartWith)) {
result += "\n";
}
}
br.close();
fr.close();
return result;
}
/**
* 根据XML 字符串 建立JDom的Document对象
*
* @param xmlString XML格式的字符串
* @return Document 返回建立的JDom的Document对象,建立不成功将抛出异常。
* @throws IOException
* @throws JDOMException
*/
private static Document getDocument(String xmlString) throws JDOMException, IOException {
SAXBuilder builder = new SAXBuilder();
Document anotherDocument = builder.build(new StringReader(xmlString));
return anotherDocument;
}
}
这里需要JDOM的依赖。
不过需要注意几点:
1、这里体现不出主键、外键关系,没办法,这里只有手工补充了;
2、每个sqlmap的文件中,每个resultMap中的result字段,都必须有jdbcType这一行,否则会报找不到属性的空指针异常,当然这里可以搞一个javaType与jdbcType的映射关系,根据javaType去找jdbcType,我这里用不着,就没有弄了;
3、sqlmap的DOCTYPE在读出来的时候要去掉,否则生成对象的时候会报错。
差不多了,我是跑成功了。
代码在附件,请下载查看。
- Sqlmap2Table.zip (2.8 KB)
- 下载次数: 16
发表评论
-
生成一年所有周开始,周结束的数据
2022-08-09 15:56 163public static void main(String[ ... -
生成一年所有周开始,周结束的数据
2022-08-09 15:46 151public static void main(String ... -
springboot使用aop切面做用户操作日志记录
2020-06-18 17:04 1102参考 https://blog.csdn.net/u21330 ... -
软件著作权源代码自动整理60页
2020-04-26 21:18 1110源程序每页不少于50行,最后一页应是程序的结束页 源程序和文档 ... -
解决com.fasterxml.jackson.databind.JsonMappingException: No suitable
2020-04-17 19:54 1067出现com.fasterxml.jackson.databin ... -
idea2017注册码
2020-03-18 17:35 11. 到网站 http://idea.lanyus.com/ ... -
java中怎么跳出两层for循环
2019-09-04 18:30 687在项目中碰到的问题,解决之后就想记录下来;说明一下,该方法是在 ... -
Maven私服上传第三方JAR包 nexus OSS 3.4.0-02
2019-08-09 14:53 785四、登录nexus后台 默认地址 http://localh ... -
Intellij IDEA 自动生成 serialVersionUID
2018-12-27 16:59 3751, Ctrl + Alt + S 调出 Settings 设 ... -
SpringCloud上传文件,中文文件名乱码解决办法
2018-12-22 17:19 556最近在使用SpringCloud搭建微服务的过程中,发现上传文 ... -
java8 LIst操作
2018-11-19 14:57 557java 8 1, 逗号拼接 字符串转 ... -
分布式与集群的区别是什么?
2018-05-17 16:02 371分布式:一个业务分拆多个子业务,部署在不同的服务器上 集群:同 ... -
Spring+dubbo项目错误:Failed to bind NettyServer on /192.168.50.12:31581, cause: Fail
2018-04-11 14:09 20272016-11-30 09:21:02 643 ERROR - ... -
maven package 和 install 区别
2018-03-14 16:26 1461maven package:打包到本项目,一般是在项目targ ... -
在IDEA中如何将Spring boot项目打包成可执行的jar包并发布到linux服务器
2018-03-14 15:20 14101,idea里面通过Maven,选中skip test模式, ... -
split() | 返回的结果不对
2018-01-18 14:08 548split方法的需要的参数是正则表达式,| 在正则表达式中是特 ... -
freemarker展示整数转字符串
2018-01-03 10:55 703${"222.22"?number} ... -
ajaxFileUpload 上传文件
2017-12-07 16:20 530<input type="file" ... -
spring @controller @service @repository @component的作用
2017-12-07 15:55 7121、@controller 控制器(注入服务) 2、@serv ... -
Spring Boot Freemarker特别篇之contextPath【从零开始学Spring Boot】
2017-12-05 15:47 532spring boot + freemarker 怎么获取c ...
相关推荐
根据MyBatis或iBatis的SQLMapper文件解析生成数据库表,通常是指通过解析MyBatis或iBatis的SQLMapper文件中的SQL语句,然后根据这些SQL语句来生成对应的数据库表结构。这样的需求可能源于需要将已有的SQLMapper文件...
Ibatis Helper是专为Ibatis框架设计的代码生成工具,它能够根据数据库表结构快速生成Mapper接口、Mapper XML文件、Service接口、Service实现类以及DAO接口和实体类。通过简单的配置,用户可以定制生成的代码风格和...
本话题将围绕Mybatis的主配置文件、附配置文件、实体类以及SQL生成工具进行详细讲解。 **一、Mybatis主配置文件** Mybatis的主配置文件(通常命名为`mybatis-config.xml`)是整个Mybatis框架的核心,它定义了...
MBG是一个代码生成工具,它可以基于数据库表结构自动生成Java实体类、Mapper接口和XML配置文件。在实际开发中,当数据库表发生变化时,通过MBG可以快速更新相关的Java代码,避免手动维护这些繁琐的细节。 1. **配置...
MyBatis是一个流行的持久层框架,提供了逆向工程功能,可以根据数据库表结构自动生成实体类、DAO接口和Mapping映射文件。本文档将详细介绍MyBatis逆向工程的配置和使用方法。 一、MyBatis逆向工程概述 MyBatis逆向...
### MyBatis详细示例操作知识点解析 #### 一、MyBatis简介及特性 - **定义**:MyBatis是一种优秀的对象关系映射(Object Relational Mapping, ORM)框架,支持基本SQL查询、存储过程及高级映射等功能。通过减少...
这个过程通常涉及到解析数据库结构,生成对应的Java实体类、Mapper接口和XML映射文件。在实际开发中,手动编写这些文件会耗费大量时间,因此自动化的解决方案显得尤为重要。 描述中提到的博客链接可能提供了关于...
iBatis 是一款著名的 Java 数据库访问框架,它在早期版本(iBatis 2)中使用 XML 配置文件来定义 SQL 映射。随着时间的推移,Mybatis(iBatis 的后续版本,目前是 3.x 版本)成为更广泛采用的选择,因为它提供了更...
MyBatis提供逆向工程工具,可以根据数据库表自动生成对应的实体类、Mapper接口和映射文件。 十一、关联查询 通过`<association>`、`<collection>`等标签处理一对多、一对一等关联查询。 总结来说,MyBatis是一个...
《iBATIS-SqlMaps-中文教程》是一个深入解析iBATIS框架的资源,适合对Java Web开发感兴趣的初学者和进阶者。iBATIS是一个持久层框架,它允许开发者将SQL语句直接写在XML配置文件中,实现了SQL与Java代码的分离,简化...
MyBatis逆向工程工具可以帮助开发者自动生成数据库表对应的Java实体类、Mapper接口以及XML映射文件等,极大地提高了开发效率。 总结起来,MyBatis是一个功能强大、易于使用的持久层框架,通过其丰富的特性和灵活的...
8. **Mapper接口与XML映射文件**:Mapper接口定义了数据库操作的方法,XML映射文件描述了这些方法对应的SQL语句和结果映射。MyBatis通过`org.apache.ibatis.builder.MapperBuilderAssistant`来处理Mapper接口和XML...
3. **Mapper 接口**:在 Dao 包中,我们可以定义 MyBatis 的 Mapper 接口,这些接口继承自 `org.apache.ibatis.annotations.Mapper`,并在 XML 文件中编写对应的 SQL 语句。Spring 会自动将这些接口与 XML 映射文件...
3. **动态SQL**:MyBatis支持动态SQL功能,这意味着可以根据不同的条件动态生成SQL语句,大大减少了代码的冗余和重复性工作。 ```xml WHERE column = #{value} </if> ``` 4. **对象映射**:MyBatis支持自动...
标签 "工具" 可能是指Ibatis与开发工具(如IDEA、Eclipse)的集成,或者是指使用其他辅助工具(如MyBatis Generator)来自动生成Ibatis的Mapper接口和映射文件,提高开发效率。 在"压缩包子文件的文件名称列表"中,...
总的来说,Ibatis Generator是MyBatis框架的重要辅助工具,它能够自动化生成数据库访问层的代码,使得开发者可以更加专注于业务逻辑的实现,提升开发效率,降低维护成本。正确配置和使用Ibatis Generator,可以极大...
- MyBatis支持多种动态SQL元素,如`<if>`、`<choose>`、`<when>`、`<otherwise>`、`<foreach>`等,可以在SQL语句中根据条件动态生成SQL片段,提高SQL的灵活性。 #### 7. 关系映射与懒加载 - **关系映射**:MyBatis...