根据尚学堂录的教程做的。:
配置文件 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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }