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

    根据尚学堂录的教程做的。:

    配置文件 db.properties

    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://127.0.0.1:3306/sorm
    user=root
    password=123
    usingDB=mysql
    srcPath=/home/frank/MyEclipseWorkSpace/S_ORM/src
    poPackage=com.frank.po
    queryClass=com.frank.sorm.core.imp.MySqlQuery
    poolMinSize=10
    poolMaxSize=100

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

    com.frank.sorm.bean

      ColumnInfo.java

      

     1 package com.frank.sorm.bean;
     2 
     3 /**
     4  * 封装表中一个字段的信息
     5  * @author frank
     6  *
     7  */
     8 public class ColumnInfo {
     9     
    10 
    11     public static final int NORMAL_KEY=0;
    12     public  static final int PRIMARY_KEY=1;
    13     public  static final int FOREIGN_KEY=2;
    14     
    15     /**
    16      *  字段名称
    17      */
    18     private String colName;
    19     
    20     /**
    21      * 字段类型
    22      */
    23     private String dataType;
    24     
    25     /**
    26      * 字段的键类型
    27      * 0:普通键 1:主键 2:外键
    28      */
    29     private int keyType;
    30 
    31     public String getColName() {
    32         return colName;
    33     }
    34 
    35     public void setColName(String colName) {
    36         this.colName = colName;
    37     }
    38 
    39     public String getDataType() {
    40         return dataType;
    41     }
    42 
    43     public void setDataType(String dataType) {
    44         this.dataType = dataType;
    45     }
    46 
    47     public int getKeyType() {
    48         return keyType;
    49     }
    50 
    51     public void setKeyType(int keyType) {
    52         this.keyType = keyType;
    53     }
    54 
    55     public ColumnInfo(String colName, String dataType, int keyType) {
    56         super();
    57         this.colName = colName;
    58         this.dataType = dataType;
    59         this.keyType = keyType;
    60     }
    61     public ColumnInfo() {
    62     }
    63 
    64 }
    View Code

      Configuration.java

      1 package com.frank.sorm.bean;
      2 
      3 /**
      4  * 管理配置信息
      5  * @author frank
      6  *
      7  */
      8 public class Configuration {
      9     /**
     10      * 驱动类
     11      */
     12     private String driver;
     13     /**
     14      * jdbc-url
     15      */
     16     private String url;
     17     /**
     18      * 数据库用户名
     19      */
     20     private String user;
     21     /**
     22      * 数据库密码
     23      */
     24     private String password;
     25     /**
     26      * 使用的数据库
     27      */
     28     private String usingDB;
     29     /**
     30      * 项目的源码路径
     31      */
     32     private String srcPath;
     33     /**
     34      * 扫描生成java类的包
     35      * persistence object
     36      */
     37     private String poPackage;
     38     
     39     /**
     40      * 连接池中最小的连接数
     41      */
     42     private int poolMinSize;
     43     /**
     44      * 连接池中最大的连接数
     45      */
     46     private int poolMaxSize;
     47 
     48     
     49     /**
     50      * 项目使用的查询类
     51      */
     52     private String queryClass;
     53     public String getQueryClass() {
     54         return queryClass;
     55     }
     56     public void setQueryClass(String queryClass) {
     57         this.queryClass = queryClass;
     58     }
     59     public Configuration(String driver, String url, String user,
     60             String password, String usingDB,
     61             String srcPath, String poPackage) {
     62         super();
     63         this.driver = driver;
     64         this.url = url;
     65         this.user = user;
     66         this.password = password;
     67         this.usingDB = usingDB;
     68         this.srcPath = srcPath;
     69         this.poPackage = poPackage;
     70     }
     71     
     72     public int getPoolMinSize() {
     73         return poolMinSize;
     74     }
     75     public void setPoolMinSize(int poolMinSize) {
     76         this.poolMinSize = poolMinSize;
     77     }
     78     public int getPoolMaxSize() {
     79         return poolMaxSize;
     80     }
     81     public void setPoolMaxSize(int poolMaxSize) {
     82         this.poolMaxSize = poolMaxSize;
     83     }
     84     public Configuration() {
     85         super();
     86     }
     87     public String getDriver() {
     88         return driver;
     89     }
     90     public void setDriver(String driver) {
     91         this.driver = driver;
     92     }
     93     public String getUrl() {
     94         return url;
     95     }
     96     public void setUrl(String url) {
     97         this.url = url;
     98     }
     99     public String getUser() {
    100         return user;
    101     }
    102     public void setUser(String user) {
    103         this.user = user;
    104     }
    105     public String getPassword() {
    106         return password;
    107     }
    108     public void setPassword(String password) {
    109         this.password = password;
    110     }
    111     public String getUsingDB() {
    112         return usingDB;
    113     }
    114     public void setUsingDB(String usingDB) {
    115         this.usingDB = usingDB;
    116     }
    117     public String getSrcPath() {
    118         return srcPath;
    119     }
    120     public void setSrcPath(String srcPath) {
    121         this.srcPath = srcPath;
    122     }
    123     public String getPoPackage() {
    124         return poPackage;
    125     }
    126     public void setPoPackage(String poPackage) {
    127         this.poPackage = poPackage;
    128     }
    129     
    130     
    131     
    132     
    133     
    134 
    135 }
    View Code

      JavaFieldGetSet.java

     1 package com.frank.sorm.bean;
     2 
     3 /**
     4  * 封装了java属性和set/get源码信息
     5  * 
     6  * @author frank
     7  * 
     8  */
     9 public class JavaFieldGetSet {
    10     /**
    11      * 属性的源码信息
    12      */
    13     private String fieldInfo;
    14     /**
    15      * get的源码信息
    16      */
    17     private String getInfo;
    18     /**
    19      * set的源码信息
    20      */
    21     private String setInfo;
    22 
    23     public String getFieldInfo() {
    24         return fieldInfo;
    25     }
    26 
    27     public void setFieldInfo(String fieldInfo) {
    28         this.fieldInfo = fieldInfo;
    29     }
    30 
    31     public String getGetInfo() {
    32         return getInfo;
    33     }
    34 
    35     public void setGetInfo(String getInfo) {
    36         this.getInfo = getInfo;
    37     }
    38 
    39     public String getSetInfo() {
    40         return setInfo;
    41     }
    42 
    43     public void setSetInfo(String setInfo) {
    44         this.setInfo = setInfo;
    45     }
    46 
    47     public JavaFieldGetSet(String fieldInfo, String getInfo,
    48             String setInfo) {
    49         super();
    50         this.fieldInfo = fieldInfo;
    51         this.getInfo = getInfo;
    52         this.setInfo = setInfo;
    53     }
    54 
    55     public JavaFieldGetSet() {
    56         super();
    57     }
    58 
    59     @Override
    60     public String toString() {
    61         System.out.println(fieldInfo);
    62         System.out.println(getInfo);
    63         System.out.println(setInfo);
    64         return super.toString();
    65     }
    66 
    67 }
    View Code

      TableInfo.java

     1 package com.frank.sorm.bean;
     2 
     3 import java.util.List;
     4 import java.util.Map;
     5 
     6 /**
     7  * 封装表结构信息
     8  * @author frank
     9  *
    10  */
    11 public class TableInfo {
    12     
    13     /**
    14      * 表名
    15      */
    16     private String tabName;
    17     
    18     /**
    19      * 所以字段信息 
    20      */
    21     private Map<String,ColumnInfo> columns;
    22 
    23     /**
    24      * 主键
    25      */
    26     private ColumnInfo priKey;
    27     
    28     /**
    29      *联合主键 
    30      *
    31      */
    32     private List<ColumnInfo> priKeys;
    33     
    34 
    35     public List<ColumnInfo> getPriKeys() {
    36         return priKeys;
    37     }
    38 
    39     public void setPriKeys(List<ColumnInfo> priKeys) {
    40         this.priKeys = priKeys;
    41     }
    42 
    43     public String getTabName() {
    44         return tabName;
    45     }
    46 
    47     public void setTabName(String tabName) {
    48         this.tabName = tabName;
    49     }
    50 
    51     public Map<String, ColumnInfo> getColumns() {
    52         return columns;
    53     }
    54 
    55     public void setColumns(Map<String, ColumnInfo> columns) {
    56         this.columns = columns;
    57     }
    58 
    59     public ColumnInfo getPriKey() {
    60         return priKey;
    61     }
    62 
    63     public void setPriKey(ColumnInfo priKey) {
    64         this.priKey = priKey;
    65     }
    66 
    67     public TableInfo(String tabName, Map<String, ColumnInfo> columns,
    68             ColumnInfo priKey) {
    69         super();
    70         this.tabName = tabName;
    71         this.columns = columns;
    72         this.priKey = priKey;
    73     }
    74 
    75     public TableInfo(String tabName, Map<String, ColumnInfo> columns,
    76             List<ColumnInfo> priKeys) {
    77         super();
    78         this.tabName = tabName;
    79         this.columns = columns;
    80         this.priKeys = priKeys;
    81     }
    82 
    83     public TableInfo() {
    84         super();
    85     }
    86     
    87     
    88 
    89 }
    View Code

    com.frank.sorm.connPool

      DBconnPool.java

     1 package com.frank.sorm.connPool;
     2 
     3 import java.sql.Connection;
     4 import java.sql.SQLException;
     5 import java.util.ArrayList;
     6 import java.util.List;
     7 
     8 import com.frank.sorm.core.DBManager;
     9 
    10 /**
    11  * 连接池
    12  * @author frank
    13  *
    14  */
    15 public class DBconnPool {
    16     /**
    17      * 连接池对象
    18      */
    19     private  List<Connection> pool;
    20     /**
    21      * 最大连接数
    22      */
    23     private static final int POOL_MAX_SIZE=DBManager.getConf().getPoolMaxSize();
    24     /**
    25      * 最小连接数
    26      */
    27     private static final int POOL_MIN_SIZE=DBManager.getConf().getPoolMinSize();
    28         
    29     
    30     /**
    31      * 初始化连接池
    32      */
    33     public void initPool(){
    34         if(pool==null){
    35             pool=new ArrayList<Connection>();
    36         }
    37         while(pool.size()<POOL_MIN_SIZE){
    38             pool.add(DBManager.createConnection());
    39         }
    40     }
    41     
    42     /**
    43      * 从连接池中取出一个连接
    44      * @return 连接
    45      */
    46     public synchronized Connection getConnection(){
    47         int last_index=pool.size()-1;
    48         Connection conn = pool.get(last_index);
    49         pool.remove(last_index);
    50         return conn;
    51     }
    52     
    53     /**
    54      * 将连接放回池中
    55      * @param conn 连接
    56      */
    57     public synchronized void close(Connection conn){
    58         if(pool.size()>=POOL_MAX_SIZE)
    59             try {
    60                 if(conn!=null)
    61                     conn.close();
    62             } catch (SQLException e) {
    63                 // TODO Auto-generated catch block
    64                 e.printStackTrace();
    65             }
    66         else
    67             pool.add(conn);
    68         
    69     }
    70     
    71     
    72     
    73     
    74     
    75     public DBconnPool(){
    76         initPool();
    77     }
    78 
    79 }
    View Code

    com.frank.sorm.core

      CallBack.java

    1 package com.frank.sorm.core;
    2 
    3 import java.sql.Connection;
    4 import java.sql.PreparedStatement;
    5 import java.sql.ResultSet;
    6 
    7 public interface CallBack {
    8     public Object doExecute(Connection conn, PreparedStatement ps,ResultSet rs);
    9 }
    View Code

      DBManager.java

      1 package com.frank.sorm.core;
      2 
      3 import java.io.IOException;
      4 import java.sql.Connection;
      5 import java.sql.DriverManager;
      6 import java.sql.ResultSet;
      7 import java.sql.SQLException;
      8 import java.sql.Statement;
      9 import java.util.Properties;
     10 
     11 import com.frank.sorm.bean.Configuration;
     12 import com.frank.sorm.connPool.DBconnPool;
     13 
     14 /**
     15  *  根据配置信息,维持连接对象的管理 
     16  * @author frank
     17  *
     18  */
     19 public class DBManager {
     20 
     21     /**
     22      * 配置信息
     23      */
     24     private static Configuration conf;
     25     /**
     26      * 连接池对象
     27      */
     28     private static DBconnPool pool ;
     29     public static Configuration getConf() {
     30         return conf;
     31     }
     32     static{
     33         Properties pros=new Properties();
     34         
     35         try {
     36             pros.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
     37         } catch (IOException e) {
     38             // TODO Auto-generated catch block
     39             e.printStackTrace();
     40         }
     41         conf = new Configuration();
     42         conf.setDriver(pros.getProperty("driver"));
     43         conf.setPoPackage(pros.getProperty("poPackage"));
     44         conf.setPassword(pros.getProperty("password"));
     45         conf.setUrl(pros.getProperty("url"));
     46         conf.setUser(pros.getProperty("user"));
     47         conf.setSrcPath(pros.getProperty("srcPath"));
     48         conf.setUsingDB(pros.getProperty("usingDB"));
     49         conf.setQueryClass(pros.getProperty("queryClass"));
     50         conf.setPoolMaxSize(Integer.parseInt(pros.getProperty("poolMaxSize")));
     51         conf.setPoolMinSize(Integer.parseInt(pros.getProperty("poolMinSize")));
     52         
     53         
     54 
     55     }
     56     /**
     57      * 获得数据库连接
     58      * @return 连接
     59      */
     60     public static Connection createConnection(){
     61         try {
     62             Class.forName(conf.getDriver());
     63             return DriverManager.getConnection(conf.getUrl(), conf.getUser(), conf.getPassword());
     64         } catch (Exception e) {
     65             // TODO Auto-generated catch block
     66             e.printStackTrace();
     67             return null;
     68         }
     69     }
     70     /**
     71      * 从连接池中获得数据库连接
     72      * @return 连接
     73      */
     74     public static Connection getConnection(){
     75 //        try {
     76 //            Class.forName(conf.getDriver());
     77 //            return DriverManager.getConnection(conf.getUrl(), conf.getUser(), conf.getPassword());
     78 //        } catch (Exception e) {
     79 //            // TODO Auto-generated catch block
     80 //            e.printStackTrace();
     81 //            return null;
     82         if(pool==null)
     83             pool = new DBconnPool();
     84         return pool.getConnection();
     85         
     86     }
     87     /**
     88      * 关闭资源
     89      * @param rs
     90      * @param ps
     91      * @param conn
     92      */
     93     public static void close(ResultSet rs,Statement ps,Connection conn){
     94         try {
     95             if(rs!=null){
     96                 rs.close();
     97             }
     98         } catch (SQLException e) {
     99             e.printStackTrace();
    100         }
    101         try {
    102             if(ps!=null){
    103                 ps.close();
    104             }
    105         } catch (SQLException e) {
    106             e.printStackTrace();
    107         }
    108         pool.close(conn);
    109     }
    110 }
    View Code

      Query.java

      1 package com.frank.sorm.core;
      2 
      3 import java.lang.reflect.Field;
      4 import java.sql.Connection;
      5 import java.sql.PreparedStatement;
      6 import java.sql.ResultSet;
      7 import java.sql.ResultSetMetaData;
      8 import java.sql.SQLException;
      9 import java.util.ArrayList;
     10 import java.util.List;
     11 
     12 import com.frank.sorm.bean.ColumnInfo;
     13 import com.frank.sorm.bean.TableInfo;
     14 import com.frank.sorm.util.JDBCUtil;
     15 import com.frank.sorm.util.ReflectUtil;
     16 
     17 /**
     18  *    负责查询 对外提供服务的核心类 
     19  * @author frank
     20  */
     21 public abstract class Query implements Cloneable{
     22     
     23     /**
     24      * 采用模板方法模式将JDBC操作封装成模板
     25      * @param sql sql语句
     26      * @param params sql参数 
     27      * @param clazz 记录要封装到的java类
     28      * @param back CallBack的实现类 回调
     29      * @return
     30      */
     31     public Object executeQueryTemplate(String sql,Object[] params, Class clazz,CallBack back){
     32         Connection conn=DBManager.getConnection();
     33         PreparedStatement ps=null;
     34         ResultSet rs=null;
     35 
     36         try {
     37             ps=conn.prepareStatement(sql);
     38             JDBCUtil.handleParams(ps, params);
     39             rs=ps.executeQuery();
     40             return back.doExecute(conn, ps, rs);
     41         } catch (Exception e) {
     42             // TODO Auto-generated catch block
     43             e.printStackTrace();
     44             return null;
     45         }finally{
     46             DBManager.close(null, ps, conn);
     47         }
     48     }
     49     
     50     /**
     51      *    执行一条DML语句 
     52      * @param sql 要执行的sql语句
     53      * @param params sql语句参数
     54      * @return 影响的记录行数
     55      */
     56     public int executeDML(String sql, Object[] params) {
     57         // TODO Auto-generated method stub
     58         Connection conn=DBManager.getConnection();
     59         int count=0;
     60         
     61         PreparedStatement ps=null;
     62         
     63         try {
     64             ps=conn.prepareStatement(sql);
     65             JDBCUtil.handleParams(ps, params);
     66             count=ps.executeUpdate();
     67         } catch (SQLException e) {
     68             // TODO Auto-generated catch block
     69             e.printStackTrace();
     70         }finally{
     71             DBManager.close(null, ps, conn);
     72         }
     73         return count;
     74     }
     75     
     76     /**
     77      *      将一个对象储存到数据库中
     78      * @param obj 要储存的对象
     79      */
     80     public void save(Object obj) {
     81         // TODO Auto-generated method stub
     82         Class c=obj.getClass();
     83         List<Object> params =new ArrayList<Object>();
     84         TableInfo tableInfo = TableContext.poClassTableMap.get(c);
     85         StringBuilder sql=new StringBuilder("insert into "+tableInfo.getTabName()+" (");
     86         Field[] fs=c.getDeclaredFields();
     87         int fieldNotNullCount=0;
     88 
     89         for(Field field:fs){
     90             String fieldName=field.getName();
     91             Object fieldValue = ReflectUtil.invokeGet(fieldName, obj);
     92 
     93             if(fieldValue!=null){
     94                 fieldNotNullCount++;
     95                 sql.append(fieldName+",");
     96                 params.add(fieldValue);
     97             }
     98         }
     99         sql.setCharAt(sql.length()-1, ')');
    100         sql.append(" values (");
    101         for(int i=0;i<fieldNotNullCount;i++){
    102             sql.append("?,");
    103         }
    104         sql.setCharAt(sql.length()-1, ')');
    105 
    106         this.executeDML(sql.toString(), params.toArray());
    107     }
    108     
    109     /**
    110      *    删除数据库中的记录 
    111      * @param clazz 对象类型
    112      * @param id 主键id
    113      * @return 影响的记录行数
    114      */
    115     @SuppressWarnings("rawtypes")
    116     public int delete(Class clazz, Object id) {
    117         // TODO Auto-generated method stub
    118         //通过class找TableInfo
    119         TableInfo tableInfo=TableContext.poClassTableMap.get(clazz);
    120         //主键
    121         ColumnInfo onlyPriKey=tableInfo.getPriKey();
    122         
    123         String sql="delete from "+tableInfo.getTabName()+" where  "+onlyPriKey.getColName()+"=?";
    124         
    125         return executeDML(sql, new Object[]{id});
    126 
    127     }
    128     
    129     /**
    130      *    删除对应数据库中的记录 
    131      * @param obj 要删除的对象
    132      * @return 影响的记录行数
    133      */
    134 
    135     public int delete(Object obj) {
    136         // TODO Auto-generated method stub
    137         Class c = obj.getClass();
    138         TableInfo tableInfo = TableContext.poClassTableMap.get(c);
    139         ColumnInfo onlyPrikey  = tableInfo.getPriKey();
    140         
    141         //反射
    142         Object priKeyValue=ReflectUtil.invokeGet(onlyPrikey.getColName(), obj);
    143         return delete(c, priKeyValue);
    144         
    145         
    146     }
    147 
    148     /**
    149      *     更新对象对应的记录
    150      * @param obj 对象
    151      * @return 影响的记录行数
    152      */
    153     public int update(Object obj ,String[] fieldNames) {
    154         // TODO Auto-generated method stub
    155         Class c=obj.getClass();
    156         List<Object> params =new ArrayList<Object>();
    157         TableInfo tableInfo = TableContext.poClassTableMap.get(c);
    158         ColumnInfo priKey = tableInfo.getPriKey();
    159         StringBuilder sql=new StringBuilder("update  "+tableInfo.getTabName()+" set ");
    160 
    161         for(String fieldName: fieldNames){
    162             Object fvalue = ReflectUtil.invokeGet(fieldName, obj);
    163             params.add(fvalue);
    164             sql.append(fieldName+"=?,");
    165         }
    166         params.add(ReflectUtil.invokeGet( priKey.getColName(),obj));
    167 
    168         sql.setCharAt(sql.length()-1,' ');
    169         sql.append(" where ");
    170         sql.append(priKey.getColName()+"=? ");
    171         System.out.println(sql.toString());
    172         return this.executeDML(sql.toString(), params.toArray());
    173     }
    174     
    175     /**
    176      *    查询数据库返回多条记录 
    177      * @param sql  sql语句
    178      * @param clazz 封装javabean类的Class对象
    179      * @param params sql语句参数
    180      * @return 查询得到的结果集
    181      */
    182     @SuppressWarnings("rawtypes")
    183     public List queryRows(String sql, final Class clazz, Object[] params) {
    184         // TODO Auto-generated method stub
    185         return (List) executeQueryTemplate(sql, params, clazz, new CallBack() {
    186 
    187             @Override
    188             public Object doExecute(Connection conn, PreparedStatement ps,
    189                     ResultSet rs) {
    190                 ResultSetMetaData metaDate;
    191                 List list=null;
    192                 try {
    193                     metaDate = rs.getMetaData();
    194                     while(rs.next()){
    195                         if(list==null)
    196                             list=new ArrayList<>();
    197                         Object rowObj=clazz.newInstance();
    198                         for(int i=0;i<metaDate.getColumnCount();i++){
    199                             String columnName = metaDate.getColumnLabel(i+1);
    200                             Object columnValue = rs.getObject(i+1);
    201                             //通过反射调用rowObj的set方法
    202                             ReflectUtil.invokeSet(rowObj, columnName, columnValue);
    203                             
    204                         }
    205                     list.add(rowObj);
    206                     }
    207                 } catch (Exception e) {
    208                     // TODO Auto-generated catch block
    209                     e.printStackTrace();
    210                 }
    211                 return list;
    212             }
    213         });
    214         
    215     
    216     }
    217     
    218 
    219     /**
    220      *    查询数据库返回一条记录 
    221      * @param sql  sql语句
    222      * @param clazz 封装javabean类的Class对象
    223      * @param params sql语句参数
    224      * @return 查询得到的结果对象
    225      */
    226     @SuppressWarnings("rawtypes")
    227     public Object queryUniqueRows(String sql, Class clazz,
    228             Object[] params) {
    229         // TODO Auto-generated method stub
    230         List list=queryRows(sql, clazz, params);
    231         return (list==null||list.size()==0)?null:list.get(0);
    232     }
    233     
    234 
    235     /**
    236      *    查询数据库返回一个值( 一行一列)
    237      * @param sql  sql语句
    238      * @param params sql语句参数
    239      * @return 查询得到的结果对象
    240      */
    241     public Object queryValue(String sql, Object[] params) {
    242         // TODO Auto-generated method stub
    243         
    244         return executeQueryTemplate(sql, params, null, new CallBack() {
    245             
    246             @Override
    247             public Object doExecute(Connection conn, PreparedStatement ps,
    248                     ResultSet rs) {
    249                 Object value = null;
    250                 // TODO Auto-generated method stub
    251                 try {
    252                     while(rs.next()){
    253                         value=rs.getObject(1);
    254                     }
    255                 } catch (SQLException e) {
    256                     // TODO Auto-generated catch block
    257                     e.printStackTrace();
    258                 }
    259                 return value ;
    260             }
    261         });
    262     }
    263     
    264     /**
    265      *    查询数据库返回一个数字
    266      * @param sql  sql语句
    267      * @param params sql语句参数
    268      * @return 查询得到的结果数字
    269      */
    270     public Number queryNumber(String sql, Object[] params) {
    271         // TODO Auto-generated method stub
    272         return (Number) queryValue(sql, params);
    273     }
    274     
    275     /**
    276      * 分页查询 
    277      * @param pageNum 当前页
    278      * @param pageSize每页显示的记录条数
    279      * @return
    280      */
    281     public abstract Object queryPagenate(int pageNum,int pageSize);
    282     
    283     @Override
    284     protected Object clone() throws CloneNotSupportedException {
    285         // TODO Auto-generated method stub
    286         return super.clone();
    287     }
    288 
    289 
    290 }
    View Code

      QueryFactory.java

     1 package com.frank.sorm.core;
     2 
     3 /**
     4  * 创建query工厂类
     5  * @author frank
     6  *
     7  */
     8 public class QueryFactory {
     9 
    10     private static QueryFactory factory=new QueryFactory();
    11     private static Query prototypeObj;
    12     static{
    13         try {
    14             Class c=Class.forName(DBManager.getConf().getQueryClass());
    15             prototypeObj=(Query) c.newInstance();
    16             
    17         } catch (Exception e) {
    18             // TODO Auto-generated catch block
    19             e.printStackTrace();
    20         }
    21         
    22     }
    23     private QueryFactory(){
    24     }
    25     
    26     public static QueryFactory getInstance(){
    27         return factory;
    28     }
    29     
    30     
    31     public Query creatyFactory(){
    32         try {
    33             return (Query) prototypeObj.clone();
    34         } catch (CloneNotSupportedException e) {
    35             // TODO Auto-generated catch block
    36             e.printStackTrace();
    37             return null;
    38         }
    39         
    40     }
    41 }
    View Code

      TableContext.java

      1 package com.frank.sorm.core;
      2 
      3 import java.sql.Connection;
      4 import java.sql.DatabaseMetaData;
      5 import java.sql.ResultSet;
      6 import java.sql.SQLException;
      7 import java.util.ArrayList;
      8 import java.util.HashMap;
      9 import java.util.Map;
     10 
     11 import javax.swing.text.TabExpander;
     12 
     13 import com.frank.sorm.bean.ColumnInfo;
     14 import com.frank.sorm.bean.TableInfo;
     15 import com.frank.sorm.core.imp.MysqlTypeConvertor;
     16 import com.frank.sorm.util.JavaFileUtil;
     17 import com.frank.sorm.util.StringUtil;
     18 
     19 
     20 
     21 /**
     22  * 负责获取管理数据库所有表结构和类结构的关系,并可以根据表结构生成类结构。
     23  * @author gaoqi www.sxt.cn
     24  *
     25  */
     26 public class TableContext {
     27 
     28     /**
     29      * 表名为key,表信息对象为value
     30      */
     31     public static  Map<String,TableInfo>  tables = new HashMap<String,TableInfo>();
     32     
     33     /**
     34      * 将po的class对象和表信息对象关联起来,便于重用!
     35      */
     36     public static  Map<Class,TableInfo>  poClassTableMap = new HashMap<Class,TableInfo>();
     37     
     38     private TableContext(){}
     39     
     40     static {
     41         try {
     42             //初始化获得表的信息
     43             Connection con = DBManager.getConnection();
     44             DatabaseMetaData dbmd = con.getMetaData(); 
     45             
     46             ResultSet tableRet = dbmd.getTables(null, "%","%",new String[]{"TABLE"}); 
     47             
     48             while(tableRet.next()){
     49                 String tableName = (String) tableRet.getObject("TABLE_NAME");
     50                 
     51                 TableInfo ti = new TableInfo(tableName,new HashMap<String, ColumnInfo>(), new ArrayList<ColumnInfo>() );
     52                 tables.put(tableName, ti);
     53                 
     54                 ResultSet set = dbmd.getColumns(null, "%", tableName, "%");  //查询表中的所有字段
     55                 while(set.next()){
     56                     ColumnInfo ci = new ColumnInfo(set.getString("COLUMN_NAME"), 
     57                             set.getString("TYPE_NAME"), 0);
     58                     ti.getColumns().put(set.getString("COLUMN_NAME"), ci);
     59                 }
     60                 
     61                 ResultSet set2 = dbmd.getPrimaryKeys(null, "%", tableName);  //查询t_user表中的主键
     62                 while(set2.next()){
     63                     ColumnInfo ci2 = (ColumnInfo) ti.getColumns().get(set2.getObject("COLUMN_NAME"));
     64                     ci2.setKeyType(ColumnInfo.PRIMARY_KEY);  //设置为主键类型
     65                     ti.getPriKeys().add(ci2);
     66                 }
     67                 
     68                 if(ti.getPriKeys().size()>0){  //取唯一主键。。方便使用。如果是联合主键。则为空!
     69                     ti.setPriKey(ti.getPriKeys().get(0));
     70                 }
     71             }
     72         } catch (SQLException e) {
     73             e.printStackTrace();
     74         }
     75         //更新类结构
     76         updateJavaPOFile();
     77         
     78         //加载po包下的所有的类
     79         loadPOTables();
     80         
     81     
     82     }
     83     /**
     84      * 根据表结构,更新配置po包下的java类
     85      */
     86     public static void updateJavaPOFile(){
     87         Map<String,TableInfo> map=tables;
     88         for(TableInfo t:map.values()){
     89             JavaFileUtil.createJavaPOFile(t, new MysqlTypeConvertor());
     90         }
     91     }
     92     /**
     93      * 加载po包下的类
     94      */
     95     public static void loadPOTables(){
     96         for(TableInfo tableInfo:tables.values()){
     97             try {
     98                 Class c = Class.forName(DBManager.getConf().getPoPackage()+
     99                         "."+StringUtil.firstChar2UpperCase(tableInfo.getTabName()));
    100                 poClassTableMap.put(c, tableInfo);
    101             } catch (ClassNotFoundException e) {
    102                 // TODO Auto-generated catch block
    103                 e.printStackTrace();
    104             }
    105         }
    106         
    107     }
    108             
    109     
    110     
    111 //    public static void main(String[] args) {
    112 //         Map<String,TableInfo>  tables = TableContext.tables;
    113 //         for(String v: tables.keySet())
    114 //         {
    115 //            System.out.println(v); 
    116 //         }
    117 //         for(TableInfo f:tables.values()){
    118 //            System.out.println(f.getPriKey().getColName()); 
    119 //         }
    120 //         System.out.println(tables);
    121 //    }
    122 
    123 }
    View Code

      TypeConvertor.java

     1 package com.frank.sorm.core;
     2 
     3 /**
     4  *    负责java类型和数据库类型的相互转换  
     5  * @author frank
     6  */
     7 
     8 public interface TypeConvertor {
     9     
    10     /**
    11      * 将数据库类型转换为java类型 
    12      * @param columnType 数据库字段类型
    13      * @return java类型
    14      */
    15     public String databaseType2JavaType(String columnType);
    16     
    17     /**
    18      * 将java类型转换为数据库类型 
    19      * @param javaType java类型
    20      * @return 数据库类型
    21      */
    22     public String javaType2DatabaseType(String  javaType);
    23 
    24 }
    View Code

    com.frank.sorm.core.imp

      MySqlQuery.java

     1 package com.frank.sorm.core.imp;
     2 
     3 import java.lang.reflect.Field;
     4 import java.sql.Connection;
     5 import java.sql.PreparedStatement;
     6 import java.sql.ResultSet;
     7 import java.sql.ResultSetMetaData;
     8 import java.sql.SQLException;
     9 import java.util.ArrayList;
    10 import java.util.List;
    11 
    12 import com.frank.sorm.bean.ColumnInfo;
    13 import com.frank.sorm.bean.TableInfo;
    14 import com.frank.sorm.core.DBManager;
    15 import com.frank.sorm.core.Query;
    16 import com.frank.sorm.core.TableContext;
    17 import com.frank.sorm.util.JDBCUtil;
    18 import com.frank.sorm.util.ReflectUtil;
    19 
    20 /**
    21  * 负责mysql数据库的操作
    22  * @author frank
    23  *
    24  */
    25 public class MySqlQuery extends Query {
    26 
    27     @Override
    28     public Object queryPagenate(int pageNum, int pageSize) {
    29         // TODO Auto-generated method stub
    30         return null;
    31     }
    32 
    33     
    34 
    35     
    36 
    37 
    38     
    39 
    40 }
    View Code

      MysqlTypeConvertor.java

     1 package com.frank.sorm.core.imp;
     2 
     3 import com.frank.sorm.core.TypeConvertor;
     4 
     5 /**
     6  * mysql数据库类型和java类型的转换
     7  * 
     8  * @author frank
     9  * 
    10  */
    11 public class MysqlTypeConvertor implements TypeConvertor {
    12 
    13     @Override
    14     public String databaseType2JavaType(String columnType) {
    15         // TODO Auto-generated method stub
    16         // varchar-->String
    17         if ("varchar".equalsIgnoreCase(columnType)
    18                 || "char".equalsIgnoreCase(columnType)) {
    19             return "String";
    20         } else if ("int".equalsIgnoreCase(columnType)
    21                 || "tinyint".equalsIgnoreCase(columnType)
    22                 || "smallint".equalsIgnoreCase(columnType)
    23                 || "integer".equalsIgnoreCase(columnType)) {
    24             return "Integer";
    25         } else if ("bigint".equalsIgnoreCase(columnType)) {
    26             return "Long";
    27         } else if ("double".equalsIgnoreCase(columnType)
    28                 || "float".equalsIgnoreCase(columnType)) {
    29             return "Double";
    30         } else if ("clob".equalsIgnoreCase(columnType)) {
    31             return "java.sql.CLob";
    32         } else if ("blob".equalsIgnoreCase(columnType)) {
    33             return "java.sql.BLob";
    34         } else if ("date".equalsIgnoreCase(columnType)) {
    35             return "java.sql.Date";
    36         } else if ("time".equalsIgnoreCase(columnType)) {
    37             return "java.sql.Time";
    38         } else if ("timestamp".equalsIgnoreCase(columnType)) {
    39             return "java.sql.Timestamp";
    40         }
    41 
    42         return null;
    43     }
    44 
    45     @Override
    46     public String javaType2DatabaseType(String javaType) {
    47         // TODO Auto-generated method stub
    48         return null;
    49     }
    50 
    51 }
    View Code

    com.frank.sorm.util

      JavaFileUtil.java

      1 package com.frank.sorm.util;
      2 
      3 import java.io.BufferedWriter;
      4 import java.io.File;
      5 import java.io.FileWriter;
      6 import java.io.IOException;
      7 import java.util.ArrayList;
      8 import java.util.List;
      9 import java.util.Map;
     10 
     11 import com.frank.sorm.bean.ColumnInfo;
     12 import com.frank.sorm.bean.JavaFieldGetSet;
     13 import com.frank.sorm.bean.TableInfo;
     14 import com.frank.sorm.core.DBManager;
     15 import com.frank.sorm.core.TypeConvertor;
     16 
     17 /**
     18  * 封装生成java源文件的常用操作
     19  * @author frank
     20  *
     21  */
     22 public class JavaFileUtil {
     23     
     24     /**
     25      *根据字段信息生成java属性信息 
     26      * @param colum 字段信息
     27      * @param convertor 类型转换器
     28      * @return java属性的set/get方法
     29      */
     30     public static JavaFieldGetSet createFieldGetSetSRC(ColumnInfo colum,TypeConvertor convertor){
     31         JavaFieldGetSet fieldSet = new JavaFieldGetSet();
     32 
     33         String javaFieldType= convertor.databaseType2JavaType(colum.getDataType());
     34 
     35         fieldSet.setFieldInfo("	private "+javaFieldType+" "+colum.getColName()+";
    ");
     36 
     37         StringBuffer getSrc=new StringBuffer();
     38         //public String getUser(){
     39         //生成get方法源码
     40         getSrc.append("	public "+javaFieldType+" get"+StringUtil.firstChar2UpperCase(colum.getColName())+"(){
    "   );
     41         getSrc.append("		return "+colum.getColName()+";
    ");
     42         getSrc.append("	}
    ");
     43         fieldSet.setGetInfo(getSrc.toString());
     44         
     45         //生成set方法源码
     46         StringBuffer setSrc= new StringBuffer();
     47         setSrc.append("	public void set"+StringUtil.firstChar2UpperCase(colum.getColName())+"("   );
     48         setSrc.append(javaFieldType+" "+colum.getColName()+"){
    ");
     49         setSrc.append("		this."+colum.getColName()+"="+colum.getColName()+";
    ");
     50         setSrc.append("	}
    ");
     51         fieldSet.setSetInfo(setSrc.toString());
     52         return fieldSet;
     53     }
     54         
     55 
     56     /**
     57      * 根据表信息生成java类源码 
     58      * @param tableInfo 表信息
     59      * @param convertor 数据类型转换器
     60      * @return java类源码
     61      */
     62     public  static String createJavaSrc(TableInfo tableInfo, TypeConvertor convertor){
     63         StringBuffer src= new StringBuffer();
     64         
     65         Map<String,ColumnInfo> columns=tableInfo.getColumns();
     66         List<JavaFieldGetSet> javaFields=new ArrayList<JavaFieldGetSet>();
     67         for(ColumnInfo c:columns.values()){
     68             javaFields.add(createFieldGetSetSRC(c,convertor));
     69         }
     70         //生成package语句
     71         src.append("package "+DBManager.getConf().getPoPackage()+";
    
    ");
     72         
     73         //生成import语句
     74         src.append("import java.sql.*;
    ");
     75         src.append("import java.util.*;
    
    ");
     76         //生成类声明语句
     77         src.append("public class "+StringUtil.firstChar2UpperCase(tableInfo.getTabName())+" {
    
    ");
     78 //        System.out.println("public class "+StringUtil.firstChar2UpperCase(tableInfo.getTabName())+" {
    
    ");
     79 
     80         
     81         //生成属性列表
     82         for(JavaFieldGetSet f:javaFields){
     83             src.append(f.getFieldInfo());
     84         }
     85         src.append("
    
    ");
     86         
     87         //生成get方法列表
     88         for(JavaFieldGetSet f:javaFields){
     89             src.append(f.getGetInfo());
     90         }
     91         
     92         //生成set方法列表
     93         for(JavaFieldGetSet f:javaFields){
     94             src.append(f.getSetInfo());
     95         }
     96         
     97         //生成类结束
     98         src.append("}
    ");
     99 //        System.out.println(src);
    100         return src.toString();
    101 
    102     }
    103     /**
    104      *根据表信息生成java文件 
    105      * @param table 表信息
    106      * @param convertor 类型转换器
    107      */
    108     public static void createJavaPOFile(TableInfo table,TypeConvertor convertor){
    109         String src=createJavaSrc(table, convertor);
    110         
    111         String srcPath=DBManager.getConf().getSrcPath()+"//";
    112         String packagePath=DBManager.getConf().getPoPackage().replaceAll("\.", "/");
    113         File f=new File(srcPath+packagePath);
    114 
    115         System.out.println(f.getAbsolutePath());
    116         
    117         if(!f.exists()){
    118             f.mkdirs();
    119         }
    120 
    121         BufferedWriter bw=null;
    122         try {
    123             bw=new BufferedWriter(new FileWriter(f.getAbsoluteFile()+"/"+StringUtil.firstChar2UpperCase(table.getTabName())+".java") );
    124             bw.write(src);
    125         } catch (IOException e) {
    126             // TODO Auto-generated catch block
    127             e.printStackTrace();
    128         }finally{
    129             if(bw!=null){
    130                 try {
    131                     bw.close();
    132                 } catch (IOException e) {
    133                     // TODO Auto-generated catch block
    134                     e.printStackTrace();
    135                 }
    136             }
    137         }
    138     }
    139 }
    View Code

      JDBCUtil.java

     1 package com.frank.sorm.util;
     2 
     3 import java.sql.PreparedStatement;
     4 import java.sql.SQLException;
     5 
     6 
     7 /**
     8  * 封装jdbc常用的操作
     9  * @author frank
    10  *
    11  */
    12 public class JDBCUtil {
    13     
    14     /**
    15      *给preparedStatement传如参数  
    16      * @param ps PreparedStatement
    17      * @param params 参数
    18      */
    19     public static void handleParams( PreparedStatement ps,Object[] params){
    20 
    21         if(params!=null){
    22             for(int i=0;i<params.length;i++){
    23                 try {
    24                     ps.setObject(i+1,params[i]);
    25                 } catch (SQLException e) {
    26                     // TODO Auto-generated catch block
    27                     e.printStackTrace();
    28                 }
    29             }
    30         }
    31     }
    32 
    33 }
    View Code

      ReflectUtil.java

     1 package com.frank.sorm.util;
     2 
     3 import java.lang.reflect.Method;
     4 
     5 /**
     6  * 封装反射的常用操作
     7  * @author frank
     8  *
     9  */
    10 public class ReflectUtil {
    11     
    12     /**
    13      * 调用obj对象对应属性的get方法
    14      * @param c
    15      * @param fieldName
    16      * @param obj
    17      * @return
    18      */
    19     public static Object invokeGet(String fieldName, Object obj){
    20         //通过反射机制,调用属性的get方法
    21                 try {
    22                     Class c=obj.getClass();
    23                     Method m=c.getDeclaredMethod("get"+StringUtil.firstChar2UpperCase(fieldName), null);
    24                      return m.invoke(obj, null);
    25                 } catch (Exception  e) {
    26                     // TODO Auto-generated catch block
    27                     e.printStackTrace();
    28                     return null;
    29                 }
    30     }
    31     
    32     /**
    33      * 调用obj对象对应属性的set方法
    34      * @param c
    35      * @param fieldName
    36      * @param obj
    37      */
    38     public static void  invokeSet( Object obj ,String fieldName,Object fieldValue){
    39         //通过反射机制,调用属性的set方法
    40                 try {
    41                     Class c=obj.getClass();
    42                     Method m=c.getDeclaredMethod("set"+StringUtil.firstChar2UpperCase(fieldName), fieldValue.getClass());
    43                     m.invoke(obj, fieldValue);
    44                 } catch (Exception  e) {
    45                     // TODO Auto-generated catch block
    46                     e.printStackTrace();
    47                 }
    48     }
    49     
    50 
    51 
    52 }
    View Code

      StringUtil.java

     1 package com.frank.sorm.util;
     2 
     3 /**
     4  * 封装String 类型的常用操作
     5  * @author frank
     6  *
     7  */
     8 public class StringUtil {
     9     
    10     /**
    11      * 将目标字符串首字母变为大写
    12      * @param str 目标字符串
    13      * @return 首字母大写的字符串
    14      */
    15     public static String firstChar2UpperCase(String str){
    16         
    17         return str.toUpperCase().substring(0,1)+str.substring(1);
    18         
    19     }
    20 
    21 }
    View Code
  • 相关阅读:
    POJ1001 Exponentiation
    centos 在安装YouCompleteMe时提示 Fatal : pyconfig.h No such file or directory
    VMware12上安装CentOS无法上网问题
    mysql报错:/usr/sbin/mysqld:unknown variable 'default-character-set=utf8'
    centos7 python3.5安装mysqlclient1.3.9
    DirectDraw创建Windows窗口
    二进制移位溢出
    格式化时间 与 时间戳的转换
    ADO 读取 ACCESS
    Windows DOS 窗口设置字体颜色
  • 原文地址:https://www.cnblogs.com/frankM/p/4590338.html
Copyright © 2011-2022 走看看