SORM框架
1 核心框架:
Query接口 负责查询(对外提供读物的核心类)
QueryFactory类 负责根据配置信息创建query对象
Typeconverto接口 负责类型转换
TableContext 类 负责获取管理数据库所有表结构和类结构的关系,并可以根据表结构生成类结构,
DBManager 类 根据配置信息,维持连接对象的管理增加连接池功能
工具类
JDBCUtil 封裝常用JDBC操作 StringUtil 封裝常用字符串操作
JavaFileUtil封裝java文件操作 ReflectUtil 封裝常用反射操作
client QueryFactory
<interface> DB2Query
query OracleQuery
mysqlQuery
TableContext
DBManager <interface> OracleTypeConvertor
TypeConvertor mysqlTypeConvertor
核心bean ,封裝相关数据
ColumnInfo 封裝表中一个字段的信息(字段类型、字段名、键类型)
Configuration 封裝配置文件信息
TableInfo 封裝一张表的信息
2、针对SORM框架的说明:
核心思想:使用简单、性能高、极易上手!
配置文件:
模卡使用资源文件、后期项目复杂后可以增加xml文件配置和注解。
类名有标明生成、只有受罪大写有区别,其他无区别
java对象的属性有表中字段生成,完全对应
目前,只支持表中只有一个主键,联合主键不支持
3.代码区


package com.bjsxt.po;
import java.sql.*;
import java.util.*;
public class Dept {
private Integer id;
private String address;
private String dname;
public Integer getId(){
return id;
}
public String getAddress(){
return address;
}
public String getDname(){
return dname;
}
public void setId(Integer id){
this.id=id;
}
public void setAddress(String address){
this.address=address;
}
public void setDname(String dname){
this.dname=dname;
}
}

package com.bjsxt.po;
import java.sql.*;
import java.util.*;
public class Emp {
private Integer id;
private java.sql.Date birthday;
private Integer deptid;
private String empname;
private Integer age;
private Double bonus;
private Double salary;
public Integer getId(){
return id;
}
public java.sql.Date getBirthday(){
return birthday;
}
public Integer getDeptid(){
return deptid;
}
public String getEmpname(){
return empname;
}
public Integer getAge(){
return age;
}
public Double getBonus(){
return bonus;
}
public Double getSalary(){
return salary;
}
public void setId(Integer id){
this.id=id;
}
public void setBirthday(java.sql.Date birthday){
this.birthday=birthday;
}
public void setDeptid(Integer deptid){
this.deptid=deptid;
}
public void setEmpname(String empname){
this.empname=empname;
}
public void setAge(Integer age){
this.age=age;
}
public void setBonus(Double bonus){
this.bonus=bonus;
}
public void setSalary(Double salary){
this.salary=salary;
}
}

package com.bjsxt.sorm.bean;
/**
* 封装表中一个字段的信息
* @author gaoiqi www.sxt.cn
* @version 0.8
*/
public class ColumnInfo {
/**
* 字段名称
*/
private String name;
/**
* 字段的数据类型
*/
private String dataType;
/**
* 字段的键类型(0:普通键,1:主键 2:外键)
*/
private int keyType;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
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;
}
public ColumnInfo(String name, String dataType, int keyType) {
super();
this.name = name;
this.dataType = dataType;
this.keyType = keyType;
}
public ColumnInfo() {
}
}

package com.bjsxt.sorm.bean;
/**
* 管理配置信息
* @author gaoqi www.sxt.cn
*
*/
public class Configuration {
/**
* 驱动类
*/
private String driver;
/**
* jdbc的url
*/
private String url;
/**
* 数据库的用户名
*/
private String user;
/**
* 数据库的密码
*/
private String pwd;
/**
* 正在使用哪个数据库
*/
private String usingDB;
/**
* 项目的源码路径
*/
private String srcPath;
/**
* 扫描生成java类的包(po的意思是:Persistence object持久化对象)
*/
private String poPackage;
private String queryClass;
private int poolMinSize;
private int poolMaxSize;
public String getQueryClass() {
return queryClass;
}
public void setQueryClass(String queryClass) {
this.queryClass = queryClass;
}
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() {
}
public Configuration(String driver, String url, String user, String pwd,
String usingDB, String srcPath, String poPackage) {
super();
this.driver = driver;
this.url = url;
this.user = user;
this.pwd = pwd;
this.usingDB = usingDB;
this.srcPath = srcPath;
this.poPackage = poPackage;
}
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 getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
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.bjsxt.sorm.bean;
/**
* 封装了java属性和get、set方法的源代码
* @author gaoqi
*
*/
public class JavaFieldGetSet {
/**
* 属性的源码信息。如:private int userId;
*/
private String fieldInfo;
/**
* get方法的源码信息.如:public int getUserId(){}
*/
private String getInfo;
/**
* set方法的源码信息.如:public void setUserId(int id){this.id = id;}
*/
private String setInfo;
@Override
public String toString() {
System.out.println(fieldInfo);
System.out.println(getInfo);
System.out.println(setInfo);
return super.toString();
}
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;
}
public JavaFieldGetSet(String fieldInfo, String getInfo, String setInfo) {
super();
this.fieldInfo = fieldInfo;
this.getInfo = getInfo;
this.setInfo = setInfo;
}
public JavaFieldGetSet() {
}
}

package com.bjsxt.sorm.bean;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 存储表结构的信息
* @author gaoqi
*
*/
public class TableInfo {
/**
* 表名
*/
private String tname;
/**
* 所有字段的信息
*/
private Map<String,ColumnInfo> columns;
/**
* 唯一主键(目前我们只能处理表中有且只有一个主键的情况)
*/
private ColumnInfo onlyPriKey;
/**
* 如果联合主键,则在这里存储
*/
private List<ColumnInfo> priKeys;
public List<ColumnInfo> getPriKeys() {
return priKeys;
}
public void setPriKeys(List<ColumnInfo> priKeys) {
this.priKeys = priKeys;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
public Map<String, ColumnInfo> getColumns() {
return columns;
}
public void setColumns(Map<String, ColumnInfo> columns) {
this.columns = columns;
}
public ColumnInfo getOnlyPriKey() {
return onlyPriKey;
}
public void setOnlyPriKey(ColumnInfo onlyPriKey) {
this.onlyPriKey = onlyPriKey;
}
public TableInfo(String tname, Map<String, ColumnInfo> columns,
ColumnInfo onlyPriKey) {
super();
this.tname = tname;
this.columns = columns;
this.onlyPriKey = onlyPriKey;
}
public TableInfo() {
}
public TableInfo(String tname,List<ColumnInfo> priKeys, Map<String, ColumnInfo> columns
) {
super();
this.tname = tname;
this.columns = columns;
this.priKeys = priKeys;
}
}

package com.bjsxt.sorm.core;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public interface CallBack
{
public abstract Object doExecute(Connection conn, PreparedStatement ps, ResultSet rs);
}

package com.bjsxt.sorm.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.bjsxt.sorm.bean.Configuration;
import com.bjsxt.sorm.pool.DBConnPool;
/**
* 根据配置信息,维持连接对象的管理(增加连接池功能)
* @author Administrator
*
*/
public class DBManager {
private static Configuration conf;
private static DBConnPool pool;
static { //静态代码块
Properties pros = new Properties();
try {
pros.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
} catch (IOException e) {
e.printStackTrace();
}
conf = new Configuration();
conf.setDriver(pros.getProperty("driver"));
conf.setPoPackage(pros.getProperty("poPackage"));
conf.setPwd(pros.getProperty("pwd"));
conf.setSrcPath(pros.getProperty("srcPath"));
conf.setUrl(pros.getProperty("url"));
conf.setUser(pros.getProperty("user"));
conf.setUsingDB(pros.getProperty("usingDB"));
conf.setQueryClass(pros.getProperty("queryClass"));
conf.setPoolMaxSize(Integer.parseInt(pros.getProperty("poolMaxSize")));
conf.setPoolMinSize(Integer.parseInt(pros.getProperty("poolMinSize")));
System.out.println(TableContext.class);
}
/*public static Connection getConn(){
try {
Class.forName(conf.getDriver());
return DriverManager.getConnection(conf.getUrl(),
conf.getUser(),conf.getPwd()); //直接建立连接,后期增加连接池处理,提高效率!!!
} catch (Exception e) {
e.printStackTrace();
return null;
}
}*/
public static Connection getConn()
{
if (pool == null) {
pool = new DBConnPool();
}
return pool.getConnection();
}
public static Connection createConn()
{
try
{
Class.forName(conf.getDriver());
return DriverManager.getConnection(conf.getUrl(),
conf.getUser(), conf.getPwd());
} catch (Exception e) {
e.printStackTrace();
}return null;
}
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);
}
public static void close(Statement ps, Connection conn)
{
try
{
if (ps != null)
ps.close();
}
catch (SQLException e) {
e.printStackTrace();
}
pool.close(conn);
}
public static void close(Connection conn)
{
pool.close(conn);
}
/**
* 返回Configuration对象
* @return
*/
public static Configuration getConf(){
return conf;
}
}

package com.bjsxt.sorm.core;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
import com.bjsxt.po.Dept;
import com.bjsxt.po.Emp;
import com.bjsxt.sorm.bean.ColumnInfo;
import com.bjsxt.sorm.bean.TableInfo;
import com.bjsxt.sorm.utils.JDBCUtils;
import com.bjsxt.sorm.utils.ReflectUtils;
import com.bjsxt.vo.EmpVO;
/**
* 负责针对Mysql数据库的查询
* @author gaoqi
*
*/
public class MySqlQuery extends Query {
public static void testDML(){
Emp e = new Emp();
e.setEmpname("lily");
e.setBirthday(new java.sql.Date(System.currentTimeMillis()));
e.setAge(30);
e.setSalary(3000.8);
e.setId(1);
// new MySqlQuery().delete(e);
// new MySqlQuery().insert(e);
new MySqlQuery().update(e,new String[]{"empname","age","salary"});
}
public static void testQueryRows(){
List<Emp> list = new MySqlQuery().queryRows("select id,empname,age from emp where age>? and salary<?",
Emp.class, new Object[]{10,5000});
for(Emp e:list){
System.out.println(e.getEmpname());
}
String sql2 = "select e.id,e.empname,salary+bonus 'xinshui',age,d.dname 'deptName',d.address 'deptAddr' from emp e "
+"join dept d on e.deptId=d.id ";
List<EmpVO> list2 = new MySqlQuery().queryRows(sql2,
EmpVO.class, null);
for(EmpVO e:list2){
System.out.println(e.getEmpname()+"-"+e.getDeptAddr()+"-"+e.getXinshui());
}
}
public static void main(String[] args) {
/* Number obj = (Number)new MySqlQuery().queryValue("select count(*) from emp where salary>?",new Object[]{1000});
Number obj = new MySqlQuery().queryNumber("select count(*) from emp where salary>?",new Object[]{1000});
System.out.println(obj.doubleValue());*/
//查询信息
List<Emp> emps=new MySqlQuery().queryRows("select * from emp", Emp.class, new Object[0]);
for (Emp emp : emps) {
System.out.println(emp.toString());
//Emp [id=1, birthday=2017-11-15, deptid=1, empname=周无极, age=12, bonus=20.0, salary=1200.0]
}
/*Number number=(Number)new MySqlQuery().queryValue("select count(*) from emp ",null);
System.out.println(number.toString());*/
//添加信息
/* Dept dept=new Dept();
dept.setAddress("南京路");
dept.setDname("采购部");
new MySqlQuery().insert(dept);*/
}
@Override
public Object queryPagenate(int pageNum, int size) {
return null;
}
}

package com.bjsxt.sorm.core;
/**
* mysql数据类型和java数据类型的转换
* @author gaoqi
*
*/
public class MySqlTypeConvertor implements TypeConvertor {
@Override
public String databaseType2JavaType(String columnType) {
//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 javaDataType) {
return null;
}
}

package com.bjsxt.sorm.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.bjsxt.sorm.bean.ColumnInfo;
import com.bjsxt.sorm.bean.TableInfo;
import com.bjsxt.sorm.utils.JDBCUtils;
import com.bjsxt.sorm.utils.ReflectUtils;
/**
* 负责查询(对外提供服务的核心类)
* @author gaoqi ww.sxt.cn
*
*/
@SuppressWarnings("all")
public abstract class Query implements Cloneable{
public Object executeQueryTemplate(String sql, Object[] params, Class clazz, CallBack back)
{
Connection conn = DBManager.getConn();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(sql);
JDBCUtils.handleParams(ps, params);
System.out.println(ps);
rs = ps.executeQuery();
return back.doExecute(conn, ps, rs);
}
catch (Exception e) {
e.printStackTrace();
return null;
} finally {
DBManager.close(ps, conn);
}
}
/**
* 直接执行一个DML语句
* @param sql sql语句
* @param params 参数
* @return 执行sql语句后影响记录的行数
*/
public int executeDML(String sql, Object[] params) {
Connection conn = DBManager.getConn();
int count = 0;
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
//给sql设参
JDBCUtils.handleParams(ps, params);
System.out.println(ps);
count = ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
DBManager.close(ps, conn);
}
return count;
}
/**
* 将一个对象存储到数据库中
* 把对象中不为null的属性往数据库中存储!如果数字为null则放0.
* @param obj 要存储的对象
*/
public void insert(Object obj) {
//obj-->表中。 insert into 表名 (id,uname,pwd) values (?,?,?)
Class c = obj.getClass();
List<Object> params = new ArrayList<Object>(); //存储sql的参数对象
TableInfo tableInfo = TableContext.poClassTableMap.get(c);
StringBuilder sql = new StringBuilder("insert into "+tableInfo.getTname()+" (");
int countNotNullField = 0; //计算不为null的属性值
Field[] fs = c.getDeclaredFields();
for(Field f:fs){
String fieldName = f.getName();
Object fieldValue = ReflectUtils.invokeGet(fieldName, obj);
if(fieldValue!=null){
countNotNullField++;
sql.append(fieldName+",");
params.add(fieldValue);
}
}
sql.setCharAt(sql.length()-1, ')');
sql.append(" values (");
for(int i=0;i<countNotNullField;i++){
sql.append("?,");
}
sql.setCharAt(sql.length()-1, ')');
executeDML(sql.toString(), params.toArray());
}
/**
* 删除clazz表示类对应的表中的记录(指定主键值id的记录)
* @param clazz 跟表对应的类的Class对象
* @param id 主键的值
*/
public void delete(Class clazz, Object id) {
//Emp.class,2-->delete from emp where id=2
//通过Class对象找TableInfo
TableInfo tableInfo = TableContext.poClassTableMap.get(clazz);
//获得主键
ColumnInfo onlyPriKey = tableInfo.getOnlyPriKey();
String sql = "delete from "+tableInfo.getTname()+" where "+onlyPriKey.getName()+"=? ";
executeDML(sql, new Object[]{id});
} /**
* 删除对象在数据库中对应的记录(对象所在的类对应到表,对象的主键的值对应到记录)
* @param obj
*/
public void delete(Object obj) {
Class c = obj.getClass();
TableInfo tableInfo = TableContext.poClassTableMap.get(c);
ColumnInfo onlyPriKey = tableInfo.getOnlyPriKey(); //主键
//通过反射机制,调用属性对应的get方法或set方法
Object priKeyValue = ReflectUtils.invokeGet(onlyPriKey.getName(), obj);
delete(c, priKeyValue);
}
/**
* 更新对象对应的记录,并且只更新指定的字段的值
* @param obj 所要更新的对象
* @param fieldNames 更新的属性列表
* @return 执行sql语句后影响记录的行数
*/
public int update(Object obj, String[] fieldNames) {
//obj{"uanme","pwd"}-->update 表名 set uname=?,pwd=? where id=?
Class c = obj.getClass();
List<Object> params = new ArrayList<Object>(); //存储sql的参数对象
//从加载数据库表信息放在map集合里,根据tablebame.class取表信息
TableInfo tableInfo = TableContext.poClassTableMap.get(c);
ColumnInfo priKey = tableInfo.getOnlyPriKey();
//获得唯一的主键
StringBuilder sql = new StringBuilder("update "+tableInfo.getTname()+" set ");
for(String fname:fieldNames){
Object fvalue = ReflectUtils.invokeGet(fname,obj);
params.add(fvalue);
sql.append(fname+"=?,");
}
sql.setCharAt(sql.length()-1, ' ');
sql.append(" where ");
sql.append(priKey.getName()+"=? ");
params.add(ReflectUtils.invokeGet(priKey.getName(), obj)); //主键的值
return executeDML(sql.toString(), params.toArray());
}
/**
* 查询返回多行记录,并将每行记录封装到clazz指定的类的对象中
* @param sql 查询语句
* @param clazz 封装数据的javabean类的Class对象
* @param params sql的参数
* @return 查询到的结果
*/
public List queryRows(final String sql,final Class clazz,final Object[] params){
return (List)executeQueryTemplate(sql, params, clazz, new CallBack(){
@Override
public Object doExecute(Connection conn,PreparedStatement ps,ResultSet rs) {
List list=null;
try{
ResultSetMetaData metaData = rs.getMetaData();
while (rs.next()) {
if (list==null) {
list=new ArrayList();
}
Object rowObj = clazz.newInstance();
for (int i = 0; i < metaData.getColumnCount(); i++) {
String columnName = metaData.getColumnLabel(i + 1);
Object columnValue = rs.getObject(i + 1);
ReflectUtils.invokeSet(rowObj, columnName, columnValue);
}
list.add(rowObj);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
});
}
/**
* 查询返回一行记录,并将该记录封装到clazz指定的类的对象中
* @param sql 查询语句
* @param clazz 封装数据的javabean类的Class对象
* @param params sql的参数
* @return 查询到的结果
*/
public Object queryUniqueRow(String sql, Class clazz, Object[] params) {
List list = queryRows(sql, clazz, params);
return (list==null&&list.size()>0)?null:list.get(0);
}
/**
* 查询返回一个值(一行一列),并将该值返回
* @param sql 查询语句
* @param params sql的参数
* @return 查询到的结果
*/
public Object queryValue(String sql, Object[] params)
{
return executeQueryTemplate(sql, params, null, new CallBack()
{
@Override
public Object doExecute(Connection conn, PreparedStatement ps, ResultSet rs) {
Object value = null;
try {
while (rs.next())
value = rs.getObject(1);
}
catch (SQLException e) {
e.printStackTrace();
}
return value;
}
});
}
/**
* 查询返回一个数字(一行一列),并将该值返回
* @param sql 查询语句
* @param params sql的参数
* @return 查询到的数字
*/
public Number queryNumber(String sql, Object[] params) {
return (Number)queryValue(sql, params);
}
/**
* 分页查询
*/
public abstract Object queryPagenate(int pageNum,int size);
protected Object clone()
throws CloneNotSupportedException
{
return super.clone();
}
}

package com.bjsxt.sorm.core;
import com.bjsxt.sorm.bean.Configuration;
public class QueryFactory
{
private static Query prototypeObj;
static
{
try
{
Class c = Class.forName(DBManager.getConf().getQueryClass());
prototypeObj = (Query)c.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
TableContext.loadPOTables();
}
public static Query createQuery()
{
try
{
return (Query)prototypeObj.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}return null;
}
}

package com.bjsxt.sorm.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.Iterator;
import java.util.Map;
import com.bjsxt.sorm.bean.ColumnInfo;
import com.bjsxt.sorm.bean.TableInfo;
import com.bjsxt.sorm.utils.JavaFileUtils;
import com.bjsxt.sorm.utils.StringUtils;
/**
* 负责获取管理数据库所有表结构和类结构的关系,并可以根据表结构生成类结构。
* @author gaoqi www.sxt.cn
*
*/
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.getConn();
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 ArrayList<ColumnInfo>()
,new HashMap<String, 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(1); //设置为主键类型
ti.getPriKeys().add(ci2);
}
if(ti.getPriKeys().size()>0){ //取唯一主键。。方便使用。如果是联合主键。则为空!
ti.setOnlyPriKey(ti.getPriKeys().get(0));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
//更新类结构
updateJavaPOFile();
//加载po包下面所有的类,便于重用,提高效率!
loadPOTables();
}
/**
* 根据表结构,更新配置的po包下面的java类
* 实现了从表结构转化到类结构
*/
public static void updateJavaPOFile(){
Map<String,TableInfo> map = TableContext.tables;
for(TableInfo t:map.values()){
JavaFileUtils.createJavaPOFile(t,new MySqlTypeConvertor());
}
}
/**
* 加载po包下面的类,向poClassTableMap集合放入tableInfo
*/
public static void loadPOTables(){
for(TableInfo tableInfo:tables.values()){
try {
Class c = Class.forName(DBManager.getConf().getPoPackage()
+"."+StringUtils.firstChar2UpperCase(tableInfo.getTname()));
poClassTableMap.put(c, tableInfo);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
/**
* 循环遍历集合
* @param args
*/
public static void main(String[] args) {
Map<String,TableInfo> tables = TableContext.tables;
Iterator iterator=tables.values().iterator();
while (iterator.hasNext()) {
TableInfo object = (TableInfo) iterator.next();
System.out.println(object);
}
}
}

package com.bjsxt.sorm.core;
/**
* 负责java数据类型和数据库数据类型的互相转换
* @author gaoqi www.sxt.cn
*
*/
public interface TypeConvertor {
/**
* 将数据库数据类型转化成java的数据类型
* @param columnType 数据库字段的数据类型
* @return java的数据类型
*/
public String databaseType2JavaType(String columnType);
/**
* 将java数据类型转化成数据库数据类型
* @param javaDataType java数据类型
* @return 数据库类型
*/
public String javaType2DatabaseType(String javaDataType);
}

package com.bjsxt.sorm.pool;
import com.bjsxt.sorm.bean.Configuration;
import com.bjsxt.sorm.core.DBManager;
import java.io.PrintStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
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 void initPool()
{
if (this.pool == null) {
this.pool = new ArrayList();
}
while (this.pool.size() < POOL_MIN_SIZE) {
this.pool.add(DBManager.createConn());
System.out.println("初始化池,池中连接数:" + this.pool.size());
}
}
public synchronized Connection getConnection()
{
int last_index = this.pool.size() - 1;
Connection conn = (Connection)this.pool.get(last_index);
this.pool.remove(last_index);
return conn;
}
public synchronized void close(Connection conn)
{
if (this.pool.size() >= POOL_MAX_SIZE)
try {
if (conn == null) return; conn.close();
}
catch (SQLException e) {
e.printStackTrace();
}
else
this.pool.add(conn);
}
public DBConnPool()
{
initPool();
}
}

package com.bjsxt.sorm.utils;
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.bjsxt.sorm.bean.ColumnInfo;
import com.bjsxt.sorm.bean.JavaFieldGetSet;
import com.bjsxt.sorm.bean.TableInfo;
import com.bjsxt.sorm.core.DBManager;
import com.bjsxt.sorm.core.MySqlTypeConvertor;
import com.bjsxt.sorm.core.TableContext;
import com.bjsxt.sorm.core.TypeConvertor;
/**
* 封装了生成Java文件(源代码)常用的操作
* @author www.sxt.cn
*
*/
public class JavaFileUtils {
/**
* 根据字段信息生成java属性信息。如:varchar username-->private String username;以及相应的set和get方法源码
* @param column 字段信息
* @param convertor 类型转化器
* @return java属性和set/get方法源码
*/
public static JavaFieldGetSet createFieldGetSetSRC(ColumnInfo column,TypeConvertor convertor){
JavaFieldGetSet jfgs = new JavaFieldGetSet();
String javaFieldType = convertor.databaseType2JavaType(column.getDataType());
jfgs.setFieldInfo("\tprivate "+javaFieldType+" "+column.getName()+";\n");
//public String getUsername(){return username;}
//生成get方法的源代码
StringBuilder getSrc = new StringBuilder();
getSrc.append("\tpublic "+javaFieldType+" get"+StringUtils.firstChar2UpperCase(column.getName())+"(){\n");
getSrc.append("\t\treturn "+column.getName()+";\n");
getSrc.append("\t}\n");
jfgs.setGetInfo(getSrc.toString());
//public void setUsername(String username){this.username=username;}
//生成set方法的源代码
StringBuilder setSrc = new StringBuilder();
setSrc.append("\tpublic void set"+StringUtils.firstChar2UpperCase(column.getName())+"(");
setSrc.append(javaFieldType+" "+column.getName()+"){\n");
setSrc.append("\t\tthis."+column.getName()+"="+column.getName()+";\n");
setSrc.append("\t}\n");
jfgs.setSetInfo(setSrc.toString());
return jfgs;
}
/**
* 根据表信息生成java类的源代码
* @param tableInfo 表信息
* @param convertor 数据类型转化器
* @return java类的源代码
*/
public static String createJavaSrc(TableInfo tableInfo,TypeConvertor convertor){
Map<String,ColumnInfo> columns = tableInfo.getColumns();
List<JavaFieldGetSet> javaFields = new ArrayList<JavaFieldGetSet>();
for(ColumnInfo c:columns.values()){
javaFields.add(createFieldGetSetSRC(c,convertor));
}
StringBuilder src = new StringBuilder();
//生成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 "+StringUtils.firstChar2UpperCase(tableInfo.getTname())+" {\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");
return src.toString();
}
public static void createJavaPOFile(TableInfo tableInfo,TypeConvertor convertor){
String src = createJavaSrc(tableInfo,convertor);
String srcPath = DBManager.getConf().getSrcPath()+"\\";
//替换
String packagePath = DBManager.getConf().getPoPackage().replaceAll("\\.", "/");
File f = new File(srcPath+packagePath);
if(!f.exists()){ //如果指定目录不存在,则帮助用户建立
f.mkdirs();
}
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(f.getAbsoluteFile()+"/"+StringUtils.firstChar2UpperCase(tableInfo.getTname())+".java"));
bw.write(src);
System.out.println("建立表"+tableInfo.getTname()+
"对应的java类:"+StringUtils.firstChar2UpperCase(tableInfo.getTname())+".java");
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(bw!=null){
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// ColumnInfo ci = new ColumnInfo("id", "int", 0);
// JavaFieldGetSet f = createFieldGetSetSRC(ci,new MySqlTypeConvertor());
// System.out.println(f);
Map<String,TableInfo> map = TableContext.tables;
for(TableInfo t:map.values()){
createJavaPOFile(t,new MySqlTypeConvertor());
}
}
}

package com.bjsxt.sorm.utils;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* 封装了JDBC查询常用的操作
* @author gaoqi www.sxt.cn
*
*/
public class JDBCUtils {
/**
* //给sql设参
* @param ps 预编译sql语句对象
* @param params 参数
*/
public static void handleParams(PreparedStatement ps,Object[] params){
if(params!=null){
for(int i=0;i<params.length;i++){
try {
ps.setObject(1+i, params[i]);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}

package com.bjsxt.sorm.utils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 封装了反射常用的操作
*
*
*/
public class ReflectUtils {
/**
* 调用obj对象对应属性fieldName的get方法
* @param fieldName
* @param obj
* @return
*/
public static Object invokeGet(String fieldName,Object obj){
try {
Class c = obj.getClass();
Method m = c.getDeclaredMethod("get"+StringUtils.firstChar2UpperCase(fieldName), null);
return m.invoke(obj, null);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void invokeSet(Object obj,String columnName,Object columnValue){
try {
Method m = obj.getClass().getDeclaredMethod("set"+StringUtils.firstChar2UpperCase(columnName),
columnValue.getClass());
m.invoke(obj, columnValue);
} catch (Exception e) {
e.printStackTrace();
}
}
}

package com.bjsxt.sorm.utils;
/**
* 封装了字符串常用的操作
* @author gaoqi www.sxt.cn
*
*/
public class StringUtils {
/**
* 将目标字符串首字母变为大写
* @param str 目标字符串
* @return 首字母变为大写的字符串
*/
public static String firstChar2UpperCase(String str){
//abcd-->Abcd
//abcd-->ABCD-->Abcd
return str.toUpperCase().substring(0, 1)+str.substring(1);
}
}

package com.bjsxt.vo;
public class EmpVO {
private Integer id;
private String empname;
private Double xinshui;
private Integer age;
private String deptName;
private String deptAddr;
public EmpVO(Integer id, String empname, Double xinshui, Integer age,
String deptName, String deptAddr) {
super();
this.id = id;
this.empname = empname;
this.xinshui = xinshui;
this.age = age;
this.deptName = deptName;
this.deptAddr = deptAddr;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getEmpname() {
return empname;
}
public void setEmpname(String empname) {
this.empname = empname;
}
public Double getXinshui() {
return xinshui;
}
public void setXinshui(Double xinshui) {
this.xinshui = xinshui;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public String getDeptAddr() {
return deptAddr;
}
public void setDeptAddr(String deptAddr) {
this.deptAddr = deptAddr;
}
public EmpVO() {
}
}

package com.test;
import java.util.List;
import com.bjsxt.po.Emp;
import com.bjsxt.sorm.core.QueryFactory;
public class Test {
public static void test01() {
List<Emp> emps = QueryFactory.createQuery().queryRows("select * from emp", Emp.class, null);
for (Emp emp : emps) {
System.out.println(emp.toString());
}
}
public static void main(String[] args) {
Long begin=System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
test01();
}
Long end=System.currentTimeMillis();
System.out.println(end-begin);//1262
}
}

driver=com.mysql.jdbc.Driver url=jdbc\:mysql\://localhost\:3306/TB47 user=root pwd=123456 usingDB=mysql srcPath=D\:\\workspace\\sormtest\\src #生成的实体类放的路径 poPackage=com.bjsxt.po #配置的是mysqlquery queryClass=com.bjsxt.sorm.core.MySqlQuery poolMinSize=10 poolMaxSize=100
来源:https://www.cnblogs.com/ou-pc/p/7223855.html
