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