ORM(手写简单ORM)

ORM(Object Relation Mapping,对象关系映射)

表结构<–>类 表中字段 <–>类的属性 表中记录<–>对象

简单完成从数据库到对象的映射

定义javabean类

①TableInfo
存储表的结构和相关信息
②ColumnInfo
存储表中字段相关信息
③configuration
读相关配置信息
④FiledSetGet
存储一个字段转换的属性和set、get方法

进行数据库的连接

使用configuraction对象中的driver、url、user、pwd建立Connection对象

conn = DriverManager.getConnection(conf.getUrl(),conf.getUser(),conf.getPwd());

提取数据库的信息

使用Connection对象来获取到DatabaseMetaData对象
然后通过DatabaseMetaData对象可以获得表信息和字段信息
此时可使用TableInfo和ColumnInfo对获取到的信息进行存储

	public static Map<String, TableInfo> tables = new HashMap<String, TableInfo>();

	Connection conn = DBManager.getConn();
   
   	DatabaseMetaData dbmd = conn.getMetaData();
  	 //获取库中所有的表(数据库名、表架构、表名、类型(TABLE、VIEW))
   	//需指定库,否则会输出所有表
   	ResultSet tableRet = dbmd.getTables(DBManager.getConfiguration().getUsingDB(), "%", "%", new String[] {"TABLE"});
   	//对表中信息进行遍历
   	while(tableRet.next()) {
    
    	String tableName = (String)tableRet.getObject("TABLE_NAME");
    	//初始化表对象
    	TableInfo tInfo = new TableInfo(tableName,new HashMap<String,ColumnInfo>(),newArrayList<ColumnInfo>());
  
    	tables.put(tableName, tInfo);
    
    	//获取列对象,对其字段信息进行存储
    	ResultSet set = dbmd.getColumns(null, "%", tableName, "%");
    	while(set.next()) {
     		ColumnInfo cInfo = new ColumnInfo(set.getString("COLUMN_NAME"),
          	set.getString("TYPE_NAME"),0);
     		tInfo.getColumns().put(set.getString("COLUMN_NAME"),cInfo);
    	}	
    
    	//获取主键相关信息
    	ResultSet setPri = dbmd.getPrimaryKeys(null, "%", tableName);
   	while(setPri.next()) {
     		ColumnInfo cInfoPri = 
       		(ColumnInfo)tInfo.getColumns().get(setPri.getString("COLUMN_NAME"));
     		cInfoPri.setKeyType(1);
     		tInfo.getPriKeys().add(cInfoPri);
    	}
}

建立数据类型转换函数

由于MySQL中的数据类型和Java中类型是不一样的,但每种类型都有相对应的类型
所以需要建立一个函数来将MySQL中的数据类型转换为Java中的数据类型

//进行主要数据类型的转换
public String databaseType2JavaType(String columnType) {
  	//使用包装类型,方便转换
  	if("varchar".equalsIgnoreCase(columnType)
    		||"char".equalsIgnoreCase(columnType)) {
   		return "String";
  	}else if("int".equalsIgnoreCase(columnType)
    			|| "smallint".equalsIgnoreCase(columnType)
    			|| "integer".equalsIgnoreCase(columnType)) {
  		 return "Integer";
  	}else if("BIT".equalsIgnoreCase(columnType)) {
   		return "Byte";
  	}else if("bigint".equalsIgnoreCase(columnType)) {
   		return "Long";
  	}else if("double".equalsIgnoreCase(columnType)
    			|| "float".equalsIgnoreCase(columnType)) {
   		return "Double";
  	}else if("clob".equalsIgnoreCase(columnType)) {
   		return "java.sql.Clob";
  	}else if("blob".equalsIgnoreCase(columnType)) {
   		return "java.sql.Blob";
  	else if("date".equalsIgnoreCase(columnType)) {
   		return "java.sql.Date";
  	}else if("time".equalsIgnoreCase(columnType)) {
   		return "java.sql.Time";
  	}else if("timestamp".equalsIgnoreCase(columnType)) {
   		return "java.sql.Timestamp";
  	}
  	return null; 
 }

将ColumnInfo信息转换为java属性和方法

在ColumnInfo中存储着数据库中字段的名字、数据类型
我们可以借助这些内容将其转换为Java中一个属性和其set、get方法
借用StringBuilder来拼接字符串,评出属性、方法
PS:此处需要注意的是在表中提取到的字段名是小写,在拼接出set和get方法时,需要将其首字母转换为大写

/**
  * 根据字段信息生成java属性信息(Field、get()、set())
  * @param columnInfo    字段信息
  * @param convertor     类型转换器
  * @return   生成的源码
  */
 public static JavaFieldGetSet createFieldGetSetSrc(ColumnInfo columnInfo, TypeConvertor convertor) {
  	FieldGetSet jfgSet = new FieldGetSet();
  	//依据字段类型获取java类型
  	String FieldType = convertor.databaseType2JavaType(columnInfo.getDataType());
  
  	//属性
  	jfgSet.setFieldInfo(new StringBuilder()
        		.append("\tprivate ")
          		.append(javaFieldType+" ")
          		.append(columnInfo.getName()+";")
            		.append(CRLF).toString());
 	 //set方法
  	jfgSet.setSetInfo(new StringBuilder()
       			.append("\tpublic void set"+StringUtils.firstChar2UpperCase(columnInfo.getName())+"("+javaFieldType+" "+columnInfo.getName()+"){")
        		.append(CRLF+"\t\tthis."+columnInfo.getName()+" = "+columnInfo.getName()+";")
         		.append(CRLF+"\t}"+CRLF).toString());
  
  //get方法
  	jfgSet.setGetInfo(new StringBuilder()
      			 .append("\tpublic "+javaFieldType+" get"+StringUtils.firstChar2UpperCase(columnInfo.getName())+"(){")
       		 	.append(CRLF+"\t\treturn this."+columnInfo.getName()+";")
         		.append(CRLF+"\t}"+CRLF).toString());  
  
  	return jfgSet; 
 }

将TableInfo信转换为一个完整的java类

由于TableInfo中存储着ColumnInfo对象,因此可遍历TableInfo中的字段信息
借助前一阶段所得到的属性和set、get方法,和一些必要的头文件来组成一篇完整的Java文件

/**
  * 根据表信息生成java类的源码
  * @param tableInfo
  * @param convertor
  * @return    源码的string类型
  */
 public static String CreateJavaSrc(TableInfo tableInfo, TypeConvertor convertor) {
 	StringBuilder sBuilder = new StringBuilder();
  	Map<String, ColumnInfo> myColumn = tableInfo.getColumns();
  	List<FieldGetSet> myOrign = new ArrayList<FieldGetSet>();
  	//将字段信息,转化为源码
  	for(ColumnInfo cInfo : myColumn.values()) {
   		myOrign.add(createFieldGetSetSrc(cInfo, convertor));
  	}
  	//包名
  	sBuilder.append("package  "+DBManager.getConfiguration().getPoPackage()+";"+CRLF);
  	sBuilder.append(CRLF);
  	//导入包
  	sBuilder.append("import java.sql.*;"+CRLF);
  	sBuilder.append("import java.util.*;"+CRLF);
  	sBuilder.append(CRLF);
  	//类声明
 	 sBuilder.append("@SuppressWarnings(\"all\")"+CRLF);
  	sBuilder.append("public class "+StringUtils.firstChar2UpperCase(tableInfo.getName())+"{"+CRLF);
  	//属性
  	for(FieldGetSet jfgSet : myOrign) {
   		sBuilder.append(jfgSet.getFieldInfo());
 	}
 	sBuilder.append(CRLF);
  	//set、get方法
  	for(JavaFieldGetSet jfgSet : myOrign) {
   		sBuilder.append(jfgSet.getSetInfo());
   		sBuilder.append(jfgSet.getGetInfo());
  	}
    	//结束
  	sBuilder.append(CRLF+"}");
  	return sBuilder.toString();
  }

将java类写入到项目的包中

借用配置文件中的srcPath和poPackage来拼接出java文件所在的路径
借助BufferedWriter来将拼接好的字符串写入java文件

/**
  * 将获取到的源码写入文件
  * @param tableInfo 表结构
  * @param convertor
  */
 public static void JavaSrc2Package( TypeConvertor convertor) {
  	StringBuilder path = new StringBuilder(DBManager.getConfiguration().getSrcPath());
    	String dpath = DBManager.getConfiguration().getPoPackage().replace(".", "/");
  	path.append(dpath).append("/");
  	File dirFile = new File(path.toString());
  	//若文件不存在,则创建  
 	if(!dirFile.isDirectory()) {
   		dirFile.mkdirs();
  	}
  	try {
    		Map<String, TableInfo> myMap = TableContext.tables;
    		for(TableInfo tInfo : myMap.values()) {
     			BufferedWriter bWriter = new BufferedWriter(
             						new FileWriter(
               							new File(
                 							path.toString()+""+StringUtils.firstChar2UpperCase(tInfo.getName())+".java")));
     		bWriter.write(CreateJavaSrc(tInfo, convertor));
     		bWriter.close();
    		}
   		} catch (IOException e) {
   			// TODO Auto-generated catch block
   			e.printStackTrace();
      	}   
 }
然后就完成了映射,从数据库表映射到一个java类,就可以将java对象和表中记录相对应
发布了82 篇原创文章 · 获赞 1 · 访问量 1485

猜你喜欢

转载自blog.csdn.net/qq_41891805/article/details/104526050
Orm