前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >第32次文章:手写SORM框架(二)

第32次文章:手写SORM框架(二)

作者头像
鹏-程-万-里
发布2019-09-27 15:49:05
2890
发布2019-09-27 15:49:05
举报

在上周,我们将整个SORM的框架结构梳理了一下,本周开始对整个框架的每个细节步骤进行相关的填充。目前还没有把整个框架全部搭建起来,只完成了一小部分,这周我们就对已完成的类中,一些比较有意思的功能进行一个小介绍吧!


1、核心bean中的JavaFieldGetSet类

在核心Javabean类中,我们增加了一个JavaFieldGetSet类,主要用于封装一个java属性的get和set方法的源码。

JavaFieldGetSet类中,设置有三个属性参数,分别为:

(1)fieldInfo:主要存储属性源码信息,如:private int userId;

(2)getInfo:get方法源码。如:public int getUserId(){}

(3)setInfo:set方法源码。如:public void setUserId(int id){this.id = id;}

需要注意的是JavaFieldGetSet类本身也属于一个Javabean类,内部只包括三个属性的set和get方法,以及无参构造器和带参构造器。

2、工具类Utils中的JavaFileUtils类

根据上周我们的架构预设,JavaFileUtils中主要是封装生成Java文件(源代码)常用的操作。

针对上面提到的JavaFieldGetSet类,我们封装相应的方法来生成源码信息。此处我们着重分享生成源码的方法:根据字段信息生成java属性信息。如:var username -->private String username;以及相应的set和get方法源码。该方法的程序代码如下:

package com.peng.sorm.utils;

import com.peng.sorm.bean.ColumnInfo;
import com.peng.sorm.bean.JavaFieldGetSet;
import com.peng.sorm.core.MySqlTypeConvertor;
import com.peng.sorm.core.TypeConvertor;

/**
 * 封装了生成Java文件(源代码)常用的操作
 *
 */
public class JavaFileUtils {
  
  /**
   * 根据字段信息生成java属性信息。如:var username -->private String username;以及相应的set和get方法源码
   * @param column 字段信息
   * @param convertor 类型转化器
   * @return java属性和set/get方法源码
   */
  public static JavaFieldGetSet createFieldGetSetSRC(ColumnInfo column,TypeConvertor convertor) {
    JavaFieldGetSet jfgs = new JavaFieldGetSet();
    String javaFieldType = convertor.databaseType2JavaType(column.getDataType());//获取属性在java中的数据类型
    
    //private String username;
    //生成属性源码
    jfgs.setFieldInfo("\tprivate "+javaFieldType+" "+column.getName()+";\n");    
    
    //public String getUsername(){return username;}
    //生成get方法的源码
    StringBuilder getSrc = new StringBuilder();
    getSrc.append("\tpublic "+javaFieldType+" get"+StringUtils.firstChar2UpperCase(column.getName())+"(){\n");
    getSrc.append("\t\treturn "+column.getName()+";\n" );
    getSrc.append("\t}\n");
    jfgs.setGetInfo(getSrc.toString());
    
    //public void setUsername(String username){this.username=username;}
    //生成set方法的源码
    StringBuilder setSrc = new StringBuilder();
    setSrc.append("\tpublic void set"+StringUtils.firstChar2UpperCase(column.getName())+"(");
    setSrc.append(javaFieldType+" "+column.getName()+"){\n");
    setSrc.append("\t\t this."+column.getName()+"="+column.getName()+";\n" );
    setSrc.append("\t}\n");
    jfgs.setSetInfo(setSrc.toString());
    return jfgs;
  }
}

tips:在上面的代码中,我们封装了一个createFieldGetSetSRC()方法,根据属性声明,set,get方法的格式,使用拼接字符串的方法来完成每一段源代码的生成。

1.为了源码生成之后的美观问题,我们需要对每一行代码的缩进与对齐方面进行控制,所以增加了制表符“\t”和换行符“\n"。

2.在生成set和get方法的源码的时候,我们按照常规习惯,会将属性名的第一字母变为大写,然后在属性名前面加上set或者get,形成set与get方法的方法名。为了便于后续的使用,我们封装了一个改变字符串首字母大小写的方法firstChar2UpperCase(),在后面我们将对其进行分析。

3.在生成源码的时候,我们还需要对数据库中传递过来的数据类型进行转换,使用到了一个我们自己封装的方法databaseType2JavaType(),此方法在后面进行详解。

3、工具类Utils中的StringUtils类

在规划整个SORM框架的时候,在StringUtils中主要封装字符串常用的操作。

针对上面的createFieldGetSetSRC()方法,我们提到了一个转换字符串首字母大小写的方法firstChar2UpperCase()。下面给出此方法的源程序:

package com.peng.sorm.utils;

/**
 * 封装了字符串常用的操作
 */
public class StringUtils {
  
  /**
   * 将目标字符串首字母变为大写
   * @param str 目标字符串
   * @return 首字母变为大写的字符串
   */
  public static String firstChar2UpperCase(String str) {
    return str.toUpperCase().substring(0,1)+str.substring(1);
  }
}

tips:在上述firstChar2UpperCase()方法里面,转换字符串首字母大小写的思想很简单:首先使用toUpperCase()方法,将字符串的全部字母转换为大写字母,然后使用subString(0,1)截取首字母;然后再用拼接字符串的方法,将原字符串的剩余部分拼接在首字母后面,最后得到一个仅改变首字母大小写的字符串。

4、核心架构中的MySqlTypeConvertor类

MySqlTypeConvertor类属于核心架构中实现了TypeConvertor接口的一个实现类,主要负责将MySql数据库和java之间的数据类型进行相互转化。在上面的createFieldGetSetSRC()方法中,已经提到了这一部分。

package com.peng.sorm.core;

/**
 * mysql数据类型和java数据类型的转换
 */
public class MySqlTypeConvertor implements TypeConvertor {

  @Override
  public String databaseType2JavaType(String columnType) {
    // varchar ---- >String
    if("varchar".equalsIgnoreCase(columnType)||"char".equalsIgnoreCase(columnType)) {
      return "String";
    }else if("int".equalsIgnoreCase(columnType)
        ||"tinyint".equalsIgnoreCase(columnType)
        ||"smallint".equalsIgnoreCase(columnType)
        ||"integer".equalsIgnoreCase(columnType)
        ) {
      return "Integer";
    }else if("bigint".equalsIgnoreCase(columnType)) {
      return "Long";
    }else if("double".equalsIgnoreCase(columnType)||"float".equalsIgnoreCase(columnType)) {
      return "Double";
    }else if("blob".equalsIgnoreCase(columnType)) {
      return "java.sql.BLob";
    }else if("clob".equalsIgnoreCase(columnType)) {
      return "java.sql.CLob";
    }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;  
  }

  @Override
  public String javaType2DatebaseType(String columnType) {
    return null;
  }
}

tips:在类型转换的时候,我们仅实现TypeCOnvertor接口中的databaseType2JavaType()方法。思想很简单,就是使用条件语句来对每一个数据库中的数据类型进行判断,然后再将其转换为对应的java中的数据类型。

5、最后检测一下生成源码的的效果

public static void main(String[] args) {
    ColumnInfo ci = new ColumnInfo("username","varchar",0);
    JavaFieldGetSet jfgs = createFieldGetSetSRC(ci, new MySqlTypeConvertor());
    System.out.println(jfgs.toString());
}

结果:

所得结果符合我们的预期效果,和我们自己手写的代码一致。


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java小白成长之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档