java框架--Model层框架 sorm

                               SORM框架
   1  核心框架:
                 Query接口 负责查询(对外提供读物的核心类)
                 QueryFactory类 负责根据配置信息创建query对象
                 Typeconverto接口 负责类型转换
                 TableContext 类 负责获取管理数据库所有表结构和类结构的关系,并可以根据表结构生成类结构,
                 DBManager 类 根据配置信息,维持连接对象的管理增加连接池功能
     工具类
                 JDBCUtil 封裝常用JDBC操作 StringUtil 封裝常用字符串操作
                 JavaFileUtil封裝java文件操作 ReflectUtil 封裝常用反射操作


                            client                 QueryFactory

                                                        <interface>                       DB2Query
                                                          query                                OracleQuery
                                                                                                 mysqlQuery
                        TableContext


                                        DBManager                             <interface>                 OracleTypeConvertor
                                                                                       TypeConvertor             mysqlTypeConvertor

       核心bean ,封裝相关数据
                           ColumnInfo 封裝表中一个字段的信息(字段类型、字段名、键类型)
                           Configuration 封裝配置文件信息
                           TableInfo 封裝一张表的信息

     2、针对SORM框架的说明:
                        核心思想:使用简单、性能高、极易上手!
                配置文件:
                        模卡使用资源文件、后期项目复杂后可以增加xml文件配置和注解。
                       类名有标明生成、只有受罪大写有区别,其他无区别
                         java对象的属性有表中字段生成,完全对应
                         目前,只支持表中只有一个主键,联合主键不支持

    3.代码区

 

package com.bjsxt.po;

import java.sql.*;
import java.util.*;

public class Dept {

    private Integer id;
    private String address;
    private String dname;


    public Integer getId(){
        return id;
    }
    public String getAddress(){
        return address;
    }
    public String getDname(){
        return dname;
    }
    public void setId(Integer id){
        this.id=id;
    }
    public void setAddress(String address){
        this.address=address;
    }
    public void setDname(String dname){
        this.dname=dname;
    }
}
Dept
package com.bjsxt.po;

import java.sql.*;
import java.util.*;

public class Emp {

    private Integer id;
    private java.sql.Date birthday;
    private Integer deptid;
    private String empname;
    private Integer age;
    private Double bonus;
    private Double salary;


    public Integer getId(){
        return id;
    }
    public java.sql.Date getBirthday(){
        return birthday;
    }
    public Integer getDeptid(){
        return deptid;
    }
    public String getEmpname(){
        return empname;
    }
    public Integer getAge(){
        return age;
    }
    public Double getBonus(){
        return bonus;
    }
    public Double getSalary(){
        return salary;
    }
    public void setId(Integer id){
        this.id=id;
    }
    public void setBirthday(java.sql.Date birthday){
        this.birthday=birthday;
    }
    public void setDeptid(Integer deptid){
        this.deptid=deptid;
    }
    public void setEmpname(String empname){
        this.empname=empname;
    }
    public void setAge(Integer age){
        this.age=age;
    }
    public void setBonus(Double bonus){
        this.bonus=bonus;
    }
    public void setSalary(Double salary){
        this.salary=salary;
    }
}
Emp
package com.bjsxt.sorm.bean;

/**
 * 封装表中一个字段的信息
 * @author gaoiqi www.sxt.cn
 * @version 0.8
 */
public class ColumnInfo {
    /**
     * 字段名称
     */
    private String name;
    
    /**
     * 字段的数据类型
     */
    private String dataType;
    
    /**
     * 字段的键类型(0:普通键,1:主键 2:外键)
     */
    private int 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) {
        this.keyType = keyType;
    }

    public ColumnInfo(String name, String dataType, int keyType) {
        super();
        this.name = name;
        this.dataType = dataType;
        this.keyType = keyType;
    }
    
    
    public ColumnInfo() {
    }
}
ColumnInfo 封装表中一个字段的信息
package com.bjsxt.sorm.bean;

/**
 * 管理配置信息
 * @author gaoqi www.sxt.cn
 *
 */
public class Configuration {
    /**
     * 驱动类
     */
    private String driver; 
    /**
     * jdbc的url
     */
    private String url;
    /**
     * 数据库的用户名
     */
    private String user;
    /**
     * 数据库的密码
     */
    private String pwd;
    /**
     * 正在使用哪个数据库
     */
    private String usingDB;
    /**
     * 项目的源码路径
     */
    private String srcPath;
    /**
     * 扫描生成java类的包(po的意思是:Persistence object持久化对象)
     */
    private String poPackage;
    private String queryClass;
    private int poolMinSize;
    private int poolMaxSize;
    
    public String getQueryClass() {
        return queryClass;
    }

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

    public int getPoolMinSize() {
        return poolMinSize;
    }

    public void setPoolMinSize(int poolMinSize) {
        this.poolMinSize = poolMinSize;
    }

    public int getPoolMaxSize() {
        return poolMaxSize;
    }

    public void setPoolMaxSize(int poolMaxSize) {
        this.poolMaxSize = poolMaxSize;
    }

    public Configuration() {
    }
    
    public Configuration(String driver, String url, String user, String pwd,
            String usingDB, String srcPath, String poPackage) {
        super();
        this.driver = driver;
        this.url = url;
        this.user = user;
        this.pwd = pwd;
        this.usingDB = usingDB;
        this.srcPath = srcPath;
        this.poPackage = poPackage;
    }



    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 getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    public String getUsingDB() {
        return usingDB;
    }
    public void setUsingDB(String usingDB) {
        this.usingDB = usingDB;
    }
    public String getSrcPath() {
        return srcPath;
    }
    public void setSrcPath(String srcPath) {
        this.srcPath = srcPath;
    }
    public String getPoPackage() {
        return poPackage;
    }
    public void setPoPackage(String poPackage) {
        this.poPackage = poPackage;
    } 
    
    
    

}
Configuration 管理配置信息
package com.bjsxt.sorm.bean;

/**
 * 封装了java属性和get、set方法的源代码
 * @author gaoqi
 *
 */
public class JavaFieldGetSet {
    /**
     * 属性的源码信息。如:private int userId;
     */
    private String fieldInfo;
    /**
     * get方法的源码信息.如:public int getUserId(){}
     */
    private String getInfo;
    /**
     * set方法的源码信息.如:public void setUserId(int id){this.id = id;}
     */
    private String setInfo;
    
    
    
    @Override
    public String toString() {
        System.out.println(fieldInfo);
        System.out.println(getInfo);
        System.out.println(setInfo);
        return super.toString();
    }
    
    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;
    }
    public JavaFieldGetSet(String fieldInfo, String getInfo, String setInfo) {
        super();
        this.fieldInfo = fieldInfo;
        this.getInfo = getInfo;
        this.setInfo = setInfo;
    }
    
    
    public JavaFieldGetSet() {
    }
}
JavaFieldGetSet 封装了java属性和get、set方法的源代码
package com.bjsxt.sorm.bean;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 存储表结构的信息
 * @author gaoqi 
 *
 */
public class TableInfo {
    /**
     * 表名
     */
    private String tname;  
    
    /**
     * 所有字段的信息
     */
    private Map<String,ColumnInfo> columns;
    
    /**
     * 唯一主键(目前我们只能处理表中有且只有一个主键的情况)
     */
    private ColumnInfo  onlyPriKey;
    
    
    /**
     * 如果联合主键,则在这里存储
     */
    private List<ColumnInfo> priKeys;   
    
    
    public List<ColumnInfo> getPriKeys() {
        return priKeys;
    }

    public void setPriKeys(List<ColumnInfo> priKeys) {
        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 TableInfo(String tname, Map<String, ColumnInfo> columns,
            ColumnInfo onlyPriKey) {
        super();
        this.tname = tname;
        this.columns = columns;
        this.onlyPriKey = onlyPriKey;
    }
    
    public TableInfo() {
    }

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

    
}
TableInfo  存储表结构的信息

 

package com.bjsxt.sorm.core;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public  interface CallBack
{
  public abstract Object doExecute(Connection conn, PreparedStatement ps, ResultSet rs);
}
CallBack
package com.bjsxt.sorm.core;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import com.bjsxt.sorm.bean.Configuration;
import com.bjsxt.sorm.pool.DBConnPool;

/**
 * 根据配置信息,维持连接对象的管理(增加连接池功能)
 * @author Administrator
 *
 */
public class DBManager {
    private static Configuration conf;
    private static DBConnPool pool;
    
    static {  //静态代码块
        Properties pros = new Properties();
        try {
            pros.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        conf = new Configuration();
        conf.setDriver(pros.getProperty("driver"));
        conf.setPoPackage(pros.getProperty("poPackage"));
        conf.setPwd(pros.getProperty("pwd"));
        conf.setSrcPath(pros.getProperty("srcPath"));
        conf.setUrl(pros.getProperty("url"));
        conf.setUser(pros.getProperty("user"));
        conf.setUsingDB(pros.getProperty("usingDB"));
        conf.setQueryClass(pros.getProperty("queryClass"));
        conf.setPoolMaxSize(Integer.parseInt(pros.getProperty("poolMaxSize")));
        conf.setPoolMinSize(Integer.parseInt(pros.getProperty("poolMinSize")));
       System.out.println(TableContext.class);
    }
    
    /*public static Connection getConn(){
        try {
            Class.forName(conf.getDriver());
            return DriverManager.getConnection(conf.getUrl(),
                    conf.getUser(),conf.getPwd());     //直接建立连接,后期增加连接池处理,提高效率!!!
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }*/
    public static Connection getConn()
      {
        if (pool == null) {
          pool = new DBConnPool();
        }
        return pool.getConnection();
      }
    
      public static Connection createConn()
      {
        try
        {
          Class.forName(conf.getDriver());
          return DriverManager.getConnection(conf.getUrl(), 
            conf.getUser(), conf.getPwd());
        } catch (Exception e) {
          e.printStackTrace();
        }return null;
      }
    
      public static void close(ResultSet rs, Statement ps, Connection conn)
      {
        try
        {
          if (rs != null)
            rs.close();
        }
        catch (SQLException e) {
          e.printStackTrace();
        }
        try {
          if (ps != null)
            ps.close();
        }
        catch (SQLException e) {
          e.printStackTrace();
        }

        pool.close(conn);
      }

      public static void close(Statement ps, Connection conn)
      {
        try
        {
          if (ps != null)
            ps.close();
        }
        catch (SQLException e) {
          e.printStackTrace();
        }

        pool.close(conn);
      }

      public static void close(Connection conn)
      {
        pool.close(conn);
      }

    
    /**
     * 返回Configuration对象
     * @return
     */
    public static Configuration getConf(){
        return conf;
    }
    
    
}
DBManager 根据配置信息,维持连接对象的管理(增加连接池功能)
package com.bjsxt.sorm.core;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

import com.bjsxt.po.Dept;
import com.bjsxt.po.Emp;
import com.bjsxt.sorm.bean.ColumnInfo;
import com.bjsxt.sorm.bean.TableInfo;
import com.bjsxt.sorm.utils.JDBCUtils;
import com.bjsxt.sorm.utils.ReflectUtils;
import com.bjsxt.vo.EmpVO;

/**
 * 负责针对Mysql数据库的查询
 * @author gaoqi
 *
 */
public class MySqlQuery extends Query {
    
    public static void testDML(){
        Emp e = new Emp();
        e.setEmpname("lily");
        e.setBirthday(new java.sql.Date(System.currentTimeMillis()));
        e.setAge(30);
        e.setSalary(3000.8);
        e.setId(1);
//        new MySqlQuery().delete(e);
//        new MySqlQuery().insert(e);
        new MySqlQuery().update(e,new String[]{"empname","age","salary"});
    }
    
    public static void testQueryRows(){
        List<Emp> list = new MySqlQuery().queryRows("select id,empname,age from emp where age>? and salary<?",
                Emp.class, new Object[]{10,5000});
        
        for(Emp e:list){
            System.out.println(e.getEmpname());
        }
        
        String sql2 = "select e.id,e.empname,salary+bonus 'xinshui',age,d.dname 'deptName',d.address 'deptAddr' from emp e "
        +"join dept d on e.deptId=d.id ";
        List<EmpVO> list2 = new MySqlQuery().queryRows(sql2,
                EmpVO.class, null);
        
        for(EmpVO e:list2){
            System.out.println(e.getEmpname()+"-"+e.getDeptAddr()+"-"+e.getXinshui());
        }
        
    }
    
    
    public static void main(String[] args) {
       /* Number obj = (Number)new MySqlQuery().queryValue("select count(*) from emp where salary>?",new Object[]{1000});
        Number obj = new MySqlQuery().queryNumber("select count(*) from emp where salary>?",new Object[]{1000});
        System.out.println(obj.doubleValue());*/
        //查询信息
        List<Emp> emps=new  MySqlQuery().queryRows("select * from emp", Emp.class, new Object[0]);
        
        for (Emp emp : emps) {
            System.out.println(emp.toString());
            //Emp [id=1, birthday=2017-11-15, deptid=1, empname=周无极, age=12, bonus=20.0, salary=1200.0]
        }
        /*Number number=(Number)new  MySqlQuery().queryValue("select count(*) from emp ",null);
        System.out.println(number.toString());*/
        //添加信息
       /* Dept dept=new Dept();
        dept.setAddress("南京路");
        dept.setDname("采购部");
        new  MySqlQuery().insert(dept);*/
        
    }

    @Override
    public Object queryPagenate(int pageNum, int size) {
        return null;
    }


}
MySqlQuery  负责针对Mysql数据库的查询
package com.bjsxt.sorm.core;

/**
 * mysql数据类型和java数据类型的转换
 * @author gaoqi
 *
 */
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("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;
    }

    @Override
    public String javaType2DatabaseType(String javaDataType) {
        return null;
    }

}
MySqlTypeConvertor mysql数据类型和java数据类型的转换
package com.bjsxt.sorm.core;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.bjsxt.sorm.bean.ColumnInfo;
import com.bjsxt.sorm.bean.TableInfo;
import com.bjsxt.sorm.utils.JDBCUtils;
import com.bjsxt.sorm.utils.ReflectUtils;

/**
 * 负责查询(对外提供服务的核心类)
 * @author gaoqi ww.sxt.cn
 *
 */
@SuppressWarnings("all")
public abstract class Query implements Cloneable{
    public Object executeQueryTemplate(String sql, Object[] params, Class clazz, CallBack back)
      {
        Connection conn = DBManager.getConn();
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
          ps = conn.prepareStatement(sql);
          JDBCUtils.handleParams(ps, params);
          System.out.println(ps);
          rs = ps.executeQuery();
          return back.doExecute(conn, ps, rs);
        }
        catch (Exception e) {
          e.printStackTrace();
          return null;
        } finally {
          DBManager.close(ps, conn);
        }
      }
    
    /**
     * 直接执行一个DML语句
     * @param sql sql语句
     * @param params 参数
     * @return 执行sql语句后影响记录的行数
     */
    public int executeDML(String sql, Object[] params) {
        Connection conn = DBManager.getConn();
        int count = 0; 
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(sql);
            
            //给sql设参
            JDBCUtils.handleParams(ps, params);
            System.out.println(ps);
            count  = ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            DBManager.close(ps, conn);
        }
        
        return count;
    }
    /**
     * 将一个对象存储到数据库中
     * 把对象中不为null的属性往数据库中存储!如果数字为null则放0.
     * @param obj 要存储的对象
     */
    public void insert(Object obj) {
        //obj-->表中。             insert into 表名  (id,uname,pwd) values (?,?,?)
        Class c = obj.getClass();
        List<Object> params = new ArrayList<Object>();   //存储sql的参数对象
        TableInfo tableInfo = TableContext.poClassTableMap.get(c);
        StringBuilder sql  = new StringBuilder("insert into "+tableInfo.getTname()+" (");
        int countNotNullField = 0;   //计算不为null的属性值
        Field[] fs = c.getDeclaredFields();
        for(Field f:fs){
            String fieldName = f.getName();
            Object fieldValue = ReflectUtils.invokeGet(fieldName, obj);
            
            if(fieldValue!=null){
                countNotNullField++;
                sql.append(fieldName+",");
                params.add(fieldValue);
            }
        }
        
        sql.setCharAt(sql.length()-1, ')');
        sql.append(" values (");
        for(int i=0;i<countNotNullField;i++){
            sql.append("?,");
        }
        sql.setCharAt(sql.length()-1, ')');
        
        executeDML(sql.toString(), params.toArray());
    }
    
    /**
     * 删除clazz表示类对应的表中的记录(指定主键值id的记录)
     * @param clazz 跟表对应的类的Class对象
     * @param id 主键的值
     */
    public void delete(Class clazz, Object id) {
        //Emp.class,2-->delete from emp where id=2
        //通过Class对象找TableInfo
        TableInfo tableInfo = TableContext.poClassTableMap.get(clazz);
        //获得主键
        ColumnInfo onlyPriKey = tableInfo.getOnlyPriKey();
        
        String sql = "delete from "+tableInfo.getTname()+" where "+onlyPriKey.getName()+"=? ";
        
        executeDML(sql, new Object[]{id});
    }    /**
     * 删除对象在数据库中对应的记录(对象所在的类对应到表,对象的主键的值对应到记录)
     * @param obj
     */
    public void delete(Object obj) {
        Class c = obj.getClass();
        TableInfo tableInfo = TableContext.poClassTableMap.get(c);
        ColumnInfo onlyPriKey = tableInfo.getOnlyPriKey();  //主键
        
        //通过反射机制,调用属性对应的get方法或set方法
        Object priKeyValue = ReflectUtils.invokeGet(onlyPriKey.getName(), obj);

        delete(c, priKeyValue);
    }
    /**
     * 更新对象对应的记录,并且只更新指定的字段的值
     * @param obj 所要更新的对象
     * @param fieldNames 更新的属性列表
     * @return 执行sql语句后影响记录的行数
     */
    public int update(Object obj, String[] fieldNames) {
        //obj{"uanme","pwd"}-->update 表名  set uname=?,pwd=? where id=?
        Class c = obj.getClass();
        List<Object> params = new ArrayList<Object>();   //存储sql的参数对象
        //从加载数据库表信息放在map集合里,根据tablebame.class取表信息
        TableInfo tableInfo = TableContext.poClassTableMap.get(c);
        
        ColumnInfo  priKey = tableInfo.getOnlyPriKey(); 
        //获得唯一的主键
        StringBuilder sql  = new StringBuilder("update "+tableInfo.getTname()+" set ");
        
        for(String fname:fieldNames){
            Object fvalue = ReflectUtils.invokeGet(fname,obj);
            params.add(fvalue);
            sql.append(fname+"=?,");
        }
        sql.setCharAt(sql.length()-1, ' ');
        sql.append(" where ");
        sql.append(priKey.getName()+"=? ");
        
        params.add(ReflectUtils.invokeGet(priKey.getName(), obj));    //主键的值
        
        return executeDML(sql.toString(), params.toArray()); 
    }

    
    /**
     * 查询返回多行记录,并将每行记录封装到clazz指定的类的对象中
     * @param sql 查询语句
     * @param clazz 封装数据的javabean类的Class对象
     * @param params sql的参数
     * @return 查询到的结果
     */
     public List queryRows(final String sql,final Class clazz,final Object[] params){
         return (List)executeQueryTemplate(sql, params, clazz, new CallBack(){
            @Override
            public Object doExecute(Connection conn,PreparedStatement ps,ResultSet rs) {
                List list=null;
                try{
                ResultSetMetaData metaData = rs.getMetaData();
                  while (rs.next()) {
                      if (list==null) {
                        list=new ArrayList();
                    }
                    Object rowObj = clazz.newInstance();

                    for (int i = 0; i < metaData.getColumnCount(); i++) {
                      String columnName = metaData.getColumnLabel(i + 1);
                      Object columnValue = rs.getObject(i + 1);
                      ReflectUtils.invokeSet(rowObj, columnName, columnValue);
                      }
                        list.add(rowObj);
                     }
                } catch (Exception e) {
                  e.printStackTrace();
                }
                  return list;
                }
          });
      }
    /**
     * 查询返回一行记录,并将该记录封装到clazz指定的类的对象中
     * @param sql 查询语句
     * @param clazz 封装数据的javabean类的Class对象
     * @param params sql的参数
     * @return 查询到的结果
     */
    public Object queryUniqueRow(String sql, Class clazz, Object[] params) {
        List list = queryRows(sql, clazz, params);
        return (list==null&&list.size()>0)?null:list.get(0);
    }
    
    /**
     * 查询返回一个值(一行一列),并将该值返回
     * @param sql 查询语句
     * @param params sql的参数
     * @return 查询到的结果
     */
     public Object queryValue(String sql, Object[] params)
      {
        return executeQueryTemplate(sql, params, null, new CallBack()
        {  
        @Override
          public Object doExecute(Connection conn, PreparedStatement ps, ResultSet rs) {
            Object value = null;
            try {
              while (rs.next())
                value = rs.getObject(1);
            }
            catch (SQLException e) {
              e.printStackTrace();
            }
            return value;
          }
        });
      }
    
    /**
     * 查询返回一个数字(一行一列),并将该值返回
     * @param sql 查询语句
     * @param params sql的参数
     * @return 查询到的数字
     */
    public Number queryNumber(String sql, Object[] params) {
        return (Number)queryValue(sql, params);
    }
    
    /**
     * 分页查询
     */
     public abstract Object queryPagenate(int pageNum,int size);

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


}
Query  负责查询(对外提供服务的核心类)
package com.bjsxt.sorm.core;

import com.bjsxt.sorm.bean.Configuration;

public class QueryFactory
{
  private static Query prototypeObj;

  static
  {
    try
    {
      Class c = Class.forName(DBManager.getConf().getQueryClass());
      prototypeObj = (Query)c.newInstance();
    } catch (Exception e) {
      e.printStackTrace();
    }

    TableContext.loadPOTables();
  }

  public static Query createQuery()
  {
    try
    {
      return (Query)prototypeObj.clone();
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
    }return null;
  }
}
QueryFactory
package com.bjsxt.sorm.core;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.bjsxt.sorm.bean.ColumnInfo;
import com.bjsxt.sorm.bean.TableInfo;
import com.bjsxt.sorm.utils.JavaFileUtils;
import com.bjsxt.sorm.utils.StringUtils;

/**
 * 负责获取管理数据库所有表结构和类结构的关系,并可以根据表结构生成类结构。
 * @author gaoqi www.sxt.cn
 *
 */
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>();
    
    private TableContext(){}
    
    static {
        try {
            //初始化获得表的信息
            Connection con = DBManager.getConn();
            DatabaseMetaData dbmd = con.getMetaData(); 
            
            ResultSet tableRet = dbmd.getTables(null, "%","%",new String[]{"TABLE"}); 
            
            while(tableRet.next()){
                //得到第一个表名
                String tableName = (String) tableRet.getObject("TABLE_NAME");
                
                TableInfo ti = new TableInfo(tableName, new ArrayList<ColumnInfo>()
                        ,new HashMap<String, 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 set2 = dbmd.getPrimaryKeys(null, "%", tableName);  //查询t_user表中的主键
                while(set2.next()){
                    ColumnInfo ci2 = (ColumnInfo) ti.getColumns().get(set2.getObject("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();
        }
        
        //更新类结构
        updateJavaPOFile();
        
        //加载po包下面所有的类,便于重用,提高效率!
        loadPOTables();
    }
    
    /**
     * 根据表结构,更新配置的po包下面的java类
     * 实现了从表结构转化到类结构
     */
    public static void updateJavaPOFile(){
        Map<String,TableInfo> map = TableContext.tables;
        for(TableInfo t:map.values()){
            JavaFileUtils.createJavaPOFile(t,new MySqlTypeConvertor());
        }    
    }
    
    /**
     * 加载po包下面的类,向poClassTableMap集合放入tableInfo
     */
    public static void loadPOTables(){
        
        for(TableInfo tableInfo:tables.values()){
            try {
                Class c = Class.forName(DBManager.getConf().getPoPackage()
                        +"."+StringUtils.firstChar2UpperCase(tableInfo.getTname()));
                poClassTableMap.put(c, tableInfo);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        
    }
    
    /**
     * 循环遍历集合
     * @param args
     */
    public static void main(String[] args) {
         Map<String,TableInfo>  tables = TableContext.tables;
          Iterator  iterator=tables.values().iterator();
           while (iterator.hasNext()) {
            TableInfo object = (TableInfo) iterator.next();
            System.out.println(object);
            
        }
    }

}
TableContext 负责获取管理数据库所有表结构和类结构的关系
package com.bjsxt.sorm.core;

/**
 * 负责java数据类型和数据库数据类型的互相转换
 * @author gaoqi www.sxt.cn
 *
 */
public interface TypeConvertor {
    
    /**
     * 将数据库数据类型转化成java的数据类型
     * @param columnType 数据库字段的数据类型
     * @return java的数据类型
     */
    public String databaseType2JavaType(String columnType);
    
    /**
     * 将java数据类型转化成数据库数据类型
     * @param javaDataType java数据类型
     * @return 数据库类型
     */
    public String javaType2DatabaseType(String javaDataType);
    
}
TypeConvertor 负责java数据类型和数据库数据类型的互相转换

 

package com.bjsxt.sorm.pool;

import com.bjsxt.sorm.bean.Configuration;
import com.bjsxt.sorm.core.DBManager;
import java.io.PrintStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class DBConnPool
{
  private List<Connection> pool;
  private static final int POOL_MAX_SIZE = DBManager.getConf().getPoolMaxSize();

  private static final int POOL_MIN_SIZE = DBManager.getConf().getPoolMinSize();

  public void initPool()
  {
    if (this.pool == null) {
      this.pool = new ArrayList();
    }

    while (this.pool.size() < POOL_MIN_SIZE) {
       this.pool.add(DBManager.createConn());
      System.out.println("初始化池,池中连接数:" + this.pool.size());
    }
  }

  public synchronized Connection getConnection()
  {
    int last_index = this.pool.size() - 1;
    Connection conn = (Connection)this.pool.get(last_index);
    this.pool.remove(last_index);

    return conn;
  }

  public synchronized void close(Connection conn)
  {
    if (this.pool.size() >= POOL_MAX_SIZE)
      try {
        if (conn == null) return; conn.close();
      }
      catch (SQLException e) {
        e.printStackTrace();
      }
    else
      this.pool.add(conn);
  }

  public DBConnPool()
  {
    initPool();
  }
}
DBConnPool 数据源连接池

 

package com.bjsxt.sorm.utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.bjsxt.sorm.bean.ColumnInfo;
import com.bjsxt.sorm.bean.JavaFieldGetSet;
import com.bjsxt.sorm.bean.TableInfo;
import com.bjsxt.sorm.core.DBManager;
import com.bjsxt.sorm.core.MySqlTypeConvertor;
import com.bjsxt.sorm.core.TableContext;
import com.bjsxt.sorm.core.TypeConvertor;

/**
 * 封装了生成Java文件(源代码)常用的操作
 * @author  www.sxt.cn
 *
 */
public class JavaFileUtils {
    
    /**
     * 根据字段信息生成java属性信息。如:varchar 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());
        
        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\tthis."+column.getName()+"="+column.getName()+";\n");
        setSrc.append("\t}\n");
        jfgs.setSetInfo(setSrc.toString());
        return jfgs;
    }
    
    /**
     * 根据表信息生成java类的源代码
     * @param tableInfo 表信息
     * @param convertor 数据类型转化器 
     * @return java类的源代码
     */
    public static String createJavaSrc(TableInfo tableInfo,TypeConvertor convertor){
        
        Map<String,ColumnInfo> columns = tableInfo.getColumns();
        List<JavaFieldGetSet> javaFields = new ArrayList<JavaFieldGetSet>();

        for(ColumnInfo c:columns.values()){
            javaFields.add(createFieldGetSetSRC(c,convertor));
        }
        
        StringBuilder src = new StringBuilder();
        
        //生成package语句
        src.append("package "+DBManager.getConf().getPoPackage()+";\n\n");
        //生成import语句
        src.append("import java.sql.*;\n");
        src.append("import java.util.*;\n\n");
        //生成类声明语句
        src.append("public class "+StringUtils.firstChar2UpperCase(tableInfo.getTname())+" {\n\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){
        String src = createJavaSrc(tableInfo,convertor);
        
        String srcPath = DBManager.getConf().getSrcPath()+"\\";
        //替换
        String packagePath = DBManager.getConf().getPoPackage().replaceAll("\\.", "/");
        
        File f = new File(srcPath+packagePath);
        
        if(!f.exists()){  //如果指定目录不存在,则帮助用户建立
            f.mkdirs();
        }
        
        BufferedWriter bw = null;
        
        try {
            bw = new BufferedWriter(new FileWriter(f.getAbsoluteFile()+"/"+StringUtils.firstChar2UpperCase(tableInfo.getTname())+".java"));
            bw.write(src);
            System.out.println("建立表"+tableInfo.getTname()+
                    "对应的java类:"+StringUtils.firstChar2UpperCase(tableInfo.getTname())+".java");
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                if(bw!=null){
                    bw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }
    
    
    public static void main(String[] args) {
//        ColumnInfo ci = new ColumnInfo("id", "int", 0);
//        JavaFieldGetSet f = createFieldGetSetSRC(ci,new MySqlTypeConvertor());
//        System.out.println(f);
        
        Map<String,TableInfo> map = TableContext.tables;
        for(TableInfo t:map.values()){
            createJavaPOFile(t,new MySqlTypeConvertor());
        }
    }
    
}
JavaFileUtils 封装了生成Java文件(源代码)常用的操作
package com.bjsxt.sorm.utils;

import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * 封装了JDBC查询常用的操作
 * @author gaoqi www.sxt.cn
 *
 */
public class JDBCUtils {
    
    /**
     * //给sql设参
     * @param ps 预编译sql语句对象
     * @param params 参数
     */
    public static void handleParams(PreparedStatement ps,Object[] params){
        if(params!=null){
            for(int i=0;i<params.length;i++){
                try {
                    ps.setObject(1+i, params[i]);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
JDBCUtils 封装了JDBC查询常用的操作
package com.bjsxt.sorm.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

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

    /**
     * 调用obj对象对应属性fieldName的get方法
     * @param fieldName
     * @param obj
     * @return
     */
    public static Object invokeGet(String fieldName,Object obj){
        try {
            Class c = obj.getClass();
            Method m = c.getDeclaredMethod("get"+StringUtils.firstChar2UpperCase(fieldName), null);
            return m.invoke(obj, null);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } 
    }
    
    
    public static void invokeSet(Object obj,String columnName,Object columnValue){
        try {
            Method m = obj.getClass().getDeclaredMethod("set"+StringUtils.firstChar2UpperCase(columnName), 
                    columnValue.getClass());
            m.invoke(obj, columnValue);
        } catch (Exception e) {
            e.printStackTrace();
        } 

    }
    
    
    
    
}
ReflectUtils 封装了反射常用的操作
package com.bjsxt.sorm.utils;

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

 

package com.bjsxt.vo;

public class EmpVO {
    
    private Integer id;
    private String empname;
    private Double xinshui; 
    private Integer age;
    private String deptName;
    private String deptAddr;
    
    
    public EmpVO(Integer id, String empname, Double xinshui, Integer age,
            String deptName, String deptAddr) {
        super();
        this.id = id;
        this.empname = empname;
        this.xinshui = xinshui;
        this.age = age;
        this.deptName = deptName;
        this.deptAddr = deptAddr;
    }
    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 getXinshui() {
        return xinshui;
    }
    public void setXinshui(Double xinshui) {
        this.xinshui = xinshui;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getDeptName() {
        return deptName;
    }
    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }
    public String getDeptAddr() {
        return deptAddr;
    }
    public void setDeptAddr(String deptAddr) {
        this.deptAddr = deptAddr;
    }
    
    public EmpVO() {
    }
    
}
EmpVO

 

package com.test;

import java.util.List;

import com.bjsxt.po.Emp;
import com.bjsxt.sorm.core.QueryFactory;

public class Test {

    public static void test01() {
        List<Emp> emps = QueryFactory.createQuery().queryRows("select * from emp", Emp.class, null);
        for (Emp emp : emps) {
            System.out.println(emp.toString());
        }
    }
   
    public static void main(String[] args) {
        Long begin=System.currentTimeMillis();
         for (int i = 0; i < 1000; i++) {
             test01();
        }
        Long end=System.currentTimeMillis();
        System.out.println(end-begin);//1262
    }
}
Test
driver=com.mysql.jdbc.Driver
url=jdbc\:mysql\://localhost\:3306/TB47
user=root
pwd=123456
usingDB=mysql
srcPath=D\:\\workspace\\sormtest\\src
#生成的实体类放的路径
poPackage=com.bjsxt.po
#配置的是mysqlquery
queryClass=com.bjsxt.sorm.core.MySqlQuery
poolMinSize=10
poolMaxSize=100
db.properties

 

转载于:https://www.cnblogs.com/ou-pc/p/7223855.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值