逆向工程vgenerator(三)

前言

该项目的最后一篇博文,最终构建,写入文件,整体项目流程将在本片文章中写出。

jdbcType

/**
*@author vvxtoys
*mysql单位 -> jdbcType
*/
package cc.vvxtoys.bean; public enum JdbcType { DATE(",date,year,"),
LONGVARCHAR(",longtext,text,mediumtext,"),
INTEGER(",int,mediumint,"),
REAL(",float,"),
OTHER(",point,multipoint,multilinestring,multipolygon,polygon,geometrycollection,linestring,"),
TINYINT(",tinyint,"),
BIGINT(",bigint,"),
TIMESTAMP(",datetime,timestamp,"),
VARCHAR(",varchar,tinytext,"),
BINARY(",tinyblob,binary,geometry,"),
CHAR(",enum,char,set,"),
DOUBLE(",double,"),
BIT(",bit,"),
SMALLINT(",smallint,"),
LONGVARBINARY(",mediumblob,blob,longblob,"),
DECIMAL(",decimal,"),
VARBINARY(",varbinary,"),
TIME(",time,"); private String type; private JdbcType(String type) {
this.type = type;
} public String getType() {
return type;
} public static String getJdbcType(String dbtype){
if(dbtype.indexOf("(")!=-1){
dbtype = dbtype.substring(0,dbtype.indexOf("("));
}
dbtype = ","+dbtype+",";
for(JdbcType jdbc:JdbcType.values()){
if(jdbc.getType().indexOf(dbtype)!=-1){
return jdbc.name();
}
}
return "OTHER";
}
}

生成xml

/**
*@author vvxtoys
*添加xml节点
*/
package cc.vvxtoys.vgenerator; import java.util.Map; import cc.vvxtoys.bean.XMLBean;
import cc.vvxtoys.factory.MapperFactory;
import cc.vvxtoys.utils.Vconst; public class SqlGenerator { private XMLBean xml;
private int k_size;//主键数
private int c_size;//去除主键列数
private String column;
private String endText = "";//最后一行 where id = "" public static Map<String,String> keys; //主键 name = jdbctype
public static Map<String,String> columns;//列 name = jdbctype public SqlGenerator(XMLBean xml) {
this.xml = xml;
} public void generatorSql(){
if(k_size>0){
generator1();
}else{
generator2();
}
} private void generator1(){
addResultMap();
addSql();
addInsert1();
addInsert2();
addSelect();
addDelete();
addUpdate1();
addUpdate2();
} private void generator2(){
addResultMap();
addSql();
addInsert1();
addInsert2();
} private void addResultMap(){
column = "";
int count = 0;
XMLBean resultMap = new XMLBean("resultMap");
xml.addElement(resultMap);
resultMap.init();
resultMap.addAttribute("id", "BaseResultMap");
resultMap.addAttribute("type", xml.getPojo());
if(k_size>0){
for(String key:keys.keySet()){
XMLBean id = new XMLBean("id");
resultMap.addElement(id);
id.init();
id.addAttribute("column", key);
id.addAttribute("property", key);
id.addAttribute("jdbcType", keys.get(key));
if(count>10){
column+="\n";
count=0;
}
column+=","+key;
count++;
setEndText(key, keys.get(key));
}
}
if(c_size>0){
for(String key:columns.keySet()){
XMLBean result = new XMLBean("result");
resultMap.addElement(result);
result.init();
result.addAttribute("column", key);
result.addAttribute("property", key);
result.addAttribute("jdbcType", columns.get(key));
if(count>10){
column+="\n";
count=0;
}
column+=","+key;
count++;
}
}
} private void addSql(){
XMLBean sql = new XMLBean("sql");
xml.addElement(sql);
sql.init();
sql.addAttribute("id", "Base_Column_List");
sql.addText(column.substring(1));
} private void addSelect(){
XMLBean select = new XMLBean("select");
xml.addElement(select);
select.init();
select.addAttribute("id", Vconst.select);
select.addAttribute("resultMap", "BaseResultMap");
if(k_size==1){
String prefix = "java.lang.";
String type = MapperFactory.ktypes.get(0);
if(type.equalsIgnoreCase("date")){
type = "java.util.Date";
}else{
type = prefix+type;
}
select.addAttribute("parameterType", type);
}
select.addText("select");
XMLBean include = new XMLBean("include");
select.addElement(include);
include.init();
include.addAttribute("refid", "Base_Column_List");
select.addEndText("from "+xml.getTname());
select.addText(getEndText());
} private void addDelete(){
XMLBean delete = new XMLBean("delete");
xml.addElement(delete);
delete.init();
delete.addAttribute("id", Vconst.delete);
if(k_size==1){
String prefix = "java.lang.";
String type = MapperFactory.ktypes.get(0);
if(type.equalsIgnoreCase("date")){
type = "java.util.Date";
}else{
type = prefix+type;
}
delete.addAttribute("parameterType", type);
}
delete.addText("delete from "+xml.getTname());
delete.addText(getEndText());
} private void addInsert1(){
XMLBean insert = new XMLBean("insert");
xml.addElement(insert);
insert.init();
insert.addAttribute("id", Vconst.insert);
insert.addAttribute("parameterType", xml.getPojo());
String attr = null;
String jdbc = null;
int count1 = 0;
int count2 = 0;
if(k_size>0){
for(String key:keys.keySet()){
if(attr==null){
attr = "(";
}else{
attr+=",";
}
if(jdbc==null){
jdbc = "(";
}else{
jdbc+=",";
} if(count1>10){
attr+="\n";
count1=0;
}
if(count2>3){
jdbc+="\n";
count2=0;
}
count1++;
count2++;
attr+=key;
jdbc+="#{"+key+","+"jdbcType="+keys.get(key)+"}";
}
} if(c_size>0){
for(String key:columns.keySet()){
if(attr==null){
attr = "(";
}else{
attr+=",";
}
if(jdbc==null){
jdbc = "(";
}else{
jdbc+=",";
} if(count1>10){
attr+="\n";
count1=0;
}
if(count2>3){
jdbc+="\n";
count2=0;
}
count1++;
count2++;
attr+=key;
jdbc+="#{"+key+","+"jdbcType="+columns.get(key)+"}";
}
}
attr+=")";
jdbc+=")";
insert.addText("insert into "+xml.getTname());
insert.addText(attr);
insert.addText("values");
insert.addText(jdbc);
}
private void addInsert2(){
XMLBean insert = new XMLBean("insert");
xml.addElement(insert);
insert.init();
insert.addAttribute("id", Vconst.insert1);
insert.addAttribute("parameterType", xml.getPojo()); insert.addText("insert into "+xml.getTname());
XMLBean trim = new XMLBean("trim");
insert.addElement(trim);
trim.init();
trim.addAttribute("prefix", "(");
trim.addAttribute("suffix", ")");
trim.addAttribute("suffixOverrides", ",");
if(c_size>0){
for(String key:columns.keySet()){
XMLBean test = new XMLBean("if");
trim.addElement(test);
test.init();
test.addAttribute("test", key+" != null");
test.addText(key+",");
}
}
XMLBean trim1 = new XMLBean("trim");
insert.addElement(trim1);
trim1.init();
trim1.addAttribute("prefix", "values (");
trim1.addAttribute("suffix", ")");
trim1.addAttribute("suffixOverrides", ",");
if(c_size>0){
for(String key:columns.keySet()){
XMLBean test = new XMLBean("if");
trim1.addElement(test);
test.init();
test.addAttribute("test", key+" != null");
test.addText("#{"+key+",jdbcType="+columns.get(key)+"},");
}
}
insert.addEndText(getEndText());
} private void addUpdate1(){
XMLBean update = new XMLBean("update");
xml.addElement(update);
update.init();
update.addAttribute("id", Vconst.update);
update.addAttribute("parameterType", xml.getPojo()); update.addText("update "+xml.getTname());
String content = null;
if(c_size>0){
for(String key:columns.keySet()){
if(content==null){
content = "set ";
}else{
content+=",";
}
content+=key+" = "+"#{"+key+",jdbcType="+columns.get(key)+"}\n";
}
}
update.addText(content);
update.addText(getEndText());
}
private void addUpdate2(){
XMLBean update = new XMLBean("update");
xml.addElement(update);
update.init();
update.addAttribute("id", Vconst.update1);
update.addAttribute("parameterType", xml.getPojo()); update.addText("update "+xml.getTname());
XMLBean set = new XMLBean("set");
update.addElement(set);
set.init();
if(c_size>0){
for(String key:columns.keySet()){
XMLBean test = new XMLBean("if");
set.addElement(test);
test.init();
test.addAttribute("test", key+" != null");
test.addText(key+" = #{"+key+",jdbcType="+columns.get(key)+"},");
}
} update.addEndText(getEndText());
}
private void setEndText(String key,String value){
if(!"".equals(endText)){
endText +=",";
}
endText+=key+" = "+"#{"+key+","+"jdbcType="+value+"}";
} private String getEndText(){
return "where "+endText;
} public void setK_size(int k_size) {
this.k_size = k_size;
} public void setC_size(int c_size) {
this.c_size = c_size;
} }

write类

/**
*@author vvxtoys
*写入项目
*/
package cc.vvxtoys.vgenerator; import java.io.File;
import java.util.ArrayList;
import java.util.List; import cc.vvxtoys.bean.ClassBean;
import cc.vvxtoys.bean.MapperBean;
import cc.vvxtoys.bean.XMLBean;
import cc.vvxtoys.utils.Common; public class VgeneratorWrite { public static List<ClassBean> clazzs = new ArrayList<ClassBean>();
public static List<MapperBean> mappers = new ArrayList<MapperBean>();
public static List<XMLBean> xmls = new ArrayList<XMLBean>(); public void generatorFile() {
generatorClazz();
generatorMapper();
generatorXML();
} private void generatorClazz() {
if (clazzs.size() > 0) {
for (ClassBean bean : clazzs) {
try {
File file = new File(bean.getFileName());
File fileParent = file.getParentFile();
if(!fileParent.exists()){
fileParent.mkdirs();
}
if(file.exists()){
file.delete();
}
file.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
Common.writeFile(bean.getFileName(), bean.getContext());
System.out.println("generator "+bean.getFileName()+" done");
}
}
} private void generatorMapper() {
if (mappers.size() > 0) {
for (MapperBean bean : mappers) {
try {
File file = new File(bean.getFileName());
File fileParent = file.getParentFile();
if(!fileParent.exists()){
fileParent.mkdirs();
}
if(file.exists()){
file.delete();
}
file.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
Common.writeFile(bean.getFileName(), bean.getContext());
System.out.println("generator "+bean.getFileName()+" done");
}
}
} private void generatorXML() {
if (xmls.size() > 0) {
for (XMLBean bean : xmls) {
try {
File file = new File(bean.getFileName());
File fileParent = file.getParentFile();
if(!fileParent.exists()){
fileParent.mkdirs();
}
if(file.exists()){
file.delete();
}
file.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
Common.writeFile(bean.getFileName(), bean.toString());
System.out.println("generator "+bean.getFileName()+" done");
}
}
} }

generator类

/**
*@author vvxtoys
*调用该类实现构建
*/
package cc.vvxtoys.vgenerator; import cc.vvxtoys.config.Engine;
import cc.vvxtoys.factory.VgeneratorFactory; public class Vgenerator { private VgeneratorFactory factory; public Vgenerator() {
factory = new VgeneratorFactory();
} public Vgenerator(String configpath){ Engine.setConfigFile(configpath);
factory = new VgeneratorFactory();
} public void help(){
System.out.println("url :数据库url");
System.out.println("name:服务名称");
System.out.println("user:用户名");
System.out.println("pass:密码");
System.out.println("targetProject:生成相对路径");
System.out.println("targetPackage:实体类包名");
System.out.println("targetMapper : mapper包名");
System.out.println("targetXML : xml包名");
System.out.println("tableName : 表名");
System.out.println("objectName : 实体名");
} public void generator(){
factory.runProperties();
factory.close();
} public void generatorAllFromDB(){
factory.runDB();
factory.close();
}
}

generator工厂

package cc.vvxtoys.factory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import cc.vvxtoys.bean.BaseBean;
import cc.vvxtoys.bean.ClassBean;
import cc.vvxtoys.bean.DBtype;
import cc.vvxtoys.bean.JdbcType;
import cc.vvxtoys.bean.MapperBean;
import cc.vvxtoys.bean.XMLBean;
import cc.vvxtoys.config.DB;
import cc.vvxtoys.config.Engine;
import cc.vvxtoys.utils.Common;
import cc.vvxtoys.utils.Vconst;
import cc.vvxtoys.vgenerator.SqlGenerator;
import cc.vvxtoys.vgenerator.VgeneratorWrite; public class VgeneratorFactory { private VgeneratorWrite write = new VgeneratorWrite();
private Engine engine = Engine.getInstance();
private ClassFactory cF;
private MapperFactory mF;
private XMLFactory xF; public void runProperties(){
DB db = DB.getInstance();
String [] tableNames = Engine.tableName;
String [] objectNames = Engine.objectName;
if(tableNames.length!=objectNames.length){
for(int i=0;i<tableNames.length;i++){
startOperator(tableNames[i], Common.upInitials(tableNames[i]),db);
}
}else{
for(int i=0;i<tableNames.length;i++){
startOperator(tableNames[i], objectNames[i],db);
}
}
} public void runDB(){
DB db = DB.getInstance();
try{
List<String> list = db.getTables();
for(String s:list){
startOperator(s, Common.upInitials(s), db);
}
}catch(Exception e){
e.printStackTrace();
}
} private void startOperator(String tname,String oname,DB db){ SqlGenerator.keys = new HashMap<String, String>();
SqlGenerator.columns = new HashMap<String, String>(); ClassBean bean = new ClassBean(oname);
MapperBean mbean = new MapperBean(oname);
XMLBean xbean = new XMLBean(Vconst.DEFAULT_XML_ROOT,tname,oname); List<String> ps = db.getPrimaryKey(tname);
if(ps==null||ps.size()==0){
mbean.setPrimary(false);
} cF = new ClassFactory(bean);
mF = new MapperFactory(mbean);
xF = new XMLFactory(); int k_size = 0;
int c_size = 0;
List<String> kname = new ArrayList<String>();
List<String> ktype = new ArrayList<String>();
boolean flag = false;//是否存在时间格式
Map<String,String> cs = db.getColumns(tname);
for(Map.Entry<String, String> m:cs.entrySet()){
String name = m.getKey();
String type = m.getValue(); if(mbean.isPrimary()&&ps.contains(name)){
kname.add(name);
ktype.add(DBtype.getModelType(type));
SqlGenerator.keys.put(name, JdbcType.getJdbcType(type));
k_size++;
}else{
SqlGenerator.columns.put(name, JdbcType.getJdbcType(type));
c_size++;
}
cF.addAttribute(DBtype.getModelType(type), name);
if(type.equalsIgnoreCase("date")){
flag = true;
}
}
bean.setDependency(flag);
cF.autoAddMethod();
cF.addConstructor();
cF.loadClass(); MapperFactory.knames = kname;
MapperFactory.ktypes = ktype;
mF.loadMapper(); xF.createDoc(xbean,k_size,c_size); write.generatorFile();
} public void close(){
engine.clear();
} }

流程分析

  • 实例化Vgenerator g

    • 实例化 VgeneratorFactory
      • 实例化 VgeneratorWrite
      • 实例化 Engine
        • 读取配置文件,加载文件保存到静态属性
        • 无参默认使用vgenerator.properties
        • 有参方法设置自定义配置文件,该方法会设置Engine的isDefault属性
  • 调用g.help

    • 输出配置文件注释
  • 调用g.generator() 读取配置文件中的表(支持多表,英文逗号隔开),生成对应的文件

    • factory.runProperties()
      • DB实例化
      • 获得表名和实体类名
        • 开始构建 startOperator()
          • 获得主键和所有列,获得列名和类型,保存到SqlGenerator和MapperFactory
          • 判断是否存在Date类型 设置classBean的dependency属性
          • ClassFactory 生成类文本保存到 classbean的context
            • VgeneratorWrite 保存classbean
          • MapperFactory根据主键生成mapper文本保存到mapperbean的context
            • VgeneratorWrite 保存mapperbean
          • xmlFactory创建文本
            • SqlGenerator根据主键生成对应xml文本保存到xmlbean
              • VgeneratorWrite 保存xmlbean
          • VgeneratorWrite generatorFile生成文件
    • factory.clear() 结束
  • 调用g.generatorAllFromDB() 构建该数据库所有表,除了需要获取所有表,其他流程都一样。

结语

第一个自己写的小项目,虽然有瑕疵,但是感觉还是蛮充实的。下一步需要加强技术了,看看编程思想和设计模式。

上一篇:跨服务器之间的session共享


下一篇:Python学习注脚