手写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("\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

 

你可能感兴趣的:(orm)