jbase引入连接池

网站主题和代码生成器完事之后,ORM成为主要工作,之前只是搭了ORM的大体结构,没有详细优化和实现。这次引入连接池、把连接串信息从配置取、调整抛出异常。

连接池包选择c3p0,因为他稳定,用的多,下载引入c3p0包
jbase引入连接池_第1张图片

调整IDbFactory接口

package LIS.DAL.ORM.DBUtility;

import java.sql.Connection;

/**
 * 数据驱动层接口,ORM基于此加载驱动和执行SQL,不同数据库实现该接口配置到容器即可
 */
public interface IDbFactory {
    /**
     * 得到数据库类型
     * @return
     */
    String GetStrDbType();

    /**
     * 得到数据库连接串
     * @return
     */
    String GetConnectionString() throws Exception;

    /**
     * 得到数据库用户名
     * @return
     */
    String GetUserName() throws Exception;

    /**
     * 得到数据库密码
     * @return
     */
    String GetUserPass() throws Exception;

    /**
     * 得到返回查询的RowID的SQL语句
     * @return
     */
    String GetReturnRowIDSql();

    /**
     * 处理表名称,用来适配不同数据库间的属性命名差异
     * @param tableName
     * @return
     */
    String DealTableName(String tableName);

    /**
     * 处理属性名字
     * @param propertyName
     * @return
     */
    String DealPropertyName(String propertyName);

    /**
     * DealSqlPara
     * @param propertyName
     * @return
     */
    String DealSqlPara(String propertyName);

    /**
     * 加载驱动
     * @return
     */
    String GetDriver();

    /**
     * 得到初始化连接串大小
     * @return
     */
    int GetInitPoolSize() throws Exception;

    /**
     * 得到最大连接串大小
     * @return
     */
    int GetMaxPoolSize() throws Exception;
}

实现连接串工具类
jbase引入连接池_第2张图片

package LIS.DAL.ORM.DBUtility;
import com.mchange.v2.c3p0.ComboPooledDataSource;

import java.sql.Connection;
import java.util.Properties;

import LIS.DAL.ORM.DBUtility.IDbFactory;

/**
 * 连接池工具类
 */
public class C3P0Util {

    /**
     * 初始化连接池
     * @param factory 数据库驱动接口
     */
    public static ComboPooledDataSource GetConnPool(IDbFactory factory) throws Exception
    {
        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
        //给数据源 comboPooledDataSource 设置相关的参数
        //注意:连接管理是由 comboPooledDataSource 来管理
        comboPooledDataSource.setDriverClass(factory.GetDriver());
        comboPooledDataSource.setJdbcUrl(factory.GetConnectionString());
        comboPooledDataSource.setUser(factory.GetUserName());
        comboPooledDataSource.setPassword(factory.GetUserPass());

        //设置初始化连接数
        comboPooledDataSource.setInitialPoolSize(factory.GetInitPoolSize());

        //最大连接数
        comboPooledDataSource.setMaxPoolSize(factory.GetMaxPoolSize());
        return comboPooledDataSource;
    }

    /**
     * 得到数据库连接对象
     * @return
     * @throws Exception
     */
    public static Connection GetConnection(ComboPooledDataSource comboPooledDataSource) throws Exception
    {
        //这个方法就是从 DataSource 接口实现的
        Connection connection = comboPooledDataSource.getConnection();
        return connection;
    }

}

调整DBManager

package LIS.DAL.ORM.DBUtility;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import LIS.DAL.ORM.DBUtility.C3P0Util;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import LIS.DAL.ORM.DBUtility.IDbFactory;

/**
 * 连接和事务管理
 */
public class DBManager {
    /**
     * 驱动名称
     */
    private String factoryName="";

    /**
     * 当前对象的驱动
     */
    private IDbFactory factory=null;


    /**
     * 存数据库连接对象
     */
    private Connection connection=null;

    /**
     * 为每个数据库驱动存储工厂
     */
    private static ConcurrentHashMap<String, IDbFactory> hsFact = new ConcurrentHashMap<>();

    /**
     * 为每个数据库驱动存储连接池
     */
    private static ConcurrentHashMap<String, ComboPooledDataSource> hsPoll = new ConcurrentHashMap<>();

    /**
     * 得到驱动对象
     * @param factoryName
     * @return
     */
    public IDbFactory GetIDbFactory(String factoryName)
    {
        if(factory==null)
        {
            factory=hsFact.get(factoryName);
        }
        return factory;
    }


    /**
     * 尝试初始化连接池
     * @param factoryName
     */
    public static void TryInitConnPool(String factoryName) throws Exception
    {
        if(factoryName=="")
        {
            factoryName="LisMianDbFactory";
        }
        if(!hsPoll.containsKey(factoryName))
        {
            IDbFactory factory=LIS.Core.Context.ObjectContainer.GetTypeObject(factoryName);
            hsPoll.put(factoryName,C3P0Util.GetConnPool(factory));
            if(!hsFact.containsKey(factoryName))
            {
                hsFact.put(factoryName,factory);
            }
        }
    }

    /**
     * 构造函数
     * @param factName 驱动配置名称
     * @throws Exception
     */
    public DBManager(String factName) throws Exception
    {
        factoryName=factName;
        TryInitConnPool(factoryName);
    }

    /**
     * 存数据库连接对象
     */
    public Connection Connection() throws Exception
    {
        if(connection==null)
        {
            connection=hsPoll.get(factoryName).getConnection();
        }
        return connection;
    }

    /**
     * 标识是否开启事务
     */
    public boolean Hastransaction = false;

    /**
     * 存储开启多次事务的保存点,每次调用BeginTransaction开启事务是自动创建保存点
     */
    public LinkedList<Savepoint> Transpoints = new LinkedList<Savepoint>();

    /**
     * 获取开启的事务层级
     * @return
     */
    public int GetTransactionLevel()
    {
        return this.Transpoints.size();
    }

    /**
     * 释放数据库连接
     * @return true成功释放,false释放失败
     */
    public boolean Close() throws Exception
    {
        connection.close();
        connection=null;
        return true;
    }


    /**
     * 此方法开启事务
     * @return  true开启事务成功,false开始事务失败
     */
    public boolean BeginTransaction() throws Exception
    {
        try
        {
            this.Connection().setAutoCommit(false);
            this.Hastransaction = true;
            Savepoint savepoint = this.Connection().setSavepoint();
            Transpoints.addLast(savepoint);
            return true;
        }

        catch (SQLException sqle)
        {
            LIS.Core.Util.LogUtils.WriteExceptionLog("开启事务失败!" + sqle.getMessage(), sqle);
        }
        return false;
    }

    /**
     * 回滚上一层事务
     * @return true回滚事务成功,false回滚事务失败
     */
    public boolean RollTransaction() throws Exception
    {
        //未开启事务时,算回滚事务成功
        if (!this.Hastransaction)
        {
            return true;
        }
        try
        {
            if (this.Transpoints.size() == 0)
            {
                this.Connection().rollback();
                this.Hastransaction = false;
            }
            else
            {
                Savepoint point = this.Transpoints.poll();
                this.Connection().rollback(point);
            }
            return true;
        }
        catch (SQLException sqle)
        {
            LIS.Core.Util.LogUtils.WriteExceptionLog("事务回滚失败!" + sqle.getMessage(),sqle);
            throw sqle;
        }
        finally
        {
            if (!this.Hastransaction)
            {
                Close();
            }
        }
    }

    /**
     * 回滚开启的全部事务
     * @return true回滚事务成功,false回滚事务失败
     */
    public boolean RollTransactionAll() throws Exception
    {
        //未开启事务时,算回滚事务成功
        if (!this.Hastransaction)
        {
            return true;
        }
        try
        {
            this.Connection().rollback();
            this.Hastransaction = false;
            return true;
        }
        catch (SQLException sqle)
        {
            LIS.Core.Util.LogUtils.WriteExceptionLog("回滚所有事务层级失败!" + sqle.getMessage(),sqle);
            throw sqle;
        }
        finally
        {
            Close();
        }
    }

    /**
     * 提交事务
     * @return true提交事务成功,false提交事务失败
     */
    public boolean CommitTransaction() throws Exception
    {
        try
        {
            this.Connection().commit();
            this.Hastransaction = false;
            return true;
        }
        catch (SQLException sqle)
        {
            LIS.Core.Util.LogUtils.WriteExceptionLog("提交事务失败!" + sqle.getMessage(),sqle);
        }
        finally
        {
            //提交事务,不论成功与否,释放数据库连接
            try
            {
                Close();
            }
            catch (Exception ex)
            {

            }
        }
        return false;
    }

}

常用api实现

package LIS.DAL.ORM.EntityManager;

import java.lang.reflect.Type;
import java.sql.*;
import java.util.List;
import java.util.*;

import LIS.Core.CustomAttributes.FrekeyAttribute;
import LIS.Core.Dto.*;
import LIS.Model.Bussiness.Sessions;
import LIS.DAL.ORM.DBUtility.JsonHelper;
import LIS.DAL.ORM.DBUtility.DBManager;
import LIS.DAL.ORM.Common.TableInfo;
import LIS.DAL.ORM.DBUtility.DBParaUtil;

public class EntityManagerImpl implements LIS.DAL.ORM.EntityManager.IEntityManager {
    /**
     * 数据库连接容器驱动名称
     */
    private String factoryName = "LisMianDbFactory";

    /// 
    /// 存会话信息
    /// 
    LIS.Model.Bussiness.Sessions Session = null;

    /**
     * 管理数据库连接
     */
    private DBManager manager = null;

    /**
     * 无参构造函数
     */
    public EntityManagerImpl() {
    }

    /**
     * 类对象代码块实现对数据库连接的初始化,操作数据库的增删改查及事务都使用对象完成
     *
     * @param dbFactoryKey 配置名称
     */
    public EntityManagerImpl(String dbFactoryKey) {
        factoryName = dbFactoryKey;
    }

    /**
     * 安装会话和数据库驱动配置对象主键初始化数据管理器
     *
     * @param session      会话对象
     * @param dbFactoryKey 配置名称
     */
    public EntityManagerImpl(Sessions session, String dbFactoryKey) {
        Session = session;
        factoryName = dbFactoryKey;
    }

    /**
     * 控制事务
     */
    public DBManager Transaction = null;

    /**
     * 开启事务,该方法初始化一个新的事务
     */
    public void BeginTransaction() throws Exception {
        Manager().BeginTransaction();
    }

    /**
     * 得到管理器
     *
     * @return
     */
    public DBManager Manager() throws Exception {
        if (manager == null) {
            manager = new DBManager(factoryName);
            //供事务操作的对象
            Transaction = manager;
        }
        return manager;
    }


    /**
     * 保存对象
     *
     * @param entity 实体对象
     * @param     实体类型约束
     * @throws SQLException 执行抛出SQL异常
     * @return影响行数
     */
    @Override
    public <T> int Save(T entity) throws Exception {
        PreparedStatement stmt = null;
        try {
            //根据实体对象获取表信息
            TableInfo tableInfo = LIS.DAL.ORM.Common.ModelToSqlUtil.GetTypeInfo(entity);
            //带出参数的对象
            HashParam hash = new HashParam();
            //获取插入SQL语句
            String sql = LIS.DAL.ORM.Common.ModelToSqlUtil.GetInsertSqlByTableInfo(Manager().GetIDbFactory(factoryName), tableInfo, hash, false);
            //写SQL日志
            LIS.Core.Util.LogUtils.WriteSqlLog("执行插入SQL:" + sql);
            //声明式SQL,并设置参数
            stmt = Manager().Connection().prepareStatement(sql);
            String paraSql = DBParaUtil.SetDBPara(stmt, hash.GetParam());
            int row = stmt.executeUpdate();
            LIS.Core.Util.LogUtils.WriteSqlLog("参数:" + paraSql);
            return row;
        } catch (Exception ex) {
            //操作异常,判断如果开启事务,则回滚事务
            if (Manager().Hastransaction) {
                if (!Manager().RollTransaction()) {
                    throw new SQLException("保存数据失败!" + ex.getMessage() + ";回滚事务失败。");
                }
            }
            throw new SQLException("保存数据失败!" + ex.getMessage());
        }
        //操作结束释放资源
        finally {
            if (stmt != null) {
                stmt.close();
            }
            //如果上层调用未开启事务,则调用结束释放数据库连接
            if (!Manager().Hastransaction) {
                manager.Close();
            }
        }
    }

    /**
     * 保存对象
     *
     * @param entity   实体对象
     * @param outParam 输出执行成功或失败信息
     * @param       实体类型约束
     * @return影响行数
     */
    @Override
    public <T> int Save(T entity, OutParam outParam) throws Exception {
        int row = 0;
        PreparedStatement stmt = null;
        boolean innerT = false;     //标识是否内部开启事务
        String sql = "";
        try {
            //根据实体对象获取表信息
            LIS.DAL.ORM.Common.TableInfo tableInfo = LIS.DAL.ORM.Common.ModelToSqlUtil.GetTypeInfo(entity);
            HashParam hash = new HashParam();
            //获取插入SQL语句
            sql = LIS.DAL.ORM.Common.ModelToSqlUtil.GetInsertSqlByTableInfo(Manager().GetIDbFactory(factoryName), tableInfo, hash, false);
            //写SQL日志
            LIS.Core.Util.LogUtils.WriteSqlLog("执行插入SQL:" + sql + ";SQL参数:" + LIS.Core.Util.JsonUtil.Object2Json(hash.GetParam()));
            //声明式SQL,并设置参数
            stmt = Manager().Connection().prepareStatement(sql);
            String paraSql = DBParaUtil.SetDBPara(stmt, hash.GetParam());
            row = stmt.executeUpdate();
            ResultSet rowID = stmt.getGeneratedKeys();
            LIS.Core.Util.LogUtils.WriteSqlLog("参数:" + paraSql);
            //保存成功返回记录主键,返回影响记录数 1
            if (row == 1) {
                outParam.Message = rowID;
            } else {
                outParam.Code = OutStatus.ERROR;
                outParam.Message = "保存数据失败,执行保存返回:" + row;
            }
            return row;
        } catch (Exception ex) {
            outParam.Code = OutStatus.ERROR;
            //操作异常,判断如果开启事务,则回滚事务
            if (Manager().Hastransaction) {
                if (!Manager().RollTransaction()) {
                    outParam.Message = "保存数据失败!" + ex.getMessage() + ";回滚事务失败。";
                }
            }
            outParam.Message = "保存数据失败!" + ex.getMessage() + "执行SQL:" + sql;
        }
        //操作结束释放资源
        finally {
            if (stmt != null) {
                stmt.close();
            }
            //如果上层调用未开启事务,则调用结束释放数据库连接
            if (!Manager().Hastransaction) {
                Manager().Close();
            }
        }
        return row;
    }

    /**
     * 更新实体对象
     *
     * @param entity        实体对象
     * @param param         更新条件,有条件就按条件更新,没有条件就按主键更新
     * @param outParam      输出执行成功或失败的信息
     * @param updateColName 更新属性名集合,无属性则更新实体的所有属性
     * @param joiner        连接符,为空或不给则按则按且连接,给的话长度应该比参数长度少1,如: and
     * @param operators     操作符,为空或不给的话各条件按等来比较,给的话长度应该跟参数长度一样,如: !=
     * @param            类型限定符
     * @return 影响行数
     */
    @Override
    public <T> int Update(T entity, HashParam param, OutParam outParam, List<String> updateColName, List<String> joiner, List<String> operators) throws Exception {
        PreparedStatement stmt = null;
        if (outParam == null) outParam = new OutParam();
        int row = 0;
        boolean innerT = false;     //标识是否内部开启事务
        try {
            //根据实体获取表信息
            LIS.DAL.ORM.Common.TableInfo tableInfo = LIS.DAL.ORM.Common.ModelToSqlUtil.GetTypeInfo(entity);
            HashParam hash = new HashParam();
            //获取更新的SQL语句
            String sql = LIS.DAL.ORM.Common.ModelToSqlUtil.GetUpdateSqlByTableInfo(Manager().GetIDbFactory(factoryName), tableInfo, param, updateColName, joiner, operators, hash);
            //写SQL日志
            LIS.Core.Util.LogUtils.WriteSqlLog("执行更新SQL:" + sql);
            //声明式SQL,并且设置参数
            stmt = Manager().Connection().prepareStatement(sql);
            String paraSql = DBParaUtil.SetDBPara(stmt, hash.GetParam());
            row = stmt.executeUpdate();
            LIS.Core.Util.LogUtils.WriteSqlLog("参数:" + paraSql);
            outParam.Code = OutStatus.SUCCESS;
            outParam.Message = "更新数据成功。";
            return row;
        } catch (Exception ex) {
            //操作异常,判断如果开启了事务,就回滚事务
            outParam.Code = OutStatus.ERROR;
            if (Manager().Hastransaction) {
                if (!Manager().RollTransaction()) {
                    outParam.Message = "更新数据失败!" + ex.getMessage() + ";回滚事务失败。";
                }
            }
            outParam.Message = "更新数据失败!" + ex.getMessage();
        }
        //操作结束释放资源
        finally {
            if (stmt != null) {
                stmt.close();
            }
            //如果上层调用未开启事务,则调用结束释放数据库连接
            if (!Manager().Hastransaction) {
                Manager().Close();
            }
        }
        return row;
    }

    /**
     * 根据条件删除记录
     *
     * @param entity    实体对象
     * @param param     删除条件,有条件按条件删除,没有条件按主键删除
     * @param outParam  输出执行成功或失败的信息
     * @param joiner    多条件逻辑连接符,为空或不给则按则按且连接,给的话长度应该比参数长度少1,如: and
     * @param operators 操作符,为空或不给的话各条件按等来比较,给的话长度应该跟参数长度一样,如: !=
     * @param        类型限定符
     * @return 影响行数
     */
    @Override
    public <T> int Remove(T entity, HashParam param, OutParam outParam, List<String> joiner, List<String> operators) throws Exception {
        PreparedStatement stmt = null;
        if (outParam == null) outParam = new OutParam();
        int row = 0;
        try {
            //根据实体对象获取表信息
            LIS.DAL.ORM.Common.TableInfo tableInfo = LIS.DAL.ORM.Common.ModelToSqlUtil.GetTypeInfo(entity);
            HashParam hash = new HashParam();
            //获取删除SQL语句
            String sql = LIS.DAL.ORM.Common.ModelToSqlUtil.GetDeleteSqlByTableInfo(Manager().GetIDbFactory(factoryName), tableInfo, param, joiner, operators, hash);
            //写SQL日志
            LIS.Core.Util.LogUtils.WriteSqlLog("执行删除SQL:" + sql);
            //声明式SQL,并设置参数
            stmt = Manager().Connection().prepareStatement(sql);
            String paraSql = DBParaUtil.SetDBPara(stmt, hash.GetParam());
            row = stmt.executeUpdate();
            LIS.Core.Util.LogUtils.WriteSqlLog("参数:" + paraSql);
            outParam.Code = OutStatus.SUCCESS;
            outParam.Message = "删除数据成功。";
            return row;
        } catch (Exception ex) {
            //操作异常,判断如果开启了事务,就回滚事务
            outParam.Code = OutStatus.ERROR;
            if (Manager().Hastransaction) {
                if (!Manager().RollTransaction()) {
                    outParam.Message = "更新数据失败!" + ex.getMessage() + ";回滚事务失败。";
                }
            }
            outParam.Message = "更新数据失败!" + ex.getMessage();
        }
        //操作结束释放资源
        finally {
            if (stmt != null) {
                stmt.close();
            }
            //如果上层调用未开启事务,则调用结束释放数据库连接
            if (!Manager().Hastransaction) {
                Manager().Close();
            }
        }
        return row;
    }

    /**
     * 根据ID删除记录
     *
     * @param entity   实体对象
     * @param outParam 输出信息
     * @param       实体类型限定
     * @return 影响行数
     */
    public <T> int Remove(T entity, OutParam outParam) throws Exception {
        return Remove(entity, null, outParam, null, null);
    }

    /**
     * 批量删除对象,发生错误后全部回滚,批量操作
     *
     * @param entity 实体对象
     * @param idList 对象ID集合
     * @param     实体限定类型
     * @return 影响行数
     */
    public <T> int RemoveLot(T entity, List<Object> idList) throws Exception {
        //无删除数据直接返回
        if (idList == null || idList.size() == 0) return 0;
        //记录影响行数
        int row = 0;
        //记录处理删除数据id
        String curId;
        //记录调用方法出参
        OutParam outParam = new OutParam();
        HashParam param = new HashParam();
        try {
            for (int i = 0; i < idList.size(); i++) {
                Object id = idList.get(i);
                LIS.DAL.ORM.Common.TableInfo tableInfo = LIS.DAL.ORM.Common.ModelToSqlUtil.GetTypeInfo(entity);
                String idName = tableInfo.ID.Key;
                param.Clear();
                param.Add(idName, id);
                curId = id.toString();
                int ret = Remove(entity, param, outParam, null, null);
                if (outParam.Code == OutStatus.ERROR) {
                    throw new Exception("删除记录失败!记录id:" + curId);
                }
                //累计删除成功的记录数
                row += ret;
            }
            return row;
        } catch (Exception ex) {
            row = 0;
            if (Manager().Hastransaction) {
                if (!Manager().RollTransactionAll()) {
                    LIS.Core.Util.LogUtils.WriteSqlLog(ex.getMessage() + ";回滚事务失败!");
                }
            }
            LIS.Core.Util.LogUtils.WriteSqlLog("批量删除数据异常:" + ex.getMessage());
        }
        return row;
    }

    /**
     * 码表查询
     *
     * @param modelName   实体名称
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderField  排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param pageSize    页大小。为-1,无条件查所有数据
     * @param pageIndex   第几页。为-1,无条件查询所有数据
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @return
     */
    @Override
    public String QueryAllWithFKByName(String modelName, HashParam param, String orderField, boolean returnCount, int pageSize, int pageIndex, String fields, List<String> joiner, List<String> operators) throws Exception {
        List<ParamDto> pdto = null;
        if (param != null) {
            pdto = param.GetParam();
        }
        return QueryAllWithFKByName(modelName, pdto, orderField, returnCount, pageSize, pageIndex, fields, joiner, operators);
    }

    /**
     * 码表查询
     *
     * @param modelName   实体名称
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderField  排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param pageSize    页大小。为-1,无条件查所有数据
     * @param pageIndex   第几页。为-1,无条件查询所有数据
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @return
     */
    @Override
    public String QueryAllWithFKByName(String modelName, List<ParamDto> param, String orderField, boolean returnCount, int pageSize, int pageIndex, String fields, List<String> joiner, List<String> operators) throws Exception {
        try {
            Class c = GetTypeByName(modelName);
            if (c != null) {
                Object o = c.getConstructor().newInstance();
                return QueryAllWithFK(o, param, orderField, returnCount, pageSize, pageIndex, fields, joiner, operators);
            }
        } catch (Exception ex) {
            LIS.Core.Util.LogUtils.WriteExceptionLog("调用ORM的QueryAllByName异常", ex);
        }
        return "";
    }

    /**
     * 码表查询,不分页
     *
     * @param modelName   实体名称
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderField  排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @return
     */
    @Override
    public String QueryAllWithFKByName(String modelName, HashParam param, String orderField, boolean returnCount, String fields, List<String> joiner, List<String> operators) throws Exception {
        return QueryAllWithFKByName(modelName, param, orderField, returnCount, -1, -1, fields, joiner, operators);
    }

    /**
     * 码表查询,不分页
     *
     * @param modelName   实体名称
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderField  排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @return
     */
    @Override
    public String QueryAllWithFKByName(String modelName, List<ParamDto> param, String orderField, boolean returnCount, String fields, List<String> joiner, List<String> operators) throws Exception {
        return QueryAllWithFKByName(modelName, param, orderField, returnCount, -1, -1, fields, joiner, operators);
    }


    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 该方法会把外键关联的字段查出来,用来取缔试图的查询
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param pageSize    页大小。为-1,无条件查所有数据
     * @param pageIndex   第几页。为-1,无条件查询所有数据
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param          限定实体类型
     * @return 查询json串
     */
    @Override
    public <T> String QueryAllWithFK(T model, HashParam param, String orderFields, boolean returnCount, int pageSize, int pageIndex, String fields, List<String> joiner, List<String> operators) throws Exception {
        List<ParamDto> pdto = null;
        if (param != null) {
            pdto = param.GetParam();
        }
        return QueryAllWithFK(model, pdto, orderFields, returnCount, pageSize, pageIndex, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 该方法会把外键关联的字段查出来,用来取缔试图的查询
     * 不分页
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param          限定实体类型
     * @return 查询json串
     */
    @Override
    public <T> String QueryAllWithFK(T model, HashParam param, String orderFields, boolean returnCount, String fields, List<String> joiner, List<String> operators) throws Exception {
        List<ParamDto> pdto = null;
        if (param != null) {
            pdto = param.GetParam();
        }
        return QueryAllWithFK(model, pdto, orderFields, returnCount, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 该方法会把外键关联的字段查出来,用来取缔试图的查询
     * 不分页
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param          限定实体类型
     * @return 查询json串
     */
    @Override
    public <T> String QueryAllWithFK(T model, List<ParamDto> param, String orderFields, boolean returnCount, String fields, List<String> joiner, List<String> operators) throws Exception {
        return QueryAllWithFK(model, param, orderFields, returnCount, -1, -1, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 该方法会把外键关联的字段查出来,用来取缔试图的查询
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param pageSize    页大小。为-1,无条件查所有数据
     * @param pageIndex   第几页。为-1,无条件查询所有数据
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param          限定实体类型
     * @return 查询json串
     */
    @Override
    public <T> String QueryAllWithFK(T model, List<ParamDto> param, String orderFields, boolean returnCount, int pageSize, int pageIndex, String fields, List<String> joiner, List<String> operators) throws Exception {
        //json数据组装容器
        StringBuilder jsonsb = new StringBuilder();
        //查询起始行数
        int fromRow = -1;
        //查询结束行数
        int toRow = -1;
        //是否查询全部数据
        boolean findAll = false;
        //记录总行数
        int rowCount = 0;
        if (fields != null && !fields.isEmpty()) {
            fields = "," + fields + ",";
        }
        //如果未传入分页数据其中一个未-1,则认为部分页而查询所有数据
        if (pageIndex == -1 || pageSize == -1) {
            findAll = true;
        }
        //计算查询起始和结束行数
        else {
            fromRow = (pageIndex - 1) * pageSize;
            toRow = pageIndex * pageSize;
        }
        PreparedStatement pstat = null;
        ResultSet rst = null;
        LIS.DAL.ORM.Common.TableInfo tableInfo = LIS.DAL.ORM.Common.ModelToSqlUtil.GetTypeInfo(model);

        //根据表信息将查询参数组装成Select SQL
        String sql = LIS.DAL.ORM.Common.ModelToSqlUtil.GetSelectSqlByTableInfo(Manager().GetIDbFactory(factoryName), tableInfo, param, operators, joiner, orderFields, true);
        //写SQL日志
        LIS.Core.Util.LogUtils.WriteSqlLog("执行QueryAllWithFK返回String查询SQL:" + sql);
        //如果返回总行数,返回总行数写法
        if (returnCount) {
            jsonsb.append("{");
            jsonsb.append("\"rows\":[");
        }
        //否则采用普通数组写法
        else {
            jsonsb.append("[");
        }
        StringBuilder rowAllsb = new StringBuilder();
        try {
            pstat = Manager().Connection().prepareStatement(sql);
            String paraSql = DBParaUtil.SetDBPara(pstat, param);
            rst = pstat.executeQuery();
            LIS.Core.Util.LogUtils.WriteSqlLog("参数:" + paraSql);
            //标识是否第一行
            boolean isFirstRow = true;
            while (rst.next()) {
                rowCount++;     //总行数加一
                //查询全部,或者取分页范围内的记录
                if (findAll || (rowCount > fromRow && rowCount <= toRow)) {
                    ResultSetMetaData metaData = rst.getMetaData();
                    //获取列数
                    int colCount = metaData.getColumnCount();
                    //单行数据容器
                    StringBuilder rowsb = new StringBuilder();
                    rowsb.append("{");
                    //标识是否第一列
                    boolean isFirstCol = true;
                    for (int coli = 1; coli <= colCount; coli++) {
                        //获取列名
                        String colName = metaData.getColumnName(coli);
                        //获取列值
                        Object colValue = rst.getObject(coli);
                        if (colValue == null) colValue = "";
                        //如果传了显示的字段,过滤不包含的字段
                        if (fields != null && !fields.isEmpty() && fields.indexOf("," + colName + ",") < 0) {
                            continue;
                        }
                        if (isFirstCol) {
                            rowsb.append("\"" + colName + "\":");
                            rowsb.append("\"" + JsonHelper.DealForJsonString(colValue.toString()).toString() + "\"");
                            isFirstCol = false;
                        } else {
                            rowsb.append(",");
                            rowsb.append("\"" + colName + "\":");
                            rowsb.append("\"" + JsonHelper.DealForJsonString(colValue.toString()).toString() + "\"");
                        }
                    }
                    rowsb.append("}");
                    if (isFirstRow) {
                        rowAllsb.append(rowsb.toString());
                        isFirstRow = false;
                    } else {
                        rowAllsb.append(",");
                        rowAllsb.append(rowsb.toString());
                    }
                }
            }
        } catch (Exception ex) {
            //查询异常清空数据记录容器
            rowAllsb.delete(0, rowAllsb.length());
        }
        //操作结束释放资源,但是不断连接,不然没法连续做其他数据库操作了
        finally {
            if (rst != null) {
                rst.close();
            }
            if (pstat != null) {
                pstat.close();
            }
            //如果上层调用未开启事务,则调用结束释放数据库连接
            if (!Manager().Hastransaction) {
                manager.Close();
            }
        }
        //组装数据记录
        jsonsb.append(rowAllsb.toString());
        //补充数组结尾符
        jsonsb.append("]");
        if (returnCount) {
            jsonsb.append(",");
            jsonsb.append("\"total\":");
            jsonsb.append(rowCount);
            jsonsb.append("}");
        }
        return jsonsb.toString();
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     *
     * @param modelName   实体名称
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param pageSize    页大小。为-1,无条件查所有数据
     * @param pageIndex   第几页。为-1,无条件查询所有数据
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @return 查询json串
     */
    @Override
    public String QueryAll(String modelName, HashParam param, String orderFields, boolean returnCount, int pageSize, int pageIndex, String fields, List<String> joiner, List<String> operators) throws Exception {
        List<ParamDto> pdto = null;
        if (param != null) {
            pdto = param.GetParam();
        }
        return QueryAll(modelName, pdto, orderFields, returnCount, pageSize, pageIndex, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     *
     * @param modelName   实体名称
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param pageSize    页大小。为-1,无条件查所有数据
     * @param pageIndex   第几页。为-1,无条件查询所有数据
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @return 查询json串
     */
    @Override
    public String QueryAll(String modelName, List<ParamDto> param, String orderFields, boolean returnCount, int pageSize, int pageIndex, String fields, List<String> joiner, List<String> operators) throws Exception {
        try {
            Class c = GetTypeByName(modelName);
            if (c != null) {
                Object o = c.getConstructor().newInstance();
                return QueryAll(o, param, orderFields, returnCount, pageSize, pageIndex, fields, joiner, operators);
            }
        } catch (Exception ex) {
            LIS.Core.Util.LogUtils.WriteExceptionLog("调用ORM的QueryAllByName异常", ex);
        }
        return "";
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 不分页
     *
     * @param modelName   实体名称
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @return 查询json串
     */
    @Override
    public String QueryAll(String modelName, HashParam param, String orderFields, boolean returnCount, String fields, List<String> joiner, List<String> operators) throws Exception {
        List<ParamDto> pdto = null;
        if (param != null) {
            pdto = param.GetParam();
        }
        return QueryAll(modelName, pdto, orderFields, returnCount, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 不分页
     *
     * @param modelName   实体名称
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @return 查询json串
     */
    @Override
    public String QueryAll(String modelName, List<ParamDto> param, String orderFields, boolean returnCount, String fields, List<String> joiner, List<String> operators) throws Exception {
        try {
            Type type = GetTypeByName(modelName);
            if (type != null) {
                Object o = type.getClass().getConstructor().newInstance();
                return QueryAll(o, param, orderFields, returnCount, -1, -1, fields, joiner, operators);
            }
        } catch (Exception ex) {
            LIS.Core.Util.LogUtils.WriteExceptionLog("调用ORM的QueryAll异常", ex);
        }
        return "";
    }


    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param pageSize    页大小。为-1,无条件查所有数据
     * @param pageIndex   第几页。为-1,无条件查询所有数据
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param          限定实体类型
     * @return 查询json串
     */
    @Override
    public <T> String QueryAll(T model, HashParam param, String orderFields, boolean returnCount, int pageSize, int pageIndex, String fields, List<String> joiner, List<String> operators) throws Exception {
        List<ParamDto> pdto = null;
        if (param != null) {
            pdto = param.GetParam();
        }
        return QueryAll(model, pdto, orderFields, returnCount, pageSize, pageIndex, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 该方法不带分页
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param          限定实体类型
     * @return 查询json串
     */
    @Override
    public <T> String QueryAll(T model, HashParam param, String orderFields, boolean returnCount, String fields, List<String> joiner, List<String> operators) throws Exception {
        List<ParamDto> pdto = null;
        if (param != null) {
            pdto = param.GetParam();
        }
        return QueryAll(model, pdto, orderFields, returnCount, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 该方法不带分页
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param          限定实体类型
     * @return 查询json串
     */
    @Override
    public <T> String QueryAll(T model, List<ParamDto> param, String orderFields, boolean returnCount, String fields, List<String> joiner, List<String> operators) throws Exception {
        return QueryAll(model, param, orderFields, returnCount, -1, -1, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param pageSize    页大小。为-1,无条件查所有数据
     * @param pageIndex   第几页。为-1,无条件查询所有数据
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param          限定实体类型
     * @return 查询json串
     */
    @Override
    public <T> String QueryAll(T model, List<ParamDto> param, String orderFields, boolean returnCount, int pageSize, int pageIndex, String fields, List<String> joiner, List<String> operators) throws Exception {
        //json数据组装容器
        StringBuilder jsonsb = new StringBuilder();
        //查询起始行数
        int fromRow = -1;
        //查询结束行数
        int toRow = -1;
        //是否查询全部数据
        boolean findAll = false;
        //记录总行数
        int rowCount = 0;
        //处理显示字段
        if (fields != null && !fields.isEmpty()) {
            fields = "," + fields + ",";
        }
        //如果未传入分页数据其中一个未-1,则认为部分页而查询所有数据
        if (pageIndex == -1 || pageSize == -1) {
            findAll = true;
        }
        //计算查询起始和结束行数
        else {
            fromRow = (pageIndex - 1) * pageSize;
            toRow = pageIndex * pageSize;
        }
        PreparedStatement pstat = null;
        ResultSet rst = null;
        LIS.DAL.ORM.Common.TableInfo tableInfo = LIS.DAL.ORM.Common.ModelToSqlUtil.GetTypeInfo(model);
        //根据表信息将查询参数组装成Select SQL
        String sql = LIS.DAL.ORM.Common.ModelToSqlUtil.GetSelectSqlByTableInfo(Manager().GetIDbFactory(factoryName), tableInfo, param, operators, joiner, orderFields, false);
        //写SQL日志
        LIS.Core.Util.LogUtils.WriteSqlLog("执行QueryAll返回String查询SQL:" + sql);
        //如果返回总行数,返回总行数写法
        if (returnCount) {
            jsonsb.append("{");
            jsonsb.append("\"rows\":[");
        }
        //否则采用普通数组写法
        else {
            jsonsb.append("[");
        }
        StringBuilder rowAllsb = new StringBuilder();
        try {
            pstat = Manager().Connection().prepareStatement(sql);
            String paraSql = DBParaUtil.SetDBPara(pstat, param);
            rst = pstat.executeQuery();
            LIS.Core.Util.LogUtils.WriteSqlLog("参数:" + paraSql);
            //标识是否第一行
            boolean isFirstRow = true;
            while (rst.next()) {
                rowCount++;     //总行数加一
                //查询全部,或者取分页范围内的记录
                if (findAll || (rowCount > fromRow && rowCount <= toRow)) {
                    ResultSetMetaData metaData = rst.getMetaData();
                    //获取列数
                    int colCount = metaData.getColumnCount();
                    //单行数据容器
                    StringBuilder rowsb = new StringBuilder();
                    rowsb.append("{");
                    //标识是否第一列
                    boolean isFirstCol = true;
                    for (int coli = 1; coli <= colCount; coli++) {
                        //获取列名
                        String colName = metaData.getColumnName(coli);
                        //获取列值
                        Object colValue = rst.getObject(coli);
                        if (colValue == null) colValue = "";
                        //如果传了显示的字段,过滤不包含的字段
                        if (fields != null && !fields.isEmpty() && fields.indexOf("," + colName + ",") < 0) {
                            continue;
                        }
                        if (isFirstCol) {
                            rowsb.append("\"" + colName + "\":");
                            rowsb.append("\"" + colValue + "\"");
                            isFirstCol = false;
                        } else {
                            //非第一列插入","
                            rowsb.append(",");
                            rowsb.append("\"" + colName + "\":");
                            rowsb.append("\"" + colValue + "\"");
                        }
                    }
                    rowsb.append("}");
                    if (isFirstRow) {
                        rowAllsb.append(rowsb.toString());
                        isFirstRow = false;
                    } else {
                        rowAllsb.append(",");
                        rowAllsb.append(rowsb.toString());
                    }
                }
            }
        } catch (Exception ex) {
            //查询异常清空数据记录容器
            rowAllsb.delete(0, rowAllsb.length());
        }
        //操作结束释放资源,但是不断连接,不然没法连续做其他数据库操作了
        finally {
            if (rst != null) {
                rst.close();
            }
            if (pstat != null) {
                pstat.close();
            }
            //如果上层调用未开启事务,则调用结束释放数据库连接
            if (!Manager().Hastransaction) {
                manager.Close();
            }
        }
        //组装数据记录
        jsonsb.append(rowAllsb.toString());
        //补充数组结尾符
        jsonsb.append("]");
        if (returnCount) {
            jsonsb.append(",");
            jsonsb.append("\"total\":");
            jsonsb.append(rowCount);
            jsonsb.append("}");
        }
        return jsonsb.toString();
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列和值的键对
     * @param orderField  排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param pageSize    页大小。为-1,无条件查所有数据
     * @param pageIndex   第几页。为-1,无条件查询所有数据
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param          限定实体类型
     * @return 查询数据json串
     */
    public <T> String SelectAll(T model, HashParam param, String orderField, boolean returnCount, int pageSize, int pageIndex, String fields) throws Exception {
        return QueryAll(model, param, orderField, returnCount, pageSize, pageIndex, fields, null, null);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 不分页
     *
     * @param modelName   实体名称
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param          限定实体类型
     * @return 查询实体列表List
     */
    @Override
    public <T> List<T> QueryAll(String modelName, HashParam param, String orderFields, String fields, List<String> joiner, List<String> operators) throws Exception {
        List<ParamDto> pdto = new LinkedList<>();
        if (param != null) {
            pdto = param.GetParam();
        }
        return QueryAll(modelName, pdto, orderFields, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 不分页
     *
     * @param modelName   实体名称
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param          限定实体类型
     * @return 查询实体列表List
     */
    @Override
    public <T> List<T> QueryAll(String modelName, List<ParamDto> param, String orderFields, String fields, List<String> joiner, List<String> operators) throws Exception {
        List<T> list = new ArrayList<T>();
        try {
            Type type = GetTypeByName(modelName);
            if (type != null) {
                T model = (T) type.getClass().getConstructor().newInstance();
                return QueryAll(model, param, orderFields, fields, joiner, operators);
            }
        } catch (Exception ex) {

        }
        return list;
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 不分页
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param          限定实体类型
     * @return 查询实体列表List
     */
    @Override
    public <T> List<T> QueryAll(T model, HashParam param, String orderFields, String fields, List<String> joiner, List<String> operators) throws Exception {
        List<ParamDto> pdto = null;
        if (param != null) {
            pdto = param.GetParam();
        }
        return QueryAll(model, pdto, orderFields, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 不分页
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param          限定实体类型
     * @return 查询实体列表List
     */
    @Override
    public <T> List<T> QueryAll(T model, List<ParamDto> param, String orderFields, String fields, List<String> joiner, List<String> operators) throws Exception {
        return QueryAll(model, param, orderFields, -1, -1, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param pageSize    页大小。为-1,无条件查所有数据
     * @param pageIndex   第几页。为-1,无条件查询所有数据
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param          限定实体类型
     * @return 查询实体列表List
     */
    @Override
    public <T> List<T> QueryAll(T model, HashParam param, String orderFields, int pageSize, int pageIndex, String fields, List<String> joiner, List<String> operators) throws Exception {
        List<ParamDto> pdto = null;
        if (param != null) {
            pdto = param.GetParam();
        }
        return QueryAll(model, pdto, orderFields, pageSize, pageIndex, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param pageSize    页大小。为-1,无条件查所有数据
     * @param pageIndex   第几页。为-1,无条件查询所有数据
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param          限定实体类型
     * @return 查询实体列表List
     */
    @Override
    public <T> List<T> QueryAll(T model, List<ParamDto> param, String orderFields, int pageSize, int pageIndex, String fields, List<String> joiner, List<String> operators) throws Exception {
        //存储返回的对象数据
        List<T> retList = new ArrayList<T>();
        //查询起始行数
        int fromRow = -1;
        //查询结束行数
        int toRow = -1;
        //是否查询全部数据
        boolean findAll = false;
        //记录总行数
        int rowCount = 0;
        //处理显示字段
        if (fields != null && !fields.isEmpty()) {
            fields = "," + fields + ",";
        }
        //如果未传入分页数据其中一个未-1,则认为部分页而查询所有数据
        if (pageIndex == -1 || pageSize == -1) {
            findAll = true;
        }
        //计算查询起始和结束行数
        else {
            fromRow = (pageIndex - 1) * pageSize;
            toRow = pageIndex * pageSize;
        }
        PreparedStatement pstat = null;
        ResultSet rst = null;
        LIS.DAL.ORM.Common.TableInfo tableInfo = LIS.DAL.ORM.Common.ModelToSqlUtil.GetTypeInfo(model);
        //根据表信息将查询参数组装成Select SQL
        String sql = LIS.DAL.ORM.Common.ModelToSqlUtil.GetSelectSqlByTableInfo(Manager().GetIDbFactory(factoryName), tableInfo, param, operators, joiner, orderFields, false);
        //写SQL日志
        LIS.Core.Util.LogUtils.WriteSqlLog("执行QueryAll返回List查询SQL:" + sql);
        Class<?> clazzz = model.getClass();
        try {
            pstat = Manager().Connection().prepareStatement(sql);
            String paraSql = DBParaUtil.SetDBPara(pstat, param);
            rst = pstat.executeQuery();
            LIS.Core.Util.LogUtils.WriteSqlLog("参数:" + paraSql);
            //标识是否第一行
            boolean isFirstRow = true;
            while (rst.next()) {
                rowCount++;     //总行数加一
                //查询全部,或者取分页范围内的记录
                if (findAll || (rowCount > fromRow && rowCount <= toRow)) {
                    T obj = (T) clazzz.getConstructor().newInstance();
                    for (int coli = 0; coli < tableInfo.ColList.size(); coli++) {
                        String name = tableInfo.ColList.get(coli).Name;
                        Object value = rst.getObject(name);
                        LIS.Core.Util.ReflectUtil.SetObjValue(obj, name, value);
                    }
                    retList.add(obj);
                }
            }
        } catch (Exception ex) {
            //查询异常清空数据
            retList.clear();
        }
        //操作结束释放资源,但是不断连接,不然没法连续做其他数据库操作了
        finally {
            if (rst != null) {
                rst.close();
            }
            if (pstat != null) {
                pstat.close();
            }
            //如果上层调用未开启事务,则调用结束释放数据库连接
            if (!Manager().Hastransaction) {
                manager.Close();
            }
        }
        return retList;
    }

    /**
     * 数据查询
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param pageSize    页大小。为-1,无条件查所有数据
     * @param pageIndex   第几页。为-1,无条件查询所有数据
     * @param          限定实体类型
     * @return 实体对象列表
     */
    public <T> List<T> FindAll(T model, HashParam param, String orderFields, int pageSize, int pageIndex) throws Exception {
        return QueryAll(model, param, orderFields, pageSize, pageIndex, "", null, null);
    }

    /**
     * 通过实体名称得到实体信息
     *
     * @param modelName 实体名称
     * @return 实体信息json串
     */
    @Override
    public String GetModelInfoByName(String modelName) throws Exception {
        //返回表消息容器
        StringBuilder tableInfoJson = new StringBuilder();
        //先获取类对象,实例化实体对象
        Class<?> clazz = Class.forName("LIS.Model.Entity." + modelName);
        LIS.DAL.ORM.Common.TableInfo tableInfo = LIS.DAL.ORM.Common.ModelToSqlUtil.GetTypeInfo(clazz.getConstructor().newInstance());
        if (tableInfo != null) {
            //表名
            String tableName = tableInfo.TableInfo.Name();
            tableInfoJson.append("{\"tableName\":\"" + tableName + "\",\"columns\":[");
            //列信息
            List<LIS.DAL.ORM.Common.ColumnInfo> colInfo = tableInfo.ColList;
            //ID信息
            LIS.DAL.ORM.Common.IdInfo idInfo = tableInfo.ID;
            String idName = idInfo.Key;
            boolean isFirst = true;
            //处理列信息
            for (int coli = 0; coli < colInfo.size(); coli++) {
                LIS.DAL.ORM.Common.ColumnInfo col = colInfo.get(coli);
                String colName = col.Name;
                if (isFirst) {
                    tableInfoJson.append("{\"columnName\":\"" + colName + "\"");
                    isFirst = false;
                } else {
                    tableInfoJson.append(",");
                    tableInfoJson.append("{\"columnName\":\"" + colName + "\"");
                }
                //是否ID字段
                if (idName.equals(colName)) {
                    tableInfoJson.append(",\"isId\":true");
                } else {
                    tableInfoJson.append(",\"isId\":false");
                }
                //外键特性
                FrekeyAttribute frekeys = col.FkInfo;
                if (frekeys != null) {
                    tableInfoJson.append(",\"fkModelName\":\"" + frekeys.Name() + "\",\"refColumnName\":\"" + frekeys.RefColumnName() + "\",\"AssociaField\":\"" + frekeys.AssociaField() + "\"");
                }
                tableInfoJson.append("}");
            }
            tableInfoJson.append("]}");
        }
        return tableInfoJson.toString();
    }

    /**
     * 通过实体名称获得实体类型信息
     *
     * @param modelName 实体名称
     * @return
     */
    public Class GetTypeByName(String modelName) throws Exception {
        return LIS.Core.Util.ReflectUtil.GetType("LIS.Model.Entity." + modelName, "LIS.Model");
    }

}

实现配置获取类
jbase引入连接池_第3张图片

package LIS.Core.MultiPlatform;

import java.io.File;
import java.net.URL;
import java.nio.file.Paths;
import java.util.Hashtable;

import LIS.Core.MultiPlatform.LISContext;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

/**
 * 获得配置工具
 */
public class LISConfigurtaion {

    /**
     * 存解析的参数
     */
    private static Hashtable<String, String> hs = new Hashtable();

    /**
     * 是否初始化
     */
    private static boolean hasInit = false;

    /**
     * 按键取值
     *
     * @param key 键
     * @return
     * @throws Exception
     */
    public static String Configuration(String key) throws Exception {
        if (hasInit == false) {
            Init();
        }
        if (hs.containsKey(key)) {
            return hs.get(key);
        }
        return "";
    }

    /**
     * 初始化配置获取
     *
     * @throws Exception
     */
    public static void Init() throws Exception {
        String confPath = Paths.get(LISContext.WebBasePath, "Conf", "appsetting.xml").toString();
        //判断配置是否存在
        File file = new File(confPath);
        if (!file.exists()) {
            throw new Exception(confPath + "文件不存在,请确认!");
        }
        //解析xml
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(file);
        // 获得根节点
        Element rootElement = document.getDocumentElement();
        // 获得根节点下的所有子节点
        NodeList students = rootElement.getChildNodes();
        for (int i = 0; i < students.getLength(); i++) {
            // 由于节点多种类型,而一般我们需要处理的是元素节点
            Node childNode = students.item(i);
            // 元素节点就是非空的子节点,也就是还有孩子的子节点
            if (childNode.getNodeType() == Node.ELEMENT_NODE) {
                Element childElement = (Element) childNode;
                //不是对象配置元素就忽略
                if (childElement.getNodeName() != "add") {
                    continue;
                }
                //解析类型配置
                String key = childElement.getAttribute("key");
                //是否单例
                String value = childElement.getAttribute("value");
                hs.put(key, value);
            }
        }
    }
}

修改数据库驱动实现类

package LIS.Dal.Base;

import LIS.DAL.ORM.DBUtility.IDbFactory;
import LIS.Core.MultiPlatform.LISConfigurtaion;
import LIS.Core.Util.Convert;

import java.sql.*;

/**
 * postgresql驱动实现类
 */
public class PostgreSqlBase implements LIS.DAL.ORM.DBUtility.IDbFactory {
    /**
     * 得到数据库类型
     *
     * @return
     */
    public String GetStrDbType() {
        return "pgsql";
    }

    /**
     * 得到数据库连接串,先写死,后面从配置取
     *
     * @return
     */
    public String GetConnectionString() throws Exception {
        return LISConfigurtaion.Configuration("ConnectionString");
    }

    /**
     * 得到数据库用户名
     *
     * @return
     */
    public String GetUserName() throws Exception {
        return LISConfigurtaion.Configuration("UserName");
    }

    /**
     * 得到数据库密码
     *
     * @return
     */
    public String GetUserPass() throws Exception {
        return LISConfigurtaion.Configuration("UserPass");
    }

    /**
     * 得到返回查询的RowID的SQL语句,供插入数据得到RowID用
     *
     * @return
     */
    public String GetReturnRowIDSql() {
        return " RETURNING \"RowID\"";
    }

    /**
     * 处理表名称,用来适配不同数据库间的属性命名差异
     *
     * @param tableName 表名
     * @return
     */
    public String DealTableName(String tableName) {
        return tableName;
    }

    /**
     * 处理属性名字
     *
     * @param propertyName 属性名字
     * @return
     */
    public String DealPropertyName(String propertyName) {
        return "\"" + propertyName + "\"";
    }

    /**
     * 处理Sql参数
     *
     * @param propertyName 属性名字
     * @return
     */
    public String DealSqlPara(String propertyName) {
        return "?";
    }

    /**
     * 加载驱动
     *
     * @return
     */
    public String GetDriver() {
        return "org.postgresql.Driver";
    }

    /**
     * 得到初始化连接串大小
     *
     * @return
     */
    public int GetInitPoolSize() throws Exception {
        String initSize = LISConfigurtaion.Configuration("PoolInitPoolSize");
        return Convert.ToInt32(initSize);
    }

    /**
     * 得到最大连接串大小
     *
     * @return
     */
    public int GetMaxPoolSize() throws Exception {
        String maxSize = LISConfigurtaion.Configuration("PoolMaxPoolSize");
        return Convert.ToInt32(maxSize);
    }

}

配置数据库连接
jbase引入连接池_第4张图片
连本地库测试
jbase引入连接池_第5张图片
多开刷新测连接
jbase引入连接池_第6张图片

本次涉及连接池、不同数据库接口定义、读取连接串配置、管理连接和事务、写Sql日志

你可能感兴趣的:(java)