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

配置文件 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("\tprivate "+javaFieldType+" "+colum.getColName()+";\n");
 36 
 37         StringBuffer getSrc=new StringBuffer();
 38         //public String getUser(){
 39         //生成get方法源码
 40         getSrc.append("\tpublic "+javaFieldType+" get"+StringUtil.firstChar2UpperCase(colum.getColName())+"(){\n"   );
 41         getSrc.append("\t\treturn "+colum.getColName()+";\n");
 42         getSrc.append("\t}\n");
 43         fieldSet.setGetInfo(getSrc.toString());
 44         
 45         //生成set方法源码
 46         StringBuffer setSrc= new StringBuffer();
 47         setSrc.append("\tpublic void set"+StringUtil.firstChar2UpperCase(colum.getColName())+"("   );
 48         setSrc.append(javaFieldType+" "+colum.getColName()+"){\n");
 49         setSrc.append("\t\tthis."+colum.getColName()+"="+colum.getColName()+";\n");
 50         setSrc.append("\t}\n");
 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()+";\n\n");
 72         
 73         //生成import语句
 74         src.append("import java.sql.*;\n");
 75         src.append("import java.util.*;\n\n");
 76         //生成类声明语句
 77         src.append("public class "+StringUtil.firstChar2UpperCase(tableInfo.getTabName())+" {\n\n");
 78 //        System.out.println("public class "+StringUtil.firstChar2UpperCase(tableInfo.getTabName())+" {\n\n");
 79 
 80         
 81         //生成属性列表
 82         for(JavaFieldGetSet f:javaFields){
 83             src.append(f.getFieldInfo());
 84         }
 85         src.append("\n\n");
 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("}\n");
 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