网站主题和代码生成器完事之后,ORM成为主要工作,之前只是搭了ORM的大体结构,没有详细优化和实现。这次引入连接池、把连接串信息从配置取、调整抛出异常。
连接池包选择c3p0,因为他稳定,用的多,下载引入c3p0包
调整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;
}
实现连接串工具类
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";
/// <summary>
/// 存会话信息
/// </summary>
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 <T> 实体类型约束
* @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 <T> 实体类型约束
* @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 <T> 类型限定符
* @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 <T> 类型限定符
* @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 <T> 实体类型限定
* @return 影响行数
*/
public <T> int Remove(T entity, OutParam outParam) throws Exception {
return Remove(entity, null, outParam, null, null);
}
/**
* 批量删除对象,发生错误后全部回滚,批量操作
*
* @param entity 实体对象
* @param idList 对象ID集合
* @param <T> 实体限定类型
* @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 <T> 限定实体类型
* @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 <T> 限定实体类型
* @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 <T> 限定实体类型
* @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 <T> 限定实体类型
* @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 <T> 限定实体类型
* @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 <T> 限定实体类型
* @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 <T> 限定实体类型
* @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 <T> 限定实体类型
* @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 <T> 限定实体类型
* @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 <T> 限定实体类型
* @return 查询实体列表List<T>
*/
@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 <T> 限定实体类型
* @return 查询实体列表List<T>
*/
@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 <T> 限定实体类型
* @return 查询实体列表List<T>
*/
@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 <T> 限定实体类型
* @return 查询实体列表List<T>
*/
@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 <T> 限定实体类型
* @return 查询实体列表List<T>
*/
@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 <T> 限定实体类型
* @return 查询实体列表List<T>
*/
@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<T>查询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 <T> 限定实体类型
* @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");
}
}
实现配置获取类
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);
}
}
配置数据库连接
连本地库测试
多开刷新测连接
本次涉及连接池、不同数据库接口定义、读取连接串配置、管理连接和事务、写Sql日志