一个简单的ORM框架

该ORM支持的功能
调用简单函数实现对指定数据库的增删查改
将自定义对象生成数据库的字段
将数据库表的字段生成java bean对象

使用方法:
创建一个demo项目,导入jar包
将配置文件放入src目录下
调用TableContext.loadPoTables()方法自动按数据库的表构建java类
github地址

项目结构:
核心类:
Query抽象类:负责查询(对外提供服务核心类)
QueryFactory类:负责根据配置信息创建query对象
TypeConverto类:负责java与数据库的数据类型转换
TableContext类:负责获取管理数据库所有表结构和类结构的关系,并可以根据表结构生成类结构(调用工具类)
DBManger:根据配置信息,维持连接对象的管理(增加连接池)

工具类:
JDBCUtils封装常用JDBC操作
StringUtils封装常用字符串操作
JavaFileUtils封装文件操作:(将表结构封装成java类的操作)
ReflectUtils封装常用反射操作

bean类:
ColumnInfo类:封装数据库表中一个字段的信息
Configuration类:封装配置信息类
TableInfo类:封装数据库表的信息(表结构+表内所有的字段)

以下是程序源代码:

核心类

Query抽象类:

/*对外提供服务的核心类
* @author xjh
*/

@SuppressWarnings("all")
public abstract class Query implements Cloneable{
    /*直接执行一个DML语句
    * sql:sql语句
    * params:语句内的参数
    * return 执行语句后影响了几条记录*/
    public int excuteDML(String sql,Object[] params){//执行DML语句
        int count=0;
        Connection conn=DBManger.getMysqlConn();
        PreparedStatement ps=null;
        try {
            ps=conn.prepareStatement(sql);
            //调用JDBCUtils包里的给prepareStatement传参操作
            JDBCUtils.handleParams(params,ps);
            count= ps.executeUpdate();
            System.out.println(ps);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            DBManger.close(ps,conn);
        }
        return count;
    };

    /*增加:将一个对象obj存储到数据库中
    * 把对象不为null的属性往数据库中存储,如果数字为null则放0*/
    public void insert(Object obj){//将obj新生成一个字段放入表中 insert into 表名 (id,uname,pwd) values (?,?,?)
        Class c = obj.getClass();
        List<Object> params=new ArrayList<>();//容器装对象不为null的属性的值,便于sql预处理赋值
        TableInfo tableInfo = TableContext.poClassTableMap.get(c);//获得类对应的表,得到表名
        Field fields[]=c.getDeclaredFields();//获得该类里所有的属性
        StringBuilder sql=new StringBuilder("insert into "+ tableInfo.getTname()+" (");
        int countNotNullField=0;//计算有多少个不为null的属性,方便在语句后加小问号
        for(Field f:fields){//得到obj所有属性的值
            String fieldname=f.getName();//Field的getName函数
            Object fieldvalue= ReflectUtils.invokeGet(fieldname,obj);
            if(fieldvalue!=null){sql.append(fieldname+",");
                params.add(fieldvalue);}}
        sql.setCharAt(sql.length()-1,')');//将当前字符串最后一个位置的,替换成)
        sql.append(" value (");
        for(int i=0;i<params.size();i++){sql.append("?,");}
        sql.setCharAt(sql.length()-1,')');
        excuteDML(sql.toString(),params.toArray());};

    /*删除:根据clazz类找到对应的表,以及主键id删除对应的记录*/
    public void delete(Class clazz,Object id){//id为需要删除的字段的主键的值
        //通过传入的Class对象找TableInfo
        TableInfo tableInfo= TableContext.poClassTableMap.get(clazz);//获得对应的表名
        ColumnInfo onlyPriKey=tableInfo.getOnlyPriKey();//获得主键
        String sql="delete from "+tableInfo.getTname()+" where "+onlyPriKey.getName()+"=?";
        excuteDML(sql,new Object[]{id});};

    /*删除:根据所给的对象,找到该对象的类,根据该对象的主键删除该对象在数据库表中对应的记录*/
    public void delete(Object obj){
        Class c = obj.getClass();
        TableInfo tableInfo = TableContext.poClassTableMap.get(c);
        ColumnInfo onlyPriKey = tableInfo.getOnlyPriKey();

        //通过ReflectUtils包内的反射方法,调用get方法得到该对象属性的值 找到 对应字段的主键的值
        Object priKeyvalue = ReflectUtils.invokeGet(onlyPriKey.getName(),obj);
        delete(c, priKeyvalue);//调用上面写好的函数
    };


    /*修改:更新对象指定字段的属性
    * fieldNames:需要更新的属性
    * return 更新了几行*/
    public int update(Object obj,String[] fieldNames){
        //传入obj,{"age","salary"}-->update 表名 set age=?,salary=? where id=?
        Class c = obj.getClass();
        TableInfo tableInfo = TableContext.poClassTableMap.get(c);//通过对象获得类名获得表名
        List<Object> params=new ArrayList<>();//存放该对象的属性的值
        ColumnInfo onlyPriKey = tableInfo.getOnlyPriKey();//获得主键,通过主键值删除字段
        Field fields[]=c.getDeclaredFields();
        StringBuilder sql=new StringBuilder("update "+ tableInfo.getTname()+" set ");
        for (String fieldname:fieldNames){
            Object field=ReflectUtils.invokeGet(fieldname,obj);//得到该对象属性的值
            params.add(field);
            sql.append(fieldname+"=?,");
        }
        sql.setCharAt(sql.length()-1,' ');//把逗号替换成空格
        sql.append("where "+onlyPriKey.getName()+"=?");
        params.add(ReflectUtils.invokeGet(onlyPriKey.getName(),obj));
        return excuteDML(sql.toString(),params.toArray());
    };
    /*---------------------------------------------查询----------------------------------------------------*/


    /*查询多行记录:
    * sql:查询语句
    *clazz:封装数据的java bean对类的class对象
    * params:sql的参数
    *  return 查询到的结果:一个list容器*/
    public List QueryRows(String sql,Class clazz,Object[] params){//多行多列查询
        Connection conn=DBManger.getMysqlConn();
        List<Object>list=null;//放查询结果对象的容器
        PreparedStatement ps=null;
        ResultSet rs=null;
        try {
            ps=conn.prepareStatement(sql);
            //调用JDBCUtils包里的给prepareStatement传参操作
            JDBCUtils.handleParams(params,ps);
            rs=ps.executeQuery();
            ResultSetMetaData metaData=rs.getMetaData();//返回结果集的元数据
            //多行,每一行为一个javabean对象
            while (rs.next()){
                if(list==null){list=new ArrayList<>();}
                Object rowObj=clazz.newInstance();//创建一个javabean对象
                //多列  select empname,salary from emp where id>?
                for (int i=0;i<metaData.getColumnCount();i++){//getColumn函数得到查询语句结果集的列数,即属性数目
                    String columnName=metaData.getColumnLabel(i+1);//得到结果的列名,即属性标签名(如果没有标签则默认属性名)
                    Object columnValue=rs.getObject(i+1);

                    //调用rowObj对象的setEmpname方法,将结果集第一列的值设置进去
                    ReflectUtils.invokeSet(rowObj,columnName,columnValue);
                }
                list.add(rowObj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            DBManger.close(rs,ps,conn);
        }
        return list;};

    /*查询单行记录:
     * sql:查询语句
     *clazz:封装数据的java bean对类的class对象
     * params:sql的参数
     *  return 查询到的结果:一个对象*/
    public Object QueryUniquerow(String sql,Class clazz,Object []params){
        //查询一行:直接调用查询多行的函数,返回第一行数据
        List list=QueryRows(sql,clazz,params);
        return (list!=null&&list.size()>0)?list.get(0):null;
    };

   /*根据主键获得一个字段*/
    public Object QueryById(Class clazz,Object id){
   //select* from emp where id=?
        TableInfo tableInfo=TableContext.poClassTableMap.get(clazz);//获得表信息
        ColumnInfo onlyPriKey=tableInfo.getOnlyPriKey();//获得主键
        String sql="select * from "+tableInfo.getTname()+" where "+onlyPriKey.getName()+"=? ";
           return QueryUniquerow(sql,clazz,new Object[]{id});
    }


    /*查询返回一个值(一行一列):
     * sql:查询语句
     * param:sql的参数
     *  return 查询到的结果:一个对象*/
    public Object QueryValue(String sql,Object []params){//sql查询语句,返回一个值,例如计算行数
        Connection conn=DBManger.getMysqlConn();
        Object value=null;//放查询结果对象的容器
        PreparedStatement ps=null;
        ResultSet rs=null;
        try {
            ps=conn.prepareStatement(sql);
            //调用JDBCUtils包里的给prepareStatement传参操作
            JDBCUtils.handleParams(params,ps);
            rs=ps.executeQuery();
            ResultSetMetaData metaData=rs.getMetaData();//返回结果集的元数据
            while (rs.next()){
                value=rs.getObject(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            DBManger.close(rs,ps,conn);
        }
        return value;};

    /*查询返回一个数字(一行一列)比如查询id:
     * sql:查询语句
     * param:sql的参数
     *  return 查询到的结果:一个对象*/
    public Number QueryNumber(String sql,Object []params){//sql语句查询结果为一个数字
        return (Number) QueryValue(sql,params);};

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

DBManger类:

/*根据配置信息,维持连接对象的 管理(增加连接池)*/
public class DBManger {
    private static Configuration conf;
    static {//加载配置文件,封装成一个对象
        Properties pros=new Properties();//读取配置资源文件
        try {
            pros.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));//读取bin目录下资源
        } catch (IOException e) {
            e.printStackTrace();
        }
        conf=new Configuration();
        conf.setDriver(pros.getProperty("driver"));
        conf.setUrl(pros.getProperty("url"));
        conf.setUser(pros.getProperty("user"));
        conf.setPassword(pros.getProperty("password"));
        conf.setSrc(pros.getProperty("src"));
        conf.setPopackage(pros.getProperty("popackage"));
        conf.setUsingdb(pros.getProperty("usingdb"));
        conf.setQueryClass(pros.getProperty("queryClass"));
    }
/*获得Connection对象*/
    public static Connection getMysqlConn() {//连接数据库
        try {
            Class.forName(conf.getDriver());//得到驱动
            String url = conf.getUrl();
            return DriverManager.getConnection(url, conf.getUser(), conf.getPassword());//建立连接
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /*关闭传入的ResultSet Statement Connection对象*/
    public static void close(ResultSet rs, Statement ps, Connection conn) {
        try {
            if (conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (ps != null) {
                ps.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    /*关闭传入的 Statement Connection对象*/
    public static void close(Statement ps, Connection conn) {
        try {
            if (conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        try {
            if (ps != null) {
                ps.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    /*关闭传入的Connection对象*/
    public static void close( Connection conn) {
        try {
            if (conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /*返回Configuration对象*/
    public static Configuration getConf(){
          return conf;
    }
}

TableContext类:

/*负责获取管理数据库所有表结构和类结构的关系,并可以根据表结构生成类结构*/
public class TableContext {
    /*表名为key,表信息对象为value*/
    public static Map<String, TableInfo> tables=new HashMap<String, TableInfo>();//启动时就加载数据库的表
   /*将po的class对象和表信息对象关联起来,便于重用*/
    public static Map<Class,TableInfo> poClassTableMap=new HashMap<Class, TableInfo>();//在启动的时候将生成Class对象与其在数据库的表对应起来

    private TableContext(){};
    /*初始化,获得数据库元数据,得到数据库表的信息*/
    static {
        try {
            Connection con = DBManger.getMysqlConn();
            DatabaseMetaData dbmd = con.getMetaData();//DatabaseMetaData类是java.sql包中的类,可以获取我们连接到的数据库的结构、存储等很多信息
            ResultSet rs = dbmd.getTables("sorm", "sorm", "%", new String[]{"TABLE"});
            /*getTables()方法,该方法需要传进4个参数:数据库名称(若不传入数据库名称sorm则会读取所有数据库的表),模式,表名,类型标准*/
            while (rs.next()) {
                String tableName = (String) rs.getObject("TABLE_NAME");
                TableInfo ti = new TableInfo(tableName, new HashMap<String, ColumnInfo>(), new ArrayList<ColumnInfo>());
                tables.put(tableName, ti);
                ResultSet set = dbmd.getColumns(null, "%", tableName, "%");
                while (set.next()) {
                    ColumnInfo ci = new ColumnInfo(set.getString("COLUMN_NAME"), set.getString("TYPE_NAME"), 0);
                    ti.getColumns().put(set.getString("COLUMN_NAME"), ci);
                }
                ResultSet keySet = dbmd.getPrimaryKeys(null, "%", tableName);
                while (keySet.next()) {
                    ColumnInfo ci2 = (ColumnInfo) ti.getColumns().get(keySet.getString("COLUMN_NAME"));
                    ci2.setKeyType(1);
                    ti.getPriKeys().add(ci2);
                }
                if(ti.getPriKeys().size()>0){//去唯一主键,方便使用
                    ti.setOnlyPriKey(ti.getPriKeys().get(0));
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            UpdatePoFile();//根据数据库的表生成PO包下的类
            loadPoTables();//加载这些类,并与表绑定起来,便于操作
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*静态方法:调用该方法根据获得数据库表结构,更新配置po包下的类*/
    public static void UpdatePoFile() throws IOException {
        Map<String, TableInfo> map = TableContext.tables; //循环获得表内容
        for (String Tablename : map.keySet()) {
            TableInfo t = map.get(Tablename);
            javaFileUtils.createJavaPoFile(t, new MysqlTypeConvertor());
        }
    }

    public static void loadPoTables(){
        for(TableInfo tableInfo:tables.values()){
            try {
                Class c=Class.forName(DBManger.getConf().getPopackage()+"."+ StringUtils.firstChar2UpperCase(tableInfo.getTname()));//让jvm加载po包的类
                poClassTableMap.put(c,tableInfo);//将生成的类与数据库的表关联起来
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Map<String,TableInfo> tables=TableContext.tables;
        System.out.println(tables);
    }

}

TypeConvertor接口:

public interface TypeConvertor {

   /*将数据库数据类型转换为java类型
   *columnType:数据库字段的数据类型
   * return java的数据类型 */
    public String databaseType2javaType(String columnType);

    /*将java数据类型转换为数据库数据类型
     *javaType:java内的数据类型
     * return 数据库的数据类型 */
    public String javaType2databaseType(String javaType);
}

MysqlTypeConvertor类实现上面接口:

/*mysql数据库和java数据类型转换,继承TypeConvertor接口*/
public class MysqlTypeConvertor implements TypeConvertor {

    @Override
    public String databaseType2javaType(String columnType) {
        if(columnType.equalsIgnoreCase("varchar")||columnType.equalsIgnoreCase("char")){//将数据库的varchar类型转为java的String
            return "String";
        }else if(columnType.equalsIgnoreCase("int")||
                columnType.equalsIgnoreCase("tinyint")||
                columnType.equalsIgnoreCase("smallint")||
                columnType.equalsIgnoreCase("integer")){return "Integer";}
        else if(columnType.equalsIgnoreCase("bigint")){return "Long";}
        else if(columnType.equalsIgnoreCase("double")||columnType.equalsIgnoreCase("float")){return "Double";}
        else if(columnType.equalsIgnoreCase("clob")){return "java.sql.Clob";}
        else if(columnType.equalsIgnoreCase("blob")){return "java.sql.Blob";}
        else if(columnType.equalsIgnoreCase("date")){return "java.sql.Date";}
        else if(columnType.equalsIgnoreCase("time")){return "java.sql.Time";}
        else if(columnType.equalsIgnoreCase("timestamp")){return "java.sql.Timestamp";}
            return null;
    }

    @Override
    public String javaType2databaseType(String javaType) {
        return null;
    }
}

QueryFactory类:
(核心使用类)

/*根据配置文件创建Query对象
*工厂类是单例模式
* 使用原型模式,工厂模式 ,通过该类获得需要的Query对象*/
public class QueryFactory {
    private static Query prototypeObj;
    static {//静态加载配置文件的指定的Query类
        try {
            Class clazz=Class.forName(DBManger.getConf().getQueryClass());
            prototypeObj= (Query) clazz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  private QueryFactory(){};
  public static Query createQuery(){
      try {
          return (Query) prototypeObj.clone();
      } catch (Exception e) {
          e.printStackTrace();
          return null;
      }
  };
}

工具类

封装了一些常用的jdbc,处理字符串,java文件操作,反射操作的方法
JDBCUtils

/*封装JDBC常用操作*/
public class JDBCUtils {

    public static void handleParams(Object[] params, PreparedStatement ps){//给sql语句处理参数
        if(params!=null){//有参数才进行预处理
            for (int i=0; i <params.length; i++) {
                try {
                    ps.setObject(i+1,params[i]);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }}
    }
}

StringUtils

public class StringUtils {
    /*将目标字符首字母变为大写
    * str为目标字符串
    * return 首字母变为大小的字符串*/
    public static String firstChar2UpperCase(String str){
            return  str.toUpperCase().substring(0,1)+str.substring(1);//例如:将str全部转为大写,截取第一个字符,再拼接原str的剩余字符
    }
}

JavaFileUtils类

/*封装生成java类文件(源代码)的常用操作*/
public class javaFileUtils {
    /*根据字段信息生成java属性信息。如:var username-->生成private String username;以及该属性的set,get方法
     * column:字段信息
     * convertor:数据类型转换器
     * return java属性和set/get方法源码*/
    public static JavaFieldGetSet createJavaFieldGetSetSRC(ColumnInfo column, TypeConvertor convertor) {
        JavaFieldGetSet jfgs = new JavaFieldGetSet();//该类封装java属性和get,set方法源代码
        String javaFieldType = convertor.databaseType2javaType(column.getDataType());
        jfgs.setFieldInfo("\t" + "private " + javaFieldType + " " + column.getName() + ";\n");

        //生成getter的源代码,例如 public int getID(){ return id;}
        StringBuilder getSrc = new StringBuilder();//StringBuilder便于拼接字符串
        getSrc.append("\tpublic " + javaFieldType + " get" + StringUtils.firstChar2UpperCase(column.getName()) + "(){\n");
        getSrc.append("\treturn " + column.getName() + ";}\n");
        jfgs.setGetInfo(getSrc.toString());

        //生成setter的源代码,例如 public int getID(){ return id;}
        StringBuilder setSrc = new StringBuilder();//StringBuilder便于拼接字符串
        setSrc.append("\tpublic void set" + StringUtils.firstChar2UpperCase(column.getName()) + "(" + javaFieldType + " " + column.getName() + "){\n");
        setSrc.append("\tthis." + column.getName() + "=" + column.getName() + ";}\n");
        jfgs.setSetInfo(setSrc.toString());

        return jfgs;
    }

    /*根据表信息生成java类的源代码
     * tableInfo:表信息
     * convertor:数据类型转换器
     * return java类的源代码*/
    public static String createJavaSrc(TableInfo tableInfo, TypeConvertor convertor) {
        StringBuilder src = new StringBuilder();
        Map<String, ColumnInfo> columns = tableInfo.getColumns();
        List<JavaFieldGetSet> javaFields = new ArrayList<JavaFieldGetSet>();//存储表内所有的字段

        for (ColumnInfo c : columns.values()) {
            javaFields.add(createJavaFieldGetSetSRC(c, convertor));
        }
//开始拼接源码
//生成package语句
        src.append("package " + DBManger.getConf().getPopackage() + ";\n\n");//通过DBManger类中的Conf对象得到配置文件写好的存放类的位置
//生成import语句
        src.append("import java.sql.*;\n");
        src.append("import java.util.*;\n\n\n");
//生成类声明语句
        src.append("public class " + StringUtils.firstChar2UpperCase(tableInfo.getTname()) + " {\n");
//生成属性列表
        for (JavaFieldGetSet f : javaFields) {
            src.append(f.getFieldInfo());//调用上面的写好的方法得到属性信息
        }
        src.append("\n\n");//空行
//生成get方法列表
        for (JavaFieldGetSet f : javaFields) {
            src.append(f.getGetInfo());//调用上面的写好的方法得到属性信息
        }
//生成set方法列表
        for (JavaFieldGetSet f : javaFields) {
            src.append(f.getSetInfo());//调用上面的写好的方法得到属性信息
        }
//生成类结束语句
        src.append("}\n");

        return src.toString();
    }

    public static void createJavaPoFile(TableInfo tableInfo,TypeConvertor convertor) throws IOException {
          String src=createJavaSrc(tableInfo, convertor);//调用上面的方法生成一张表对应的java类的源代码
        String secPath=DBManger.getConf().getSrc()+"/";//得到配置文件内的src文件的地址
        String packagePath=DBManger.getConf().getPopackage().replaceAll("\\.","\\\\");//得到配置文件内po包的地址,在java内一个反斜杠都要写成两个
        File f=new File(secPath+"\\"+packagePath);
       if(!f.exists()){
          f.mkdir();
       }
        BufferedWriter bw=null;//通过流将源码写入文件
        bw=new BufferedWriter(new FileWriter(f.getAbsoluteFile()+"\\"+StringUtils.firstChar2UpperCase(tableInfo.getTname())+".java",false));
        try {
            bw.write(src);
            System.out.println("建立表"+tableInfo.getTname()+"对应的java类"+StringUtils.firstChar2UpperCase(tableInfo.getTname())+".java"+"到指定目录下");
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(bw!=null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

   public static void main(String[] args) throws IOException {//测试代码
      //  ColumnInfo ci = new ColumnInfo("id", "tinyint", 0);
     //   JavaFieldGetSet j = createJavaFieldGetSetSRC(ci, new MysqlTypeConvertor());
       // j.toString()
       Map<String,TableInfo>map= TableContext.tables; //循环获得表内容
       for(String Tablename:map.keySet()){  TableInfo t=map.get(Tablename);
           createJavaPoFile(t,new MysqlTypeConvertor());//根据表内容新建类,将该代码写成方法放入TableContext类中}
    }
}

}

ReflectUtils

/*封装反射的的常用操作*/
public class ReflectUtils {

    /*调用obj对象的某一属性的get方法*/
    public static  Object invokeGet(String fieldName,Object obj){
        //通过反射机制,调用属性的get或set方法
        try {
            Class c=obj.getClass();
            Method m=c.getDeclaredMethod("get"+StringUtils.firstChar2UpperCase(fieldName),null);
            return m.invoke(obj,null);//调用get方法得到该属性的值
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void invokeSet(Object obj,String fieldName,Object fieldValue){
        //通过反射机制,调用属性的get或set方法
        if(fieldValue!=null){
        try {
            Class c=obj.getClass();
            Method m=c.getDeclaredMethod("set"+StringUtils.firstChar2UpperCase(fieldName),fieldValue.getClass());
            m.invoke(obj,fieldValue);//调用get方法得到该属性的值
        } catch (Exception e) {
            e.printStackTrace();
        }}
    }
}
/*封装表中一个字段的信息*/
public class ColumnInfo {
    private String name;//字段名称

    private String dataType;//字段数据类型

    private int KeyType;//0代表非主键,1代表主键,2代表外键

    public ColumnInfo() {
    }

    public ColumnInfo(String name, String dataType, int keyType) {
        this.name = name;
        this.dataType = dataType;
        KeyType = keyType;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDataType() {
        return dataType;
    }

    public void setDataType(String dataType) {
        this.dataType = dataType;
    }

    public int getKeyType() {
        return KeyType;
    }

    public void setKeyType(int keyType) {
        KeyType = keyType;
    }
}

Configuration类

public class Configuration {
    private String driver;//数据库驱动
    private String url;//数据库url
    private String user;//数据库用户名
    private String password;//数据库密码
    private String src;//项目源码路径
    private String popackage;//扫描后生成java类存储的包,po:Persistence object持久化对象
    private String usingdb;//选择数据库类型
    private String queryClass;//项目选择的查询类,即Query的一个子类

    public Configuration() {//无参构造
    }


    public String getDriver() {
        return driver;
    }

    public void setDriver(String driver) {
        this.driver = driver;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSrc() {
        return src;
    }

    public void setSrc(String src) {
        this.src = src;
    }

    public String getPopackage() {
        return popackage;
    }

    public void setPopackage(String popackage) {
        this.popackage = popackage;
    }

    public String getUsingdb() {
        return usingdb;
    }

    public void setUsingdb(String usingdb) {
        this.usingdb = usingdb;
    }

    public String getQueryClass() {
        return queryClass;
    }

    public void setQueryClass(String queryClass) {
        this.queryClass = queryClass;
    }
}

TableInfo类

public class TableInfo {
    /*表名*/
    private String tname;

    /*表中所有字段信息*/
    private Map<String,ColumnInfo> columns;

    /*唯一主键:目前只处理表中只有一个主键的情况*/
    private ColumnInfo onlyPriKey;//单一主键
    private List<ColumnInfo> priKeys;//联合主键
    public TableInfo() {
    }

    public TableInfo(String tname, Map<String, ColumnInfo> columns, ColumnInfo onlyPriKey) {
        this.tname = tname;
        this.columns = columns;
        this.onlyPriKey = onlyPriKey;
    }

    public TableInfo(String tname, Map<String, ColumnInfo> columns,  List<ColumnInfo> priKeys) {
        this.tname = tname;
        this.columns = columns;
        this.priKeys = priKeys;
    }

    public String getTname() {
        return tname;
    }

    public void setTname(String tname) {
        this.tname = tname;
    }

    public Map<String, ColumnInfo> getColumns() {
        return columns;
    }

    public void setColumns(Map<String, ColumnInfo> columns) {
        this.columns = columns;
    }

    public ColumnInfo getOnlyPriKey() {
        return onlyPriKey;
    }

    public void setOnlyPriKey(ColumnInfo onlyPriKey) {
        this.onlyPriKey = onlyPriKey;
    }

    public List<ColumnInfo> getPriKeys() {
        return priKeys;
    }

    public void setPriKeys(List<ColumnInfo> priKeys) {
        this.priKeys = priKeys;
    }
}

JavaFieldGetSet类用于辅助JavaFileUtils类存储java属性以及getter setter的源码

/*封装java属性和get,set方法源代码*/
public class JavaFieldGetSet {
    private String fieldInfo;
    private String getInfo;
    private String setInfo;

    public String getFieldInfo() {
        return fieldInfo;
    }

    public void setFieldInfo(String fieldInfo) {
        this.fieldInfo = fieldInfo;
    }

    public String getGetInfo() {
        return getInfo;
    }

    public void setGetInfo(String getInfo) {
        this.getInfo = getInfo;
    }

    public String getSetInfo() {
        return setInfo;
    }

    public void setSetInfo(String setInfo) {
        this.setInfo = setInfo;
    }

    @Override
    public String toString() {
        System.out.println(this.getFieldInfo());
        System.out.println(this.getGetInfo());
        System.out.println(this.getSetInfo());
        return super.toString();
    }
}

如何使用该框架:
首先导入Jar包(该框架的jar包以及Mysql驱动jar包),然后编写配置文件。最后调用QueryFactory创建一个Query类实现对数据库的操作。
简单示例:

/*客户端调用的测试类*/
public class test {
    public static void main(String[] args) throws ParseException {//测试单行单列查找
        Query q=QueryFactory.createQuery();
        Object o =q.QueryValue("select empname from emp where id=?", new Object[]{2});
        System.out.println(o);
        testDML();
        }
    public static void testQueryRows() {//测试查找语句,多行多列查找
        String sql = "select empname,age from emp where id>?";
        List<Emp> l = new MysqlQuery().QueryRows(sql, Emp.class, new Object[]{0});
        for (Emp e : l) {
            System.out.println(e.getEmpname() + e.getAge());
        }
    }
    public static void testDML() throws ParseException {//测试DML语句
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date d = df.parse("2024-08-05");
        MysqlTypeConvertor mc = new MysqlTypeConvertor();
        Emp e = new Emp();
        e.setId(3);
        e.setEmpname("test");
        e.setBirthday(new java.sql.Date(d.getTime()));
        MysqlQuery ms = new MysqlQuery();
        ms.update(e, new String[]{"empname", "birthday"});
    }
}

配置文件:

driver:com.mysql.cj.jdbc.Driver
url:jdbc:mysql://localhost:3306/sorm?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8
user:root
password:xjh1999
src:E:\\Idea  workspace\\JDBC_project\\Moudel3\\src
popackage:cn.xjh.po
usingdb:mysql
queryClass:cn.xjh.sorm.core.MysqlQuery

driver:数据库驱动器
url:连接数据库的url,最后一个sorm是数据库的名字
user:数据库用户名
password:密码
src:当前项目的src目录
popackage:数据库表生成的java对象存储的包
usingdb:使用的数据库类型
queryClass:使用的Query类(目前只有MysqlQuery类,只支持mysql)

补充:如果要进行联表查询,则需要自己在po包内创建好相关的类,再调用
insert方法,将新的类当作参数传入进去。

public class EmpVO {//联合查询
    //例如select e.id,e.empname ,e.salary,d.dname from emp e JOIN dept d on e.deptID=d.id
    //专门建一个java bean来存放查询结果
    private Integer id;
    private String empname;
    private Double salary;
    private String dname;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getEmpname() {
        return empname;
    }
    public void setEmpname(String empname) {
        this.empname = empname;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public String getDname() {
        return dname;
    }
    public void setDname(String dname) {
        this.dname = dname;
    }
    public EmpVO() {
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值