黑马程序员_学习日记55_628三层项目(用类封装用于拼接的where条件语句、写代码生成器)
2012-07-01 21:46
483 查看
一、用类封装用于拼接的where条件语句(三层实现多条件搜索)
(一)
思想:
多条件搜索时拼接where条件语句,以前是在查询方法中用List<string>和List<SqlParameter>分别存储where条件语句和查询参数,这样做确实很好的解决了多条件查询的问题,但where条件语句和查询参数的集合一旦需要修改,必须进入查询方法修改源代码,不利于程序的扩展。
在此,用Condition类将where条件语句封装起来,需要增加查询条件时,只需实例化一个新的Condition对象,无须修改查询方法。在DAL层中还是要用到List<string>和List<SqlParameter>集合。
(二)具体代码:
1、Condition类:
///<summary>
///拼接where语句的条件有共性:列名、条件比较符、比较值,可以用Condition类封装
///</summary>
public
class Condition
{
///<summary>
///属性名或者数据库中的列名
///</summary>
public
string PropertyName
{
get;
set;
}
//属性对应的值
public
object Value
{
get;
set;
}
public
Operator Operation
{
get;
set;
}
}
public
enum Operator
{
Equal,
NotEqual,
GreaterThan,
LessThan,
Like
}
2、UI层实例化Condition对象,并加入List<Condition>集合
private
void btnSearch_Click(object sender,
EventArgs e)
{
List<Condition> listWhere =
new List<Condition>();
if (txtName.Text.Trim().Length>0)
{
Condition condition =
new Condition();
condition.PropertyName =
"BookName";
condition.Value = txtName.Text.Trim();
condition.Operation =
Operator.Like;
listWhere.Add(condition);
}
if (txtAuthor.Text.Trim().Length > 0)
{
Condition condition =
new Condition();
condition.PropertyName =
"BookAuthor";
condition.Value = txtAuthor.Text.Trim();
condition.Operation =
Operator.Like;
listWhere.Add(condition);
}
if (txtPress.Text.Trim().Length > 0)
{
Condition condition =
new Condition();
condition.PropertyName =
"BookPublisher";
condition.Value = txtPress.Text.Trim();
condition.Operation =
Operator.Like;
listWhere.Add(condition);
}
if (txtPrice.Text.Trim().Length > 0)
{
Condition condition =
new Condition();
condition.PropertyName =
"BookPrice";
condition.Value = txtPrice.Text.Trim();
condition.Operation =
Operator.Equal;
listWhere.Add(condition);
}
BookBll bll =
new BookBll();
bll.Seach(listWhere);
}
3、DAL层拼接where语句,实现查询
public
List<string> Search(List<Condition> list)
{
StringBuilder sbsql =
new StringBuilder("select * from books ");
List<string> wheres =
new List<string>();
List<SqlParameter> pams =
new List<SqlParameter>();
foreach (Condition item
in list)
{
//假设item.PropertyName中存储的就是数据库中的列名
//item.PropertyName
StringBuilder sbWhere =
new StringBuilder();
sbWhere.AppendFormat("{0}",item.PropertyName);
SqlParameter p1 =
new SqlParameter("@" + item.PropertyName, item.Value);
switch (item.Operation)
{
case
Operator.Equal:
sbWhere.Append(" = ");
break;
case
Operator.NotEqual:
sbWhere.Append(" <> ");
break;
case
Operator.GreaterThan:
sbWhere.Append(" > ");
break;
case
Operator.LessThan:
sbWhere.Append(" < ");
break;
case
Operator.Like:
sbWhere.Append(" like ");
p1.Value = "%" + p1.Value +
"%";
break;
}
pams.Add(p1);
//拼接对应的列的值
sbWhere.AppendFormat("@{0}", item.PropertyName);
wheres.Add(sbWhere.ToString());
}
//现在wheres集合中存储的就是每个条件
if (wheres.Count>0)
{
//string.Join串联对象数组的每个元素,并在元素之间加上指定的分隔符,在这里是“and”
sbsql.Append(" where " +
string.Join(" and ", wheres.ToArray()));
//SqlHelper.ExecuteReader(constr, sbsql.ToString(), pams.ToArray());
}
Console.WriteLine(sbsql.ToString());
//循环输出参数名与参数值
foreach (SqlParameter pam
in pams)
{
Console.Write(pam.ParameterName+"\t");
Console.WriteLine(pam.Value);
}
return
null;
}
二、写代码生成器(将表中列信息生成类的属性)
(一)连接指定数据库,读取所有表
private
void LoadTables()
{
using (SqlConnection con =
new SqlConnection(txtConstr.Text.Trim()))
{
//要查询当前的数据库中的表,需要执行以下sql语句
string sql =
"select table_name from INFORMATION_SCHEMA.TABLES";
using (SqlCommand cmd =
new SqlCommand(sql,con))
{
con.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
lstTables.Items.Add(reader.GetString(0));
}
}
}
}
}
}
(二)写将表生成类的模板
private
void btnBuild_Click(object sender,
EventArgs e)
{
//进行一系列的字符串拼接
//1、先获取用户选择的表
string tbName = lstTables.SelectedItem.ToString();
//2、获取用户输入的命名空间
string nsName = txtNameSpace.Text.Trim();
StringBuilder sbCode =
new StringBuilder();
sbCode.AppendLine("using System");
sbCode.AppendLine("using System.Collections.Generic;");
sbCode.AppendLine("using System.Linq;");
sbCode.AppendLine("using System.Text;");
sbCode.AppendLine("");
sbCode.AppendLine("namespace "+nsName);
sbCode.AppendLine("{");
sbCode.AppendLine("
class "+tbName);
sbCode.AppendLine("
{");
//根据列动态生成属性
//1、根据表名查询当前表中所有列信息
List<ColumnInfo> listCols = GetColumnInfoByTableName(tbName);
//遍历列信息,为每一列生成一个属性
foreach (ColumnInfo item
in listCols)
{
sbCode.AppendLine("
public "+ item.DataType +" "+item.ColumnName);
sbCode.AppendLine("
{");
sbCode.AppendLine("
get;");
sbCode.AppendLine("
set;");
sbCode.AppendLine("
}");
}
sbCode.AppendLine("
}");
sbCode.AppendLine("}");
txtCode.Text = sbCode.ToString();
}
(三)根据表名查询当前表中所有列信息
private
List<ColumnInfo> GetColumnInfoByTableName(string tbName)
{
List<ColumnInfo> list =
new List<ColumnInfo>();
using (SqlConnection con =
new SqlConnection(txtConstr.Text.Trim()))
{
string sql =
"select COLUMN_NAME,DATA_TYPE,IS_NULLABLE from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='"+ tbName +"'";
using (SqlCommand cmd =
new SqlCommand(sql,con))
{
con.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
ColumnInfo model =
new ColumnInfo();
model.ColumnName = reader.GetString(0);
model.DataType = reader.GetString(1);
model.IsNullable = reader.GetString(2);
list.Add(model);
}
}
}
}
}
return list;
}
(四)把列名首字母大写。生成ChangeToPropertyName()方法
private
string ChangeToPropertyName(string fieldName)
{
return
char.ToUpper(fieldName[0]) + fieldName.Substring(1);
}
(五)把数据库数据类型转成C#数据类型
private
string ChangeDbTypeToCSharpType(string dbType,string isnullable)
{
Type csharpType =
null;
switch (dbType)
{
case
"char":
case
"nchar":
case
"varchar":
case
"nvarchar":
case
"text":
case
"ntext":
csharpType = typeof(string);
break;
case
"bit":
csharpType = typeof(bool);
break;
case
"int":
csharpType = typeof(int);
break;
}
if (isnullable.ToLower() ==
"yes" && csharpType.IsValueType)
{
return csharpType.ToString() +
"?";
}
return csharpType.ToString();
}
可以看看动软源代码
三、codeSmith
(一)
思想:
多条件搜索时拼接where条件语句,以前是在查询方法中用List<string>和List<SqlParameter>分别存储where条件语句和查询参数,这样做确实很好的解决了多条件查询的问题,但where条件语句和查询参数的集合一旦需要修改,必须进入查询方法修改源代码,不利于程序的扩展。
在此,用Condition类将where条件语句封装起来,需要增加查询条件时,只需实例化一个新的Condition对象,无须修改查询方法。在DAL层中还是要用到List<string>和List<SqlParameter>集合。
(二)具体代码:
1、Condition类:
///<summary>
///拼接where语句的条件有共性:列名、条件比较符、比较值,可以用Condition类封装
///</summary>
public
class Condition
{
///<summary>
///属性名或者数据库中的列名
///</summary>
public
string PropertyName
{
get;
set;
}
//属性对应的值
public
object Value
{
get;
set;
}
public
Operator Operation
{
get;
set;
}
}
public
enum Operator
{
Equal,
NotEqual,
GreaterThan,
LessThan,
Like
}
2、UI层实例化Condition对象,并加入List<Condition>集合
private
void btnSearch_Click(object sender,
EventArgs e)
{
List<Condition> listWhere =
new List<Condition>();
if (txtName.Text.Trim().Length>0)
{
Condition condition =
new Condition();
condition.PropertyName =
"BookName";
condition.Value = txtName.Text.Trim();
condition.Operation =
Operator.Like;
listWhere.Add(condition);
}
if (txtAuthor.Text.Trim().Length > 0)
{
Condition condition =
new Condition();
condition.PropertyName =
"BookAuthor";
condition.Value = txtAuthor.Text.Trim();
condition.Operation =
Operator.Like;
listWhere.Add(condition);
}
if (txtPress.Text.Trim().Length > 0)
{
Condition condition =
new Condition();
condition.PropertyName =
"BookPublisher";
condition.Value = txtPress.Text.Trim();
condition.Operation =
Operator.Like;
listWhere.Add(condition);
}
if (txtPrice.Text.Trim().Length > 0)
{
Condition condition =
new Condition();
condition.PropertyName =
"BookPrice";
condition.Value = txtPrice.Text.Trim();
condition.Operation =
Operator.Equal;
listWhere.Add(condition);
}
BookBll bll =
new BookBll();
bll.Seach(listWhere);
}
3、DAL层拼接where语句,实现查询
public
List<string> Search(List<Condition> list)
{
StringBuilder sbsql =
new StringBuilder("select * from books ");
List<string> wheres =
new List<string>();
List<SqlParameter> pams =
new List<SqlParameter>();
foreach (Condition item
in list)
{
//假设item.PropertyName中存储的就是数据库中的列名
//item.PropertyName
StringBuilder sbWhere =
new StringBuilder();
sbWhere.AppendFormat("{0}",item.PropertyName);
SqlParameter p1 =
new SqlParameter("@" + item.PropertyName, item.Value);
switch (item.Operation)
{
case
Operator.Equal:
sbWhere.Append(" = ");
break;
case
Operator.NotEqual:
sbWhere.Append(" <> ");
break;
case
Operator.GreaterThan:
sbWhere.Append(" > ");
break;
case
Operator.LessThan:
sbWhere.Append(" < ");
break;
case
Operator.Like:
sbWhere.Append(" like ");
p1.Value = "%" + p1.Value +
"%";
break;
}
pams.Add(p1);
//拼接对应的列的值
sbWhere.AppendFormat("@{0}", item.PropertyName);
wheres.Add(sbWhere.ToString());
}
//现在wheres集合中存储的就是每个条件
if (wheres.Count>0)
{
//string.Join串联对象数组的每个元素,并在元素之间加上指定的分隔符,在这里是“and”
sbsql.Append(" where " +
string.Join(" and ", wheres.ToArray()));
//SqlHelper.ExecuteReader(constr, sbsql.ToString(), pams.ToArray());
}
Console.WriteLine(sbsql.ToString());
//循环输出参数名与参数值
foreach (SqlParameter pam
in pams)
{
Console.Write(pam.ParameterName+"\t");
Console.WriteLine(pam.Value);
}
return
null;
}
二、写代码生成器(将表中列信息生成类的属性)
(一)连接指定数据库,读取所有表
private
void LoadTables()
{
using (SqlConnection con =
new SqlConnection(txtConstr.Text.Trim()))
{
//要查询当前的数据库中的表,需要执行以下sql语句
string sql =
"select table_name from INFORMATION_SCHEMA.TABLES";
using (SqlCommand cmd =
new SqlCommand(sql,con))
{
con.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
lstTables.Items.Add(reader.GetString(0));
}
}
}
}
}
}
(二)写将表生成类的模板
private
void btnBuild_Click(object sender,
EventArgs e)
{
//进行一系列的字符串拼接
//1、先获取用户选择的表
string tbName = lstTables.SelectedItem.ToString();
//2、获取用户输入的命名空间
string nsName = txtNameSpace.Text.Trim();
StringBuilder sbCode =
new StringBuilder();
sbCode.AppendLine("using System");
sbCode.AppendLine("using System.Collections.Generic;");
sbCode.AppendLine("using System.Linq;");
sbCode.AppendLine("using System.Text;");
sbCode.AppendLine("");
sbCode.AppendLine("namespace "+nsName);
sbCode.AppendLine("{");
sbCode.AppendLine("
class "+tbName);
sbCode.AppendLine("
{");
//根据列动态生成属性
//1、根据表名查询当前表中所有列信息
List<ColumnInfo> listCols = GetColumnInfoByTableName(tbName);
//遍历列信息,为每一列生成一个属性
foreach (ColumnInfo item
in listCols)
{
sbCode.AppendLine("
public "+ item.DataType +" "+item.ColumnName);
sbCode.AppendLine("
{");
sbCode.AppendLine("
get;");
sbCode.AppendLine("
set;");
sbCode.AppendLine("
}");
}
sbCode.AppendLine("
}");
sbCode.AppendLine("}");
txtCode.Text = sbCode.ToString();
}
(三)根据表名查询当前表中所有列信息
private
List<ColumnInfo> GetColumnInfoByTableName(string tbName)
{
List<ColumnInfo> list =
new List<ColumnInfo>();
using (SqlConnection con =
new SqlConnection(txtConstr.Text.Trim()))
{
string sql =
"select COLUMN_NAME,DATA_TYPE,IS_NULLABLE from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='"+ tbName +"'";
using (SqlCommand cmd =
new SqlCommand(sql,con))
{
con.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
ColumnInfo model =
new ColumnInfo();
model.ColumnName = reader.GetString(0);
model.DataType = reader.GetString(1);
model.IsNullable = reader.GetString(2);
list.Add(model);
}
}
}
}
}
return list;
}
(四)把列名首字母大写。生成ChangeToPropertyName()方法
private
string ChangeToPropertyName(string fieldName)
{
return
char.ToUpper(fieldName[0]) + fieldName.Substring(1);
}
(五)把数据库数据类型转成C#数据类型
private
string ChangeDbTypeToCSharpType(string dbType,string isnullable)
{
Type csharpType =
null;
switch (dbType)
{
case
"char":
case
"nchar":
case
"varchar":
case
"nvarchar":
case
"text":
case
"ntext":
csharpType = typeof(string);
break;
case
"bit":
csharpType = typeof(bool);
break;
case
"int":
csharpType = typeof(int);
break;
}
if (isnullable.ToLower() ==
"yes" && csharpType.IsValueType)
{
return csharpType.ToString() +
"?";
}
return csharpType.ToString();
}
可以看看动软源代码
三、codeSmith
相关文章推荐
- 黑马程序员_学习日记49_618数据库开发及ADO.Net(多条件搜索、case…when…语句、索引Index、子查询、分页、Join语句)
- 黑马程序员学习日记 (四)面向对象三大特征: 封装 继承 多态
- 黑马程序员-我的第二篇学习日记:C语言中的 if 语句总结
- 黑马程序员_学习日记54_626三层项目(三层案例)
- 黑马程序员_学习日记52_622三层项目(MD5、NPOI)
- 黑马程序员(学习日记2,标识符,常量,变量,运算符,语句)
- 黑马程序员——学习日记之控制语句练习
- Oracle select --lnnvl用于某个语句的where子句中的条件
- sql 自定义函数 ,where后拼接条件跳转语句,实现可变参数查询
- 将带有、号的字符串,以逗号分割,然后拼接为SQL语句的WHERE条件
- Postgresql 存储过程--sql语句的where条件的拼接操作
- 黑马程序员——学习日记7 java面向对象之封装
- 使用反射让linq实现动态查询, 类似拼接sql语句的where 条件
- 黑马程序员_学习日记81_810图书商城项目纪要
- 黑马程序员--Java学习日记之面向对象(封装,this和static,继承)
- 黑马程序员_学习日记82_811图书商城项目纪要
- 黑马程序员_学习日记56_629三层项目(邮件收发、三层总结、HTML)
- 安全化mysql的where条件输入拼接面板:用于给不会mysql语法的操作人使用
- 封装MySQL操作时Where条件语句的组织
- 黑马程序员_学习日记48_616数据库开发及ADO.Net(带参数的Sql语句、数据库与文本文件导入导出、省市联动、资料管理器、DataSet (ado.net断开式数据访问)、SQLHelper)