zoukankan      html  css  js  c++  java
  • java框架--Model层框架 sorm

                                   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;
        }
    }
    Dept
    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;
        }
    }
    Emp
    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() {
        }
    }
    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;
        } 
        
        
        
    
    }
    Configuration 管理配置信息
    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() {
        }
    }
    JavaFieldGetSet 封装了java属性和get、set方法的源代码
    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;
        }
    
        
    }
    TableInfo  存储表结构的信息
    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);
    }
    CallBack
    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;
        }
        
        
    }
    DBManager 根据配置信息,维持连接对象的管理(增加连接池功能)
    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;
        }
    
    
    }
    MySqlQuery  负责针对Mysql数据库的查询
    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;
        }
    
    }
    MySqlTypeConvertor mysql数据类型和java数据类型的转换
    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();
         }
    
    
    }
    Query  负责查询(对外提供服务的核心类)
    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;
      }
    }
    QueryFactory
    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);
                
            }
        }
    
    }
    TableContext 负责获取管理数据库所有表结构和类结构的关系
    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);
        
    }
    TypeConvertor 负责java数据类型和数据库数据类型的互相转换
    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();
      }
    }
    DBConnPool 数据源连接池
    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("	private "+javaFieldType+" "+column.getName()+";
    ");
            
            //public String getUsername(){return username;}
            //生成get方法的源代码
            StringBuilder getSrc = new StringBuilder();
            getSrc.append("	public "+javaFieldType+" get"+StringUtils.firstChar2UpperCase(column.getName())+"(){
    ");
            getSrc.append("		return "+column.getName()+";
    ");
            getSrc.append("	}
    ");
            jfgs.setGetInfo(getSrc.toString());
            
            //public void setUsername(String username){this.username=username;}
            //生成set方法的源代码
            StringBuilder setSrc = new StringBuilder();
            setSrc.append("	public void set"+StringUtils.firstChar2UpperCase(column.getName())+"(");
            setSrc.append(javaFieldType+" "+column.getName()+"){
    ");
            setSrc.append("		this."+column.getName()+"="+column.getName()+";
    ");
            setSrc.append("	}
    ");
            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()+";
    
    ");
            //生成import语句
            src.append("import java.sql.*;
    ");
            src.append("import java.util.*;
    
    ");
            //生成类声明语句
            src.append("public class "+StringUtils.firstChar2UpperCase(tableInfo.getTname())+" {
    
    ");
            
            //生成属性列表
            for(JavaFieldGetSet f:javaFields){
                src.append(f.getFieldInfo());
            }
            src.append("
    
    ");
            //生成get方法列表
            for(JavaFieldGetSet f:javaFields){
                src.append(f.getGetInfo());
            }
            //生成set方法列表
            for(JavaFieldGetSet f:javaFields){
                src.append(f.getSetInfo());
            }
            
            //生成类结束
            src.append("}
    ");
            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());
            }
        }
        
    }
    JavaFileUtils 封装了生成Java文件(源代码)常用的操作
    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();
                    }
                }
            }
        }
    }
    JDBCUtils 封装了JDBC查询常用的操作
    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();
            } 
    
        }
        
        
        
        
    }
    ReflectUtils 封装了反射常用的操作
    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);
        }
        
    }
    StringUtils 封装了字符串常用的操作
    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() {
        }
        
    }
    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
        }
    }
    Test
    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
    db.properties
  • 相关阅读:
    栈和队列的存储结构、线性结构和非线性结构
    java 将一个有大量数据的list集合分成指定大小的list集合
    Java和jdbc实现数据库操作的基础例子
    解决连接Oracle 11g报ORA-01034和ORA-27101的错误和报ORA-00119和ORA-00132这个问题
    Java语言类的特性
    Java类与对象
    Java中的字符串(String)
    Java数组
    Java中的流程控制
    Java中的运算符与表达式
  • 原文地址:https://www.cnblogs.com/ou-pc/p/7223855.html
Copyright © 2011-2022 走看看