如何使用config.xmlxml网站地图生成器器

基于tinyxml的xml解析代码生成器
平时工作中解析每个xml文件都需要编写一大段代码。终于决心设计一个代码生成器,用于生成读取xml文件的代码。一个xml节点对应于c++中的一个对象,
同时也对应于父节点的成员变量。每个c++对象load函数实现读取自己的属性。基于这个思路来实现生成器。当然xml文件需要添加一个节点&_config/&用于描述每个节点的存储类型和属性值类型。这样利用生成的代码实现解析xml文件只需要两行代码即可完成,即
XXX *p = new XXX(); p-&load(xxx.xml); 就可以完成读取。获取读取的数据更为简单,
p-&对象.对象 即可。
使用的xml示例 ai.xml
&/_config&
解析生成的代码
#ifndef __QQ_H_CONFIG__
#define __QQ_H_CONFIG__
#include "tinyxml.h"
////////////////////////////////////////////////////
//本文件由程序生成。 panqiangqiang
////////////////////////////////////////////////////
struct AiConfig
& & struct
& & struct Ai
& void load(TiXmlElement* e)
& & & action =
e-&Attribute("action");
e-&Attribute("r",r);
& & & str =
e-&Attribute("str");
& & typedef vector
Vector_Ai;
& & typedef Vector_Ai::iterator
& & Vector_Ai
& & void load(TiXmlElement*
& e-&Attribute("id",id);
& TiXmlElement* pAi =
e-&FirstChildElement("ai");
& while(pAi)
ai.load(pAi);
vector_ai.push_back(ai);
& & & pAi =
pAi-&NextSiblingElement("ai");
& & typedef
& & typedef
Map_Script::iterator Iter_
Map_Script map_
& & struct
& & struct Iq
& void load(TiXmlElement* e)
e-&Attribute("value",value);
& & typedef vector
Vector_Iq;
& & typedef Vector_Iq::iterator
& & Vector_Iq
& & void load(TiXmlElement*
& TiXmlElement* pIq =
e-&FirstChildElement("iq");
& while(pIq)
iq.load(pIq);
vector_iq.push_back(iq);
& & & pIq =
pIq-&NextSiblingElement("iq");
& & struct
& & void load(TiXmlElement*
& e-&Attribute("id",id);
& & typedef
vector Vector_H
& & typedef
Vector_Huangshi::iterator Iter_
Vector_Huangshi vector_
& & struct
& & string
& & void load(TiXmlElement*
e-&Attribute("str");
load(TiXmlElement* e)
& & TiXmlElement* pScript =
e-&FirstChildElement("script");
while(pScript)
& script.load(pScript);
& map_script[script.id] =
& pScript =
pScript-&NextSiblingElement("script");
& & TiXmlElement* pGame =
e-&FirstChildElement("game");
game.load(pGame);
& & TiXmlElement* pHuangshi =
e-&FirstChildElement("huangshi");
while(pHuangshi)
& huangshi.load(pHuangshi);
vector_huangshi.push_back(huangshi);
& pHuangshi =
pHuangshi-&NextSiblingElement("huangshi");
& & TiXmlElement* pHp =
e-&FirstChildElement("hp");
hp.load(pHp);
load(char* file)
& & TiXmlDocument
xml(file);
if(!xml.LoadFile())
& & TiXmlHandle
handle(&xml);
& & TiXmlElement *root =
handle.FirstChild("config").ToElement();
load(root);
& & return
生成器核心代码
"tinyxml.h"
struct Tab
Tab(int _deep, int _space =
4, char c = ' '):deep(_deep),space(_space),tabChar(c){}
friend std::ostream&
operator&&(std::ostream& os, const Tab& tab)
return os&&
std::string(tab.deep * tab.space, tab.tabChar);
struct TypeConfig
TypeConfig(TiXmlElement* e,
const char* filename):xmlFileName(filename)
TiXmlElement* pConfig =
e-&FirstChildElement("_config")-&FirstChildElement();
while(pConfig)
TiXmlAttribute* pAtt =
pConfig-&FirstAttribute();
if(!strncmp(pAtt-&Name(),
"container", 10))
containerList[pConfig-&Value()] = pAtt-&Value();
if(!strncmp(pAtt-&Name(), "type", 10))
typeList[pConfig-&Value()] = pAtt-&Value();
pConfig-&NextSiblingElement();
bool isCreateContainer(const
std::string &nodeName)
&containerList.find(nodeName) !=
containerList.end();
const std::string
findContainerTypeByNodeName(const std::string &nodeName)
containerList.find(nodeName);
containerList.end())
return it-&
std::string("vector");
const std::string
findTypeByPropName(const std::string& nodeName)
typeList.find(nodeName);
typeList.end())
return it-&
std::string("string");
typedef std::map
typedef Container::iterator
containerL
Container typeL
const char*
struct Upper
Upper(const char*
upname = new char[32];
bzero(upname, 32);
strncpy(upname, name,
char* headUp()
if(isalpha(upname[0]))
upname[0] =
toupper(upname[0]);
struct PrefixUpper
PrefixUpper(const char*
_nodeName, const char* _xmlName):
nodeName(_nodeName),xmlName(_xmlName)
prefixName = new
bzero(prefixName, 32);
~PrefixUpper()
delete [] prefixN
char* prefixUp()
Upper node(nodeName);
Upper xml(xmlName);
char *pXml =
xml.headUp();
int index = 0;
while(*pXml)
if(*pXml == '.')
prefixName[index++] =
strncpy(&prefixName[index], node.headUp(), 32);
return prefixN
char* prefixN
const char* nodeN
const char* xmlN
struct Uppercase
Uppercase(const char*
_str):str(_str)
upperstr = new
bzero(upperstr, 32);
~Uppercase()
char* up()
int index = 0;
while(*str)
if(*str != '.')
if(isalpha(*str))
upperstr[index++] =
toupper(*str++);
upperstr[index++] =
const char*
struct GenProp
GenProp(std::ofstream&
_os, int _tab, TiXmlAttribute* _attr, TypeConfig*
_typeConfig)
:os(_os),tab(_tab),attr(_attr),typeConfig(_typeConfig)
void gen()
Tab _tab(tab);
while(attr)
std::string type =
typeConfig-&findTypeByPropName(attr-&Name());
if(type == "string")
os&&_tab&&attr-&Name()&&" =
e-&Attribute(""&&attr-&Name()&&"");\n";
else if(type == "int")
os&&_tab&&"e-&Attribute(""&&attr-&Name()&&"","&&attr-&Name()&&");\n";
printf("不能解析变量:%s\t类型:%s\n",
attr-&Name(), type.c_str());
attr-&Next();
std::ofstream&
TiXmlAttribute*
TypeConfig*
struct ContainPush
ContainPush(const char*
_nodeName, const char* _subNodeName,&
std::ofstream& _os,
TypeConfig* _typeConfig,int _tab)
:nodeName(_nodeName),subNodeName(_subNodeName),os(_os),
typeConfig(_typeConfig),tab(_tab)
void push()
contain_var(typeConfig-&findContainerTypeByNodeName(nodeName));
contain_var(typeConfig-&findContainerTypeByNodeName(subNodeName));
var(contain_var);
contain_var += "_";
contain_var +=
Tab t(tab);
if(!strncmp(var.c_str(),
"vector", 10))
os&&t&&contain_var&&".push_back("&&subNodeName&&");\n";
if(!strncmp(var.c_str(), "map", 10))
//os&&t&&contain_var&&".insert("&&subNodeName&&".id,"&&subNodeName&&");\n";
os&&t&&contain_var&&"["&&subNodeName&&".id]
= "&&subNodeName&&";\n";
void declaration()
upperNodeName(nodeName);
string container =
typeConfig-&findContainerTypeByNodeName(nodeName);
upperContainerName(container.c_str());
string defContainer =
upperContainerName.headUp();
defContainer += "_";
defContainer +=
upperNodeName.headUp();
Tab t(tab);
os&&t&&"typedef
if(!strncmp(container.c_str(), "vector", 10))
os&&"&"&&upperNodeName.headUp()&&"&
"&&defContainer&&";\n";
if(!strncmp(container.c_str(), "map", 10))
os&&"&"&&typeConfig-&findTypeByPropName("id");
os&&","&&upperNodeName.headUp()&&"&
"&&defContainer&&";\n";
os&&t&&"typedef
"&&defContainer&&"::iterator
Iter_"&&nodeName&&";\n";
os&&t&&defContainer&&"
"&&container&&"_"&&nodeName&&";\n";
const char* nodeN
const char*
std::ofstream&
TypeConfig*
struct Node
Node(TypeConfig* tc, bool
_root = false):typeConfig(tc),root(_root)
for(It it = subnode.begin();
it != subnode.end(); ++it)
Node* n = *
void parse(TiXmlElement*
TiXmlElement* child =
node-&FirstChildElement();
if(!strncmp(child-&Value(), "_config", 10))
child-&NextSiblingElement();
while(child)
if(!hasParse(child))
Node* n = new
Node(typeConfig);
n-&parse(child);
subnode.push_back(n);
printf("--- 节点:%s\t添加子节点:%s
---\n", node-&Value(), child-&Value());
child-&NextSiblingElement();
child-&NextSiblingElement();
void dump()
TiXmlAttribute* attr =
node-&ToElement()-&FirstAttribute();
while(attr)
cout &&" "&&
attr-&Name() &&"="&& attr-&Value();
attr-&Next();
for(It it = subnode.begin();
&it != subnode.end(); ++it)
Node* n = *
n-&dump();
genFunc(std::ofstream& os, int _tab, TiXmlElement* e)
TiXmlAttribute* attr =
e-&ToElement()-&FirstAttribute();
if(subnode.empty()
Tab tab(_tab);
os&&tab&&"void
load(TiXmlElement* e)\n"&&tab&&"{\n";
Tab tab2(_tab+1);
GenProp genProp(os, _tab +
1, attr, typeConfig);
genProp.gen();
for(It it = subnode.begin();
it != subnode.end(); ++it)
Node* pSubNode = *
const char* pSubNodeName =
pSubNode-&node-&Value();
uper(pSubNodeName);
string point("p");
uper.headUp();
os&&tab2&&"TiXmlElement* "&&point&&" =
os&&"e-&FirstChildElement(""&&pSubNodeName&&"");\n";
Tab tab3(_tab+2);
if(typeConfig-&isCreateContainer(pSubNode-&node-&Value()))
os&&tab2&&"while("&&point&&")\n"&&tab2&&"{\n";
os&&tab3&&uper.headUp()&&"
"&&pSubNodeName&&";\n";
os&&tab3&&pSubNodeName&&".load("&&point&&");\n";
ContainPush
containPush(node-&Value(), pSubNodeName, os,typeConfig, _tab +
containPush.push();
os&&tab3&&point&&" =
"&&point&&"-&NextSiblingElement(""&&pSubNodeName&&"");\n";
os&&tab2&&"}\n";
os&&tab2&&pSubNodeName&&".load("&&point&&");\n";
os&&tab&&"}\n";
void gen(std::ofstream&
os, int _tab)
static bool isAddPrefix =
Tab tab(_tab);
upper(node-&Value());
if(isAddPrefix)
PrefixUpper
prefix(node-&Value(), typeConfig-&xmlFileName);
os&&tab&&"struct\t"&&prefix.prefixUp()&&"\n"&&tab&&"{\n";
isAddPrefix =
os&&tab&&"struct\t"&&upper.headUp()&&"\n"&&tab&&"{\n";
for(It it = subnode.begin();
&it != subnode.end(); ++it)
Node* n = *
n-&gen(os, _tab +
TiXmlAttribute* attr =
node-&ToElement()-&FirstAttribute();
while(attr)
Tab tab1(_tab + 1);
os&&tab1&&typeConfig-&findTypeByPropName(attr-&Name())&&"
"&& attr-&Name() &&";\n";
attr-&Next();
genFunc(os, _tab + 1,
Tab tab1(_tab + 1);
os&&tab1&&"bool
load(char* file)\n"&&tab1&&"{\n";
Tab tab2(_tab + 2);
os&&tab2&&"TiXmlDocument
xml(file);\n"&&tab2&&"if(!xml.LoadFile())\n";
os&&tab2&&"{\n";
Tab tab3(_tab + 3);
os&&tab3&&"return
\n"&&tab2&&"}\n";
os&&tab2&&"TiXmlHandle handle(&xml);\n";
os&&tab2&&"TiXmlElement *root =
handle.FirstChild("config").ToElement();\n";
os&&tab2&&"load(root);\n"&&tab2&&"return
os&&tab1&&"}\n";
os&&tab&&"};\n";
if(typeConfig-&isCreateContainer(node-&Value()))
ContainPush
containPush(node-&Value(), "", os,typeConfig, _tab);
containPush.declaration();
if(strncmp(node-&Value(), "config", 10))
os&&tab&&upper.headUp()&&"
"&&node-&Value()&&";\n";
os&&tab&&"#endif";
bool hasParse(TiXmlElement
for(It it = subnode.begin();
it != subnode.end(); ++it)
Node* thisnode = *
if(!strncmp(thisnode-&node-&Value(), n-&Value(),
TypeConfig
TiXmlElement*
typedef vector::iterator
struct XmlParse
XmlParse(const char*
_xmlfile, const char*
_genfile):xmlfile(_xmlfile),genfile(_genfile)
void autoParse()
TiXmlDocument
xml(xmlfile);
if (!xml.LoadFile())
TiXmlHandle
handle(&xml);
TiXmlElement *root =
handle.FirstChild("config").ToElement();
TypeConfig typeConfig(root,
Node* n = new
Node(&typeConfig, true);
n-&parse(root);
n-&dump();
std::ofstream
os(genfile);
Uppercase up(genfile);
os&&"#ifndef
__"&&up.up()&&"_CONFIG__\n";
os&&"#define
__"&&up.up()&&"_CONFIG__\n";
os&&"#include
"tinyxml.h"\n\n";
os&&"////////////////////////////////////////////////////\n";
os&&"//本文件由程序生成。
panqiangqiang\n";
os&&"////////////////////////////////////////////////////\n\n";
os&&"using namespace
n-&gen(os, 0);
os.close();
const char *
const char *
//编译成器代码
#include "tinyxml.h"
#include "autoparse.cpp"
///////////////////////////////////////////////////////////////////////////////
//生成的代码使用如下:
//AiConfig *aiconfig = new AiConfig();
// aiconfig-&load("ai.xml");
// for(AiConfig::Iter_script it =
aiconfig-&map_script.begin();
// it != aiconfig-&map_script.end(); ++it)
// printf("id:%u\n", it-&first);
// for(AiConfig::Script::Iter_ai _it =
it-&second.vector_ai.begin();
// _it != it-&second.vector_ai.end(); ++_it)
// printf("action:%s\tstr:%s \n", _it-&action.c_str(),
_it-&str.c_str());
// printf("hp str: %s\n", aiconfig-&hp.str.c_str());
///////////////////////////////////////////////////////////////////////////////
DEFINE_string(xml,"", "");
DEFINE_string(out,"", "");
int main(int argc,char **argv)
::google::ParseCommandLineFlags(&argc, &argv,
if(FLAGS_xml.empty() || FLAGS_out.empty())
printf("\n\tUsage:\n\t\t xmlg &-xml xxx.xml
-out xxx.h\n\n");
XmlParse xmlparse(FLAGS_xml.c_str(), FLAGS_out.c_str());
xmlparse.autoParse();
把原创的东西分享出来,如有不妥之处欢迎指正。如有转载,请注明出处。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。EIP、ERP、HIS、B2B、B2C、系统架构、PM管理流程、软件工程、
敏捷开发、CRM、WF、SAAS、SOA、SBPM
&&&&& 本篇主要介绍如何使用现有的技术而不是使用AgileEAS.NET应用开发平台自带的ORM设计器,而是我们实现自己的代码生成器一步一步的。希望大家能在学习的
过程中对代码生成器本身有个更深入的认识与了解,本人技术水平有限,本篇只是抛砖引玉,错误之处,还请大家批评支出。
&&&&& 代码生成器主要的目的,是适应我们自己的已有框架的编码格式,生成我们需要的基础代码。虽然目前开源的代码生成器也比较多,但是有时候我们自己已有一个
比较成熟的,易用的,快速的稳定的开发框架,这时候写个自定义的代码生成器就极其必要。代码生成器的主要目标是根据数据库表结构生成实体层与数据层代码,当
然具体的业务代码可能还要自己手动来做,代码生成器只能生成基本的增删修查的业务代码。
&&&&& 一般情况下我们的代码生成器首先需要与数据库进行关联,或者是从自定义格式文件中动态的读取实体信息。我们从简单的开始吧。我们本篇都已数据库的链接为
例构建简单的代码代码生成器。首先需要一个简单的数据库链接的配置页面,配置文件可以直接通过XML文件来存储,或者不构建这样的可视化的配置界面,直接通过
XML文件来实现。
&&&& 由于本篇意在指导大家来做,所以这里就直接通过XML来配置数据库访问字符串。
&?xml version="1.0" encoding="utf-8" ?& &Connection& & &ConnectionItem name="ConnectionString"& type="SQLServer"&Data Source=.\SQLEXPRESS;Initial Catalog=EasySUser ID=Password=123456&/ConnectionItem& & &ConnectionItem name="ConnectionString1" type="Oracle"&&/ConnectionItem& & &ConnectionItem name="ConnectionString2" type="Access"&&/ConnectionItem& &/Connection&
&&& 首先是根据XML配置文件中读取链接字符串,读取ConnectionString,然后与数据建立链接。
&&& 主要代码如下:
&&&& 该类负责读取XML文档中节点的值
&&&& public class ConfigXml &&& { &&&&&&& public static ConfigX &&&&&&& public static ConfigXml Instance &&&&&&& { &&&&&&&&&&& get &&&&&&&&&&& { &&&&&&&&&&&&&&& if (instance == null) &&&&&&&&&&&&&&&&&&& instance = new ConfigXml(); &&&&&&&&&&&&&&& &&&&&&&&&&& } &&&&&&& }
&&&&&&& public string GetConnectionString(string filename, string type) &&&&&&& { &&&&&&&&&&& string value = string.E
&&&&&&&&&&& string path = System.IO.Directory.GetCurrentDirectory().Replace("\\bin", "") + "/CommonLibary/" + filename + ".xml";
&&&&&&&&&&& XmlDocument doc = new XmlDocument(); &&&&&&&&&&& doc.Load(path);
&&&&&&&&&&& XmlElement root = doc.DocumentE
&&&&&&&&&&& XmlNodeList nodes = root.SelectNodes("ConnectionItem");
&&&&&&&&&&& foreach (XmlNode node in nodes) &&&&&&&&&&& { &&&&&&&&&&&&&&& XmlElement ele = (XmlElement)
&&&&&&&&&&&&&&& if (ele.GetAttribute("type") == type) &&&&&&&&&&&&&&& { &&&&&&&&&&&&&&&&&&& value = ele.InnerT &&&&&&&&&&&&&&& } &&&&&&&&&&& }
&&&&&&&&&&& &&&&&&& } &&& }
&&& 通过这个类文件就可以读取出链接字符串,接下来就是在具体生成代码的主界面中通过这个类提供的方法,从数据库中读取出所有的该数据库下的所有的表,绑定在树形列表中:
&&&& private string connectionString = @"" + ConfigXml.Instance.GetConnectionString("ConfigXmlPath", "SQLServer") + "";
&&&&& public OfficeWordCreator() &&&&&&& { &&&&&&&&&&& InitializeComponent(); &&&&&&&&&&& this.InitInfo(); &&&&&&& }
&&&&&&& private void InitInfo() &&&&&&& { &&&&&&&&&&& SqlAccess sql = new SqlAccess();
&&&&&&&&&&& string sqlText& = " SELECT A.NAME,B.NAME OWNER FROM SYSOBJECTS A LEFT JOIN SYSUSERS B ON A.UID = B.UID& WHERE A.TYPE = 'U' AND A.NAME&&'dtproperties'& ORDER BY A.NAME";
&&&&&&&&&&& sql.ConnectionString = this.connectionS &&&&&&&&&&& this.InitTreeList(sql.Query(sqlText)); &&&&&&& }
private void InitTreeList(DataTable dataTable) &&&&&&& { &&&&&&&&&&& TreeNode root = new TreeNode("数据库表", 0, 1);
&&&&&&&&&&& foreach (System.Data.DataRow row in dataTable.Rows) &&&&&&&&&&& { &&&&&&&&&&&&&&& TreeNode node = new TreeNode(row["name"].ToString(), 2, 3); &&&&&&&&&&&&&&& node.Tag = row["name"].ToString();
&&&&&&&&&&&&&&& root.Nodes.Add(node); &&&&&&&&&&& }
&&&&&&&&&&& this.tvwList.Nodes.Add(root);
&&&&&&&&&&& this.tvwList.ExpandAll(); &&&&&&& }
&&&&&& 绑定后的效果如图:
&&&&&& 接下来我们的操作可能是选择树形的节点后,自动在右侧显示该表中的数据字段。
private void tvwList_AfterSelect(object sender, TreeViewEventArgs e) &&&&&&& { &&&&&&&&&&& if (this.tvwList.SelectedNode == null) &&&&&&&&&&&&&&& &&&&&&&&&&& if (this.tvwList.SelectedNode.Tag == null) &&&&&&&&&&&&&&&
&&&&&&&&&&& this.tbDbName.Text = this.tvwList.SelectedNode.Tag.ToString();
&&&&&&&&&&& StringBuilder sb = new StringBuilder();
&&&&&&&&&&& sb.Append(" SELECT "); &&&&&&&&&&& sb.Append("A.NAME,A.COLID,C.NAME TYPE,A.LENGTH BYTES,COLUMNPROPERTY(A.id,A.name,'precision') LENGTH,"); &&&&&&&&&&& sb.Append("A.XPREC [PRECISION],ISNULL(COLUMNPROPERTY(A.ID,A.NAME,'Scale'),0) SCALE,ISNULL(D.TEXT,'') DEFAULTVALUE,"); &&&&&&&&&&& sb.Append("CASE when exists(SELECT 1 FROM SYSOBJECTS where xtype='PK'and name in (& SELECT NAME FROM sysindexes WHERE indid in( SELECT indid FROM sysindexkeys WHERE id = a.id AND colid=a.colid& )))&&&& then '1' else '0' END PK,"); &&&&&&&&&&& sb.Append("F.NAME TABLE_NAME,F.OWNER TABLE_OWNER "); &&&&&&&&&&& sb.Append("FROM SYSCOLUMNS A LEFT JOIN SYSOBJECTS B ON A.ID = B.ID "); &&&&&&&&&&& sb.Append("LEFT JOIN SYSTYPES C ON A.XTYPE=C.XUSERTYPE "); &&&&&&&&&&& sb.Append("LEFT JOIN SYSCOMMENTS D ON A.CDEFAULT = D.ID "); &&&&&&&&&&& sb.Append("INNER JOIN "); &&&&&&&&&&& sb.Append("(SELECT A.NAME,A.ID,B.NAME OWNER FROM SYSOBJECTS A LEFT JOIN SYSUSERS B ON A.UID = B.UID WHERE A.TYPE = 'U' OR A.TYPE = 'V') F ON A.ID = F.ID "); &&&&&&&&&&& sb.Append(" AND F.NAME='" + this.tbDbName.Text + "' ORDER BY A.COLID");
&&&&&&&&&&& string sqlText = sb.ToString();
&&&&&&&&&&& SqlAccess access = new SqlAccess(); &&&&&&&&&&& access.ConnectionString = this.connectionS
&&&&&&&&&&& this.InitlvwInfo(access.Query(sqlText)); &&&&&&& }
private void InitlvwInfo(DataTable dataTable) &&&&&&& { &&&&&&&&&&& this.lvwInfo.Items.Clear(); &&&&&&&&&&& this.lvwInfo.BeginUpdate();
&&&&&&&&&&& foreach (System.Data.DataRow row in dataTable.Rows) &&&&&&&&&&& { &&&&&&&&&&&&&&& ListViewItem item = new ListViewItem(new string[] { "", row["name"].ToString(), row["type"].ToString(), row["bytes"].ToString(), row["PK"].ToString() == "1" ? "是" : "否" }); &&&&&&&&&&&&&&& item.Tag =
&&&&&&&&&&&&&&& this.lvwInfo.Items.Add(item); &&&&&&&&&&& } &&&&&&&&&&& this.lvwInfo.Tag = dataT
&&&&&&&&&&& this.lvwInfo.EndUpdate(); &&&&&&& }
&&&&&& 通过上面的2个函数即可实现,当选中某个属性节点后,列表中自动显示该表下的所有的列。具体效果如图:
&&&&&& 然后通过选中的字段名称,点击生成文档,然后在不同的文档页面中就生成了不同的代码。
&&&&&&& 当然可能生成的代码还有部分错误,这里只是抛砖引玉。为不熟悉这块内容的朋友提供一个简单的认识。
&&&& 如果各位有好的建议还请多多给我提出改进意见。谢谢您的意见。
阅读(...) 评论()1864人阅读
后台开发(24)
经过前文的叙述,各位看官是不是已经被Mybatis的强大功能给折服了呢?本文我们将介绍一个能够极大提升我们开发效率的插件:即代码自动生成。这里的代码自动生成包括,与一一对应的实体对象,Mapper基本结构文件,与Mapper对应的基本接口文件。本文,我们只介绍这个插件的基本用法,更多内容,就请读者先自行学习吧。
准备工作:
a.操作系统 :win7 x64
b.基本软件:,Mybatis,SQLyog
-------------------------------------------------------------------------------------------------------------------------------------
第一种方式:通过Main方法执行配置文件。
-------------------------------------------------------------------------------------------------------------------------------------
1.创建本文我们将使用的工程Mybatis13,工程结构图如下:【重点文件我们给出,其他配置文件请读者参考前文工程】
2.修改jdbc.properties文件,具体内容如下:
3.修改log4j.properties,具体内容如下:
4.修改mbgConfiguration.xml,具体内容如下:
5.修改GenMain.java文件,具体内容如下:
6.测试方法:运行main方法,然后刷新工程即可。正常情况下:控制台能够看到如下输出,刷新工程后项目列表也能够看到填充文件的变化。
--------------------------------------------------------------------------------------------------------------------------------------------------------
在上面的mbgConfiguration.xml文件中,我们在给出一份更加详细的官方配置地址供读者参考,如下:
【英文版】http://www.mybatis.org/generator/configreference/xmlconfig.html
【中文版】http://generator./configreference/table.html
--------------------------------------------------------------------------------------------------------------------------------------------------------
第二种方式:通过Maven插件运行。
--------------------------------------------------------------------------------------------------------------------------------------------------------
上面我们的工程是通过maven构建的,mybatis generator中也包含了一个可以集成到Maven的插件,具体做法如下:
1.修改pom.xml文件如下:
2.在默认情况下,MBG的配置文件的名称为generatorConfig.xml,并且与上文不同的是,这里需要指明数据库连接器的绝对路径。修改之后的配置文件如下:
3.运行方法:在eclipse 中,选择pom.xml文件,击右键先择Run AS——&Maven Build…
——&在Goals框中输入:mybatis-generator:generate
--------------------------------------------------------------------------------------------------------------------------------------------------------
对比上面两种方式,博主更加倾向于第一种方式,其main方法每次保持不变,xml配置文件中,也不用关心jdbc配置,每次使用时只需要修改其他关键配置项即可。另外,按照官方文档,我们还能够使用命令行,ant等方式实现上述同样的效果。这里博主只列出这两种方式的示例,更多内容请读者自行实现。
最后,在给出一个小建议:在建表时,字段名称建议用&_&分隔多个单词,比如:AWB_NO、REC_ID...,这样生成的entity,属性名称就会变成漂亮的驼峰命名,即:awbNo、recId
--------------------------------------------------------------------------------------------------------------------------------------------------------
至此,Mybatis最入门---代码自动生成(GeneratorCOnfig.xml配置)结束
参考资料:
官方文档:
/yjmyzz/p/4210554.html
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:6682次
排名:千里之外
原创:22篇
转载:43篇
(21)(9)(9)(1)(1)(1)(25)

我要回帖

更多关于 xml生成器 的文章

 

随机推荐