zoukankan      html  css  js  c++  java
  • 手写ORM持久层框架(转)

    工程结构:

    本文测试的数据库为:

    其中student的表结构为:

          

    表数据:

    配置文件 DB2.properties

    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://127.0.0.1:3306/test
    user=root
    password=123456
    usingDB=mysql
    srcPath=E:/eclipse_workspace/Test/src
    poPackage=com.frank.po
    queryClass=com.frank.stom.core.imp.MySqlQuery
    poolMinSize=10
    poolMaxSize=100

    只支持mysql数据库.poPackage为框架根据数据库表自动生成的domain类的包名

    下面堆代码:

    package com.frank.stom.bean;
    
    /**
     * 封装表中一个字段的信息
     *
     */
    public class ColumnInfo {
    
        public static final int NORMAL_KEY=0;
        public static final int PRIMARY_KEY=1;
        public static final int FOREIGN_KEY=2;
        
        /**
         *  字段名称
         */
        private String colName;
        
        /**
         * 字段类型
         */
        private String dataType;
        
        /**
         * 字段的键类型
         * 0:普通键 1:主键 2:外键
         */
        private int keyType;
        
        public ColumnInfo(String colName, String dataType, int keyType) {
            super();
            this.colName = colName;
            this.dataType = dataType;
            this.keyType = keyType;
        }
        
        public ColumnInfo() {
            
        }
    
        public String getColName() {
            return colName;
        }
    
        public void setColName(String colName) {
            this.colName = colName;
        }
    
        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;
        }
    
    }
    package com.frank.stom.bean;
    
    /**
     * 管理配置信息
     *
     */
    public class Configuration {
        /**
         * 驱动类
         */
        private String driver;
        /**
         * jdbc-url
         */
        private String url;
        /**
         * 数据库用户名
         */
        private String user;
        /**
         * 数据库密码
         */
        private String password;
        /**
         * 使用的数据库
         */
        private String usingDB;
        /**
         * 项目的源码路径
         */
        private String srcPath;
        /**
         * 扫描生成java类的包
         * persistence object
         */
        private String poPackage;
        
        /**
         * 连接池中最小的连接数
         */
        private int poolMinSize;
        /**
         * 连接池中最大的连接数
         */
        private int poolMaxSize;
        
        /**
         * 项目使用的查询类
         */
        private String queryClass;
        
        public String getQueryClass() {
            return queryClass;
        }
        public void setQueryClass(String queryClass) {
            this.queryClass = queryClass;
        }
        public Configuration(String driver, String url, String user,
                String password, String usingDB,
                String srcPath, String poPackage) {
            super();
            this.driver = driver;
            this.url = url;
            this.user = user;
            this.password = password;
            this.usingDB = usingDB;
            this.srcPath = srcPath;
            this.poPackage = poPackage;
        }
        
        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() {
            super();
        }
        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 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;
        }
        
    }
    package com.frank.stom.bean;
    
    /**
     * 封装了java属性和set/get源码信息
     * 
     * @author frank
     * 
     */
    public class JavaFieldGetSet {
        /**
         * 属性的源码信息
         */
        private String fieldInfo;
        /**
         * get的源码信息
         */
        private String getInfo;
        /**
         * set的源码信息
         */
        private String setInfo;
        
        public JavaFieldGetSet(String fieldInfo, String getInfo, String setInfo) {
            super();
            this.fieldInfo = fieldInfo;
            this.getInfo = getInfo;
            this.setInfo = setInfo;
        }
    
        public JavaFieldGetSet() {
            super();
        }
    
        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(fieldInfo);
            System.out.println(getInfo);
            System.out.println(setInfo);
            return super.toString();
        }
    
    }
    package com.frank.stom.bean;
    
    import java.util.List;
    import java.util.Map;
    
    /**
     * 封装表结构信息
     * @author frank
     *
     */
    public class TableInfo {
        
        /**
         * 表名
         */
        private String tabName;
        
        /**
         * 所以字段信息 
         */
        private Map<String,ColumnInfo> columns;
    
        /**
         * 主键
         */
        private ColumnInfo priKey;
        
        /**
         *联合主键 
         *
         */
        private List<ColumnInfo> priKeys;
        
        public TableInfo(String tabName, Map<String, ColumnInfo> columns, ColumnInfo priKey) {
            super();
            this.tabName = tabName;
            this.columns = columns;
            this.priKey = priKey;
        }
    
        public TableInfo(String tabName, Map<String, ColumnInfo> columns,
                List<ColumnInfo> priKeys) {
            super();
            this.tabName = tabName;
            this.columns = columns;
            this.priKeys = priKeys;
        }
    
        public TableInfo() {
            super();
        }
        
    
        public List<ColumnInfo> getPriKeys() {
            return priKeys;
        }
    
        public void setPriKeys(List<ColumnInfo> priKeys) {
            this.priKeys = priKeys;
        }
    
        public String getTabName() {
            return tabName;
        }
    
        public void setTabName(String tabName) {
            this.tabName = tabName;
        }
    
        public Map<String, ColumnInfo> getColumns() {
            return columns;
        }
    
        public void setColumns(Map<String, ColumnInfo> columns) {
            this.columns = columns;
        }
    
        public ColumnInfo getPriKey() {
            return priKey;
        }
    
        public void setPriKey(ColumnInfo priKey) {
            this.priKey = priKey;
        }
    
    }
    package com.frank.stom.connPool;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    
    import com.frank.stom.core.DBManager;
    
    /**
     * 连接池
     * @author frank
     *
     */
    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 DBconnPool(){
            initPool();
        }
        
        /**
         * 初始化连接池
         */
        public void initPool(){
            if(pool==null){
                pool=new ArrayList<Connection>();
            }
            while(pool.size()<POOL_MIN_SIZE){
                pool.add(DBManager.createConnection());
            }
        }
        
        /**
         * 从连接池中取出一个连接
         * @return 连接
         */
        public synchronized Connection getConnection(){
            int last_index=pool.size()-1;
            Connection conn = pool.get(last_index);
            pool.remove(last_index);
            return conn;
        }
        
        /**
         * 将连接放回池中
         * @param conn 连接
         */
        public synchronized void close(Connection conn){
            if(pool.size()>=POOL_MAX_SIZE)
                try {
                    if(conn!=null)
                        conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            else
                pool.add(conn);
            
        }
        
    }
    package com.frank.stom.core.imp;
    
    import com.frank.stom.core.Query;
    
    /**
     * 负责mysql数据库的操作
     * @author frank
     *
     */
    public class MySqlQuery extends Query {
    
    //    @Override
    //    public Object queryPagenate(int pageNum, int pageSize) {
    //        return null;
    //    }
    }
    package com.frank.stom.core.imp;
    
    import com.frank.stom.core.TypeConvertor;
    
    
    /**
     * mysql数据库类型和java类型的转换
     * 
     * @author frank
     * 
     */
    public class MysqlTypeConvertor implements TypeConvertor {
    
        @Override
        public String databaseType2JavaType(String columnType) {
            // TODO Auto-generated method stub
            // 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 javaType) {
            return null;
        }
    
    }
    package com.frank.stom.core;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    
    public interface CallBack {
        public Object doExecute(Connection conn, PreparedStatement ps,ResultSet rs);
    }
    package com.frank.stom.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.frank.stom.bean.Configuration;
    import com.frank.stom.connPool.DBconnPool;
    
    /**
     *  根据配置信息,维持连接对象的管理 
     * @author frank
     *
     */
    public class DBManager {
    
        /**
         * 配置信息
         */
        private static Configuration conf;
        /**
         * 连接池对象
         */
        private static DBconnPool pool ;
        public static Configuration getConf() {
            return conf;
        }
        static{
            Properties pros=new Properties();
            
            try {
                pros.load(DBManager.class.getClassLoader().getResourceAsStream("DB2.properties"));
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            conf = new Configuration();
            conf.setDriver(pros.getProperty("driver"));
            conf.setPoPackage(pros.getProperty("poPackage"));
            conf.setPassword(pros.getProperty("password"));
            conf.setUrl(pros.getProperty("url"));
            conf.setUser(pros.getProperty("user"));
            conf.setSrcPath(pros.getProperty("srcPath"));
            conf.setUsingDB(pros.getProperty("usingDB"));
            conf.setQueryClass(pros.getProperty("queryClass"));
            conf.setPoolMaxSize(Integer.parseInt(pros.getProperty("poolMaxSize")));
            conf.setPoolMinSize(Integer.parseInt(pros.getProperty("poolMinSize")));  
        }
        /**
         * 获得数据库连接
         * @return 连接
         */
        public static Connection createConnection(){
            try {
                Class.forName(conf.getDriver());
                return DriverManager.getConnection(conf.getUrl(), conf.getUser(), conf.getPassword());
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return null;
            }
        }
        /**
         * 从连接池中获得数据库连接
         * @return 连接
         */
        public static Connection getConnection(){
    //        try {
    //            Class.forName(conf.getDriver());
    //            return DriverManager.getConnection(conf.getUrl(), conf.getUser(), conf.getPassword());
    //        } catch (Exception e) {
    //            // TODO Auto-generated catch block
    //            e.printStackTrace();
    //            return null;
            if(pool==null)
                pool = new DBconnPool();
            return pool.getConnection();
            
        }
        /**
         * 关闭资源
         * @param rs
         * @param ps
         * @param conn
         */
        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);
        }
    }
    package com.frank.stom.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.frank.stom.bean.ColumnInfo;
    import com.frank.stom.bean.TableInfo;
    import com.frank.stom.util.JDBCUtil;
    import com.frank.stom.util.ReflectUtil;
    
    /**
     *    负责查询 对外提供服务的核心类 
     * @author frank
     */
    public abstract class Query implements Cloneable{
        
        /**
         * 采用模板方法模式将JDBC操作封装成模板
         * @param sql sql语句
         * @param params sql参数 
         * @param clazz 记录要封装到的java类
         * @param back CallBack的实现类 回调
         * @return
         */
        public Object executeQueryTemplate(String sql,Object[] params, Class clazz,CallBack back){
            Connection conn=DBManager.getConnection();
            PreparedStatement ps=null;
            ResultSet rs=null;
    
            try {
                ps=conn.prepareStatement(sql);
                JDBCUtil.handleParams(ps, params);
                rs=ps.executeQuery();
                return back.doExecute(conn, ps, rs);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return null;
            }finally{
                DBManager.close(null, ps, conn);
            }
        }
        
        /**
         *    执行一条DML语句 
         * @param sql 要执行的sql语句
         * @param params sql语句参数
         * @return 影响的记录行数
         */
        public int executeDML(String sql, Object[] params) {
            Connection conn=DBManager.getConnection();
            int count=0;
            
            PreparedStatement ps=null;
            
            try {
                ps=conn.prepareStatement(sql);
                JDBCUtil.handleParams(ps, params);
                count=ps.executeUpdate();
            } catch (SQLException e) {
                e.printStackTrace();
            }finally{
                DBManager.close(null, ps, conn);
            }
            return count;
        }
        
        /**
         * 将一个对象储存到数据库中
         * @param obj 要储存的对象
         */
        public void save(Object obj) {
            Class c=obj.getClass();
            List<Object> params =new ArrayList<Object>();
            TableInfo tableInfo = TableContext.poClassTableMap.get(c);
            StringBuilder sql=new StringBuilder("insert into "+tableInfo.getTabName()+" (");
            Field[] fs=c.getDeclaredFields();
            int fieldNotNullCount=0;
    
            for(Field field:fs){
                String fieldName=field.getName();
                Object fieldValue = ReflectUtil.invokeGet(fieldName, obj);
    
                if(fieldValue!=null){
                    fieldNotNullCount++;
                    sql.append(fieldName+",");
                    params.add(fieldValue);
                }
            }
            sql.setCharAt(sql.length()-1, ')');
            sql.append(" values (");
            for(int i=0;i<fieldNotNullCount;i++){
                sql.append("?,");
            }
            sql.setCharAt(sql.length()-1, ')');
    
            this.executeDML(sql.toString(), params.toArray());
        }
        
        /**
         *    删除数据库中的记录 
         * @param clazz 对象类型
         * @param id 主键id
         * @return 影响的记录行数
         */
        @SuppressWarnings("rawtypes")
        public int delete(Class clazz, Object id) {
            // TODO Auto-generated method stub
            //通过class找TableInfo
            TableInfo tableInfo=TableContext.poClassTableMap.get(clazz);
            //主键
            ColumnInfo onlyPriKey=tableInfo.getPriKey();
            
            String sql="delete from "+tableInfo.getTabName()+" where  "+onlyPriKey.getColName()+"=?";
            
            return executeDML(sql, new Object[]{id});
    
        }
        
        /**
         *    删除对应数据库中的记录 
         * @param obj 要删除的对象
         * @return 影响的记录行数
         */
    
        public int delete(Object obj) {
            // TODO Auto-generated method stub
            Class c = obj.getClass();
            TableInfo tableInfo = TableContext.poClassTableMap.get(c);
            ColumnInfo onlyPrikey  = tableInfo.getPriKey();
            
            //反射
            Object priKeyValue=ReflectUtil.invokeGet(onlyPrikey.getColName(), obj);
            return delete(c, priKeyValue);
            
        }
    
        /**
         *     更新对象对应的记录
         * @param obj 对象
         * @return 影响的记录行数
         */
        public int update(Object obj ,String[] fieldNames) {
            // TODO Auto-generated method stub
            Class c=obj.getClass();
            List<Object> params =new ArrayList<Object>();
            TableInfo tableInfo = TableContext.poClassTableMap.get(c);
            ColumnInfo priKey = tableInfo.getPriKey();
            StringBuilder sql=new StringBuilder("update  "+tableInfo.getTabName()+" set ");
    
            for(String fieldName: fieldNames){
                Object fvalue = ReflectUtil.invokeGet(fieldName, obj);
                params.add(fvalue);
                sql.append(fieldName+"=?,");
            }
            params.add(ReflectUtil.invokeGet( priKey.getColName(),obj));
    
            sql.setCharAt(sql.length()-1,' ');
            sql.append(" where ");
            sql.append(priKey.getColName()+"=? ");
            System.out.println(sql.toString());
            return this.executeDML(sql.toString(), params.toArray());
        }
        
        /**
         *    查询数据库返回多条记录 
         * @param sql  sql语句
         * @param clazz 封装javabean类的Class对象
         * @param params sql语句参数
         * @return 查询得到的结果集
         */
        @SuppressWarnings("rawtypes")
        public List queryRows(String sql, final Class clazz, Object[] params) {
            // TODO Auto-generated method stub
            return (List) executeQueryTemplate(sql, params, clazz, new CallBack() {
    
                @Override
                public Object doExecute(Connection conn, PreparedStatement ps,
                        ResultSet rs) {
                    ResultSetMetaData metaDate;
                    List list=null;
                    try {
                        metaDate = rs.getMetaData();
                        while(rs.next()){
                            if(list==null)
                                list=new ArrayList<>();
                            Object rowObj=clazz.newInstance();
                            for(int i=0;i<metaDate.getColumnCount();i++){
                                String columnName = metaDate.getColumnLabel(i+1);
                                Object columnValue = rs.getObject(i+1);
                                //通过反射调用rowObj的set方法
                                ReflectUtil.invokeSet(rowObj, columnName, columnValue);
                                
                            }
                        list.add(rowObj);
                        }
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    return list;
                }
            });
            
        }
        
    
        /**
         *    查询数据库返回一条记录 
         * @param sql  sql语句
         * @param clazz 封装javabean类的Class对象
         * @param params sql语句参数
         * @return 查询得到的结果对象
         */
        @SuppressWarnings("rawtypes")
        public Object queryUniqueRows(String sql, Class clazz,
                Object[] params) {
            // TODO Auto-generated method stub
            List list=queryRows(sql, clazz, params);
            return (list==null||list.size()==0)?null:list.get(0);
        }
    
        /**
         *    查询数据库返回一个值( 一行一列)
         * @param sql  sql语句
         * @param params sql语句参数
         * @return 查询得到的结果对象
         */
        public Object queryValue(String sql, Object[] params) {
            // TODO Auto-generated method stub
            
            return executeQueryTemplate(sql, params, null, new CallBack() {
                
                @Override
                public Object doExecute(Connection conn, PreparedStatement ps,
                        ResultSet rs) {
                    Object value = null;
                    // TODO Auto-generated method stub
                    try {
                        while(rs.next()){
                            value=rs.getObject(1);
                        }
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    return value ;
                }
            });
        }
        
        /**
         *    查询数据库返回一个数字
         * @param sql  sql语句
         * @param params sql语句参数
         * @return 查询得到的结果数字
         */
        public Number queryNumber(String sql, Object[] params) {
            // TODO Auto-generated method stub
            return (Number) queryValue(sql, params);
        }
        
        /**
         * 分页查询 
         * @param pageNum 当前页
         * @param pageSize每页显示的记录条数
         * @return
         */
    //    public abstract Object queryPagenate(int pageNum,int pageSize);
        
        @Override
        protected Object clone() throws CloneNotSupportedException {
            // TODO Auto-generated method stub
            return super.clone();
        }
    
    }
    package com.frank.stom.core;
    
    /**
     * 创建query工厂类
     * @author frank
     *
     */
    public class QueryFactory {
    
        private static QueryFactory factory=new QueryFactory();
        private static Query prototypeObj;
        static{
            try {
                Class c=Class.forName(DBManager.getConf().getQueryClass());
                prototypeObj=(Query) c.newInstance();
                
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        private QueryFactory(){
        }
        
        public static QueryFactory getInstance(){
            return factory;
        }
        
        public Query creatyFactory(){
            try {
                return (Query) prototypeObj.clone();
            } catch (CloneNotSupportedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return null;
            }
            
        }
    }
    package com.frank.stom.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.Map;
    
    import com.frank.stom.bean.ColumnInfo;
    import com.frank.stom.bean.TableInfo;
    import com.frank.stom.core.imp.MysqlTypeConvertor;
    import com.frank.stom.util.JavaFileUtil;
    import com.frank.stom.util.StringUtil;
    
    /**
     * 负责获取管理数据库所有表结构和类结构的关系,并可以根据表结构生成类结构。
     * @author
     *
     */
    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.getConnection();
                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 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 set2 = dbmd.getPrimaryKeys(null, "%", tableName);  //查询t_user表中的主键
                    while(set2.next()){
                        ColumnInfo ci2 = (ColumnInfo) ti.getColumns().get(set2.getObject("COLUMN_NAME"));
                        ci2.setKeyType(ColumnInfo.PRIMARY_KEY);  //设置为主键类型
                        ti.getPriKeys().add(ci2);
                    }
                    
                    if(ti.getPriKeys().size()>0){  //取唯一主键。。方便使用。如果是联合主键。则为空!
                        ti.setPriKey(ti.getPriKeys().get(0));
                    }
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            //更新类结构
            updateJavaPOFile();
            
            //加载po包下的所有的类
            loadPOTables();
            
        
        }
        /**
         * 根据表结构,更新配置po包下的java类
         */
        public static void updateJavaPOFile(){
            Map<String,TableInfo> map=tables;
            for(TableInfo t:map.values()){
                JavaFileUtil.createJavaPOFile(t, new MysqlTypeConvertor());
            }
        }
        /**
         * 加载po包下的类
         */
        public static void loadPOTables(){
            for(TableInfo tableInfo:tables.values()){
                try {
                    Class c = Class.forName(DBManager.getConf().getPoPackage()+
                            "."+StringUtil.firstChar2UpperCase(tableInfo.getTabName()));
                    poClassTableMap.put(c, tableInfo);
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
        }
        
        public static void main(String[] args) {
             Map<String,TableInfo>  tables = TableContext.tables;
             for(String v: tables.keySet()) {
                System.out.println(v); 
             }
             for(TableInfo f:tables.values()){
                System.out.println(f.getPriKey().getColName()); 
             }
             System.out.println(tables);
        }
    
    }
    package com.frank.stom.core;
    
    /**
     *    负责java类型和数据库类型的相互转换  
     * @author frank
     */
    
    public interface TypeConvertor {
        
        /**
         * 将数据库类型转换为java类型 
         * @param columnType 数据库字段类型
         * @return java类型
         */
        public String databaseType2JavaType(String columnType);
        
        /**
         * 将java类型转换为数据库类型 
         * @param javaType java类型
         * @return 数据库类型
         */
        public String javaType2DatabaseType(String  javaType);
    
    }
    package com.frank.stom.util;
    
    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.frank.stom.bean.ColumnInfo;
    import com.frank.stom.bean.JavaFieldGetSet;
    import com.frank.stom.bean.TableInfo;
    import com.frank.stom.core.DBManager;
    import com.frank.stom.core.TypeConvertor;
    
    
    /**
     * 封装生成java源文件的常用操作
     * @author frank
     *
     */
    public class JavaFileUtil {
        
        /**
         *根据字段信息生成java属性信息 
         * @param colum 字段信息
         * @param convertor 类型转换器
         * @return java属性的set/get方法
         */
        public static JavaFieldGetSet createFieldGetSetSRC(ColumnInfo colum,TypeConvertor convertor){
            JavaFieldGetSet fieldSet = new JavaFieldGetSet();
    
            String javaFieldType= convertor.databaseType2JavaType(colum.getDataType());
    
            fieldSet.setFieldInfo("	private "+javaFieldType+" "+colum.getColName()+";
    ");
    
            StringBuffer getSrc=new StringBuffer();
            //public String getUser(){
            //生成get方法源码
            getSrc.append("	public "+javaFieldType+" get"+StringUtil.firstChar2UpperCase(colum.getColName())+"(){
    "   );
            getSrc.append("		return "+colum.getColName()+";
    ");
            getSrc.append("	}
    ");
            fieldSet.setGetInfo(getSrc.toString());
            
            //生成set方法源码
            StringBuffer setSrc= new StringBuffer();
            setSrc.append("	public void set"+StringUtil.firstChar2UpperCase(colum.getColName())+"("   );
            setSrc.append(javaFieldType+" "+colum.getColName()+"){
    ");
            setSrc.append("		this."+colum.getColName()+"="+colum.getColName()+";
    ");
            setSrc.append("	}
    ");
            fieldSet.setSetInfo(setSrc.toString());
            return fieldSet;
        }
            
    
        /**
         * 根据表信息生成java类源码 
         * @param tableInfo 表信息
         * @param convertor 数据类型转换器
         * @return java类源码
         */
        public  static String createJavaSrc(TableInfo tableInfo, TypeConvertor convertor){
            StringBuffer src= new StringBuffer();
            
            Map<String,ColumnInfo> columns=tableInfo.getColumns();
            List<JavaFieldGetSet> javaFields=new ArrayList<JavaFieldGetSet>();
            for(ColumnInfo c:columns.values()){
                javaFields.add(createFieldGetSetSRC(c,convertor));
            }
            //生成package语句
            src.append("package "+DBManager.getConf().getPoPackage()+";
    
    ");
            
            //生成import语句
            src.append("import java.sql.*;
    ");
            src.append("import java.util.*;
    
    ");
            //生成类声明语句
            src.append("public class "+StringUtil.firstChar2UpperCase(tableInfo.getTabName())+" {
    
    ");
    //        System.out.println("public class "+StringUtil.firstChar2UpperCase(tableInfo.getTabName())+" {
    
    ");
    
            
            //生成属性列表
            for(JavaFieldGetSet f:javaFields){
                src.append(f.getFieldInfo());
            }
            src.append("
    
    ");
            
            //生成get方法列表
            for(JavaFieldGetSet f:javaFields){
                src.append(f.getGetInfo());
            }
            
            //生成set方法列表
            for(JavaFieldGetSet f:javaFields){
                src.append(f.getSetInfo());
            }
            
            //生成类结束
            src.append("}
    ");
    //        System.out.println(src);
            return src.toString();
    
        }
        /**
         *根据表信息生成java文件 
         * @param table 表信息
         * @param convertor 类型转换器
         */
        public static void createJavaPOFile(TableInfo table,TypeConvertor convertor){
            String src=createJavaSrc(table, convertor);
            
            String srcPath=DBManager.getConf().getSrcPath()+"//";
            String packagePath=DBManager.getConf().getPoPackage().replaceAll("\.", "/");
            File f=new File(srcPath+packagePath);
    
            System.out.println(f.getAbsolutePath());
            
            if(!f.exists()){
                f.mkdirs();
            }
    
            BufferedWriter bw=null;
            try {
                bw=new BufferedWriter(new FileWriter(f.getAbsoluteFile()+"/"+StringUtil.firstChar2UpperCase(table.getTabName())+".java") );
                bw.write(src);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                if(bw!=null){
                    try {
                        bw.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    package com.frank.stom.util;
    
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    
    /**
     * 封装jdbc常用的操作
     * @author frank
     *
     */
    public class JDBCUtil {
        
        /**
         *给preparedStatement传如参数  
         * @param ps PreparedStatement
         * @param params 参数
         */
        public static void handleParams( PreparedStatement ps,Object[] params){
    
            if(params!=null){
                for(int i=0;i<params.length;i++){
                    try {
                        ps.setObject(i+1,params[i]);
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    }
    package com.frank.stom.util;
    
    import java.lang.reflect.Method;
    
    /**
     * 封装反射的常用操作
     * @author frank
     *
     */
    public class ReflectUtil {
        
        /**
         * 调用obj对象对应属性的get方法
         * @param c
         * @param fieldName
         * @param obj
         * @return
         */
        public static Object invokeGet(String fieldName, Object obj){
            //通过反射机制,调用属性的get方法
                    try {
                        Class c=obj.getClass();
                        Method m=c.getDeclaredMethod("get"+StringUtil.firstChar2UpperCase(fieldName), null);
                         return m.invoke(obj, null);
                    } catch (Exception  e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        return null;
                    }
        }
        
        /**
         * 调用obj对象对应属性的set方法
         * @param c
         * @param fieldName
         * @param obj
         */
        public static void  invokeSet( Object obj ,String fieldName,Object fieldValue){
            //通过反射机制,调用属性的set方法
                    try {
                        Class c=obj.getClass();
                        Method m=c.getDeclaredMethod("set"+StringUtil.firstChar2UpperCase(fieldName), fieldValue.getClass());
                        m.invoke(obj, fieldValue);
                    } catch (Exception  e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
        }
    
    }
    package com.frank.stom.util;
    
    /**
     * 封装String 类型的常用操作
     * @author frank
     *
     */
    public class StringUtil {
        
        /**
         * 将目标字符串首字母变为大写
         * @param str 目标字符串
         * @return 首字母大写的字符串
         */
        public static String firstChar2UpperCase(String str){
            
            return str.toUpperCase().substring(0,1)+str.substring(1);
            
        }
    
    }
    package com.frank.stom.test;
    
    import java.util.List;
    
    import com.frank.po.Student;
    import com.frank.stom.core.Query;
    import com.frank.stom.core.QueryFactory;
    
    public class TestMain {
    
        public static void main(String[] args) {
            String sql = "SELECT * FROM student WHERE id = ?";
            
            Student stu1  = new Student(); //这一new 产生一个Student对象,一个Class对象
            Class clazz = stu1.getClass();
            
            Object[] params = new Object[1];
            params[0] = "1";
            
            QueryFactory aueryFactory = QueryFactory.getInstance();
            Query query = aueryFactory.creatyFactory();
            Object obj = query.queryUniqueRows(sql, clazz, params);
            System.out.println(obj);
            
            System.out.println();
            
            sql = "SELECT * FROM student";
            params = null;
            List<Student> list = query.queryRows(sql, clazz, params);
            for(Student student : list) {
                System.out.println(student);
            }
        }
    
    }

    对于数据库表的实体类 po包下面的类 是自动生成的,运行TableContext里面的main()方法,提前生成好实体类,可以根据需要添加实体类的toStirng(),hashCode()等方法。

    生成完实体类之后,运行TestMain()进行一些查询,结果为:

     

    转自:https://www.cnblogs.com/frankM/p/4590338.html

  • 相关阅读:
    变量,基本数据类型
    编程语言分类,Python介绍、IDE集成开发环境,注释
    Django之Cookie,Session
    第三章
    第二章
    第一章
    php面向对象(文件操作)
    php面向对象(目录操作)
    php有关类和对象的相关知识2
    php有关类和对象的相关知识1
  • 原文地址:https://www.cnblogs.com/myseries/p/10839104.html
Copyright © 2011-2022 走看看