[c#基础]使用抽象工厂实现三层
引言
昨天加了一天班,今天闲来无事,就在想如何将之前的三层和最近一直在学的设计模式给联系在一起,然后就动手弄了个下面的小demo。
项目结构

项目各个层实现
Wolfy.Model层中有一个抽象类BaseModel.cs,User.cs是用户实体类,继承与BaseModel类,是用于类型安全考虑的,让各实体类有个统一的父类,在其他层使用的时候,可以使用里氏替换原则的考虑。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.Model
{
/// <summary>
/// 该抽象类为所有实体类的父类,
/// 所有实体类继承该抽象类, 为保持类型一致而设计的父类,也是出于安全性的考虑
/// </summary>
public abstract class BaseModel
{
}
}
BaseModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.Model
{
/// <summary>
/// 实体类user继承自BaseModel
/// 调用时就可以通过BaseModel model=new UserModel();
/// </summary>
public class UserModel : BaseModel
{
public int Id { get; set; }
public string UserName { set; get; }
public string Password { set; get; }
}
}
UserModel
Wolfy.FactoryDAL层是用于反射获取实例,其中只有一个类。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.FactoryDAL
{
public class DataAccess<T> where T : class
{
//获取配置路径
private static readonly string path = System.Configuration.ConfigurationManager.AppSettings["DAL"];
private DataAccess() { }
/// <summary>
/// 创建实例 反射创建实例
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static T CreateDAL(string type)
{
string className = string.Format(path + ".{0}", type);
try
{
return (T)System.Reflection.Assembly.Load(path).CreateInstance(className); }
catch (Exception ex)
{
throw new Exception(ex.Message.ToString());
}
}
}
}
DataAccess
Wolfy.IDAL层依赖与Wolfy.Model,其中包含一个基接口IBaseDAL.cs,还有一个用于定义一些基接口中没有方法的接口IUserDAL,继承基接口IBaseDAL<T>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.IDAL
{
/// <summary>
/// 所有的dal基本都有增删改查等功能,提取到dal接口层,
/// 所有实现该接口的类必须实现所有的未实现的成员
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IBaseDAL<T> where T : Model.BaseModel, new()
{
bool Add(T model);
bool Detele(int ID);
bool Update(T model);
T GetModel(int ID);
}
}
IBaseDAL
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.IDAL
{
/// <summary>
/// 需有特殊的方法的 可定义子接口
/// </summary>
public interface IUserDAL:IBaseDAL<Model.UserModel>
{
/// <summary>
/// 判断用户名是否存在
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
bool Exists(string userName);
/// <summary>
/// 登录
/// </summary>
/// <param name="name"></param>
/// <param name="pwd"></param>
/// <returns></returns>
Model.UserModel Login(string name, string pwd);
}
}
IUserDAL
Wolfy.DAL层,处理数据库的操作。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace Wolfy.DAL
{
public class UserDAL : Wolfy.IDAL.IUserDAL
{
public bool Exists(string userName)
{
string sql = "select count(*) from Users where UserName=@UserName";
SqlParameter[] sp = {
new SqlParameter("@UserName",userName)
}; return (int)SqlHelper.ExecuteScalar(CommandType.Text, sql, sp) > ;
} public bool Add(Model.UserModel model)
{
string sql = "insert into Users values(@UserName,@UserPwd)";
SqlParameter[] sp = {
new SqlParameter("@UserName",model.UserName),
new SqlParameter("@UserName",model.Password)
};
return SqlHelper.ExecuteNonQuery(CommandType.Text, sql, sp) > ;
} public bool Detele(int ID)
{
string sql = "delete from Users where id=" + ID;
return SqlHelper.ExecuteNonQuery(CommandType.Text, sql) > ;
} public bool Update(Model.UserModel model)
{
string sql = string.Format("update Users set UserName={0},UserPwd={1} where id={2}", model.UserName, model.Password, model.Id);
return SqlHelper.ExecuteNonQuery(CommandType.Text, sql) > ;
} public Model.UserModel GetModel(int ID)
{
string sql = "select * from Users where id=" + ID;
DataTable dt = SqlHelper.ExecuteDataTable(sql);
if (dt != null && dt.Rows.Count > )
{
return new Model.UserModel() { UserName = dt.Rows[]["UserName"].ToString(), Password = dt.Rows[]["UserPwd"].ToString() };
}
else
{
return null;
}
} public Model.UserModel Login(string name, string pwd)
{
Model.UserModel model = null;
string sql = "select * from Users where UserName=@UserName and UserPwd=@UserPwd";
SqlParameter[] sp = {
new SqlParameter("@UserName",name),
new SqlParameter("@UserPwd",pwd)
};
SqlDataReader reader = SqlHelper.ExecuteReader(CommandType.Text, sql, sp);
if (reader != null && !reader.IsClosed && reader.HasRows)
{
model = new Model.UserModel();
while (reader.Read())
{
model.Id = Convert.ToInt32(reader[]);
model.UserName = reader[].ToString();
model.Password = reader[].ToString();
}
}
reader.Dispose();
return model;
}
}
}
UserDAL
using System;
using System.Data;
using System.Xml;
using System.Data.SqlClient;
using System.Collections;
using System.Configuration;
using System.IO;
using System.Web; namespace Wolfy.DAL
{
/// <summary>
/// 数据库的通用访问代码
/// 此类为抽象类,不允许实例化,在应用时直接调用即可
/// </summary>
public abstract class SqlHelper
{
//获取数据库连接字符串,其属于静态变量且只读,项目中所有文档可以直接使用,但不能修改
public static readonly string connectionString = ConfigurationManager.ConnectionStrings["SqlConnect"].ConnectionString; // 哈希表用来存储缓存的参数信息,哈希表可以存储任意类型的参数。
private static Hashtable parmCache = Hashtable.Synchronized(new Hashtable()); /// <summary>
///执行一个不需要返回值的SqlCommand命令,通过指定专用的连接字符串。
/// 使用参数数组形式提供参数列表
/// </summary>
/// <remarks>
/// 使用示例:
/// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connectionString">一个有效的数据库连接字符串</param>
/// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
/// <param name="commandText">存储过程的名字或者 T-SQL 语句</param>
/// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
/// <returns>返回一个数值表示此SqlCommand命令执行后影响的行数</returns>
public static int ExecuteNonQuery(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
using (SqlConnection conn = new SqlConnection(connectionString))
{
//通过PrePareCommand方法将参数逐个加入到SqlCommand的参数集合中
PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
//清空SqlCommand中的参数列表
cmd.Parameters.Clear();
return val;
}
} /// <summary>
///执行一条不返回结果的SqlCommand,通过一个已经存在的数据库连接
/// 使用参数数组提供参数
/// </summary>
/// <remarks>
/// 使用示例:
/// int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="conn">一个现有的数据库连接</param>
/// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
/// <param name="commandText">存储过程的名字或者 T-SQL 语句</param>
/// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
/// <returns>返回一个数值表示此SqlCommand命令执行后影响的行数</returns>
public static int ExecuteNonQuery(SqlConnection connection, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
} /// <summary>
/// 执行一条不返回结果的SqlCommand,通过一个已经存在的数据库事物处理
/// 使用参数数组提供参数
/// </summary>
/// <remarks>
/// 使用示例:
/// int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="trans">一个存在的 sql 事物处理</param>
/// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
/// <param name="commandText">存储过程的名字或者 T-SQL 语句</param>
/// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
/// <returns>返回一个数值表示此SqlCommand命令执行后影响的行数</returns>
public static int ExecuteNonQuery(SqlTransaction trans, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd, trans.Connection, trans, cmdType, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
} /// <summary>
/// 执行一条返回结果集的SqlCommand命令,通过专用的连接字符串。
/// 使用参数数组提供参数
/// </summary>
/// <remarks>
/// 使用示例:
/// SqlDataReader r = ExecuteReader(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connectionString">一个有效的数据库连接字符串</param>
/// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
/// <param name="commandText">存储过程的名字或者 T-SQL 语句</param>
/// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
/// <returns>返回一个包含结果的SqlDataReader</returns>
public static SqlDataReader ExecuteReader(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
SqlConnection conn = new SqlConnection(connectionString);
// 在这里使用try/catch处理是因为如果方法出现异常,则SqlDataReader就不存在,
//CommandBehavior.CloseConnection的语句就不会执行,触发的异常由catch捕获。
//关闭数据库连接,并通过throw再次引发捕捉到的异常。
try
{
PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
cmd.Parameters.Clear();
return rdr;
}
catch
{
conn.Close();
throw;
}
} /// <summary>
/// 执行一条返回第一条记录第一列的SqlCommand命令,通过专用的连接字符串。
/// 使用参数数组提供参数
/// </summary>
/// <remarks>
/// 使用示例:
/// Object obj = ExecuteScalar(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connectionString">一个有效的数据库连接字符串</param>
/// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
/// <param name="commandText">存储过程的名字或者 T-SQL 语句</param>
/// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
/// <returns>返回一个object类型的数据,可以通过 Convert.To{Type}方法转换类型</returns>
public static object ExecuteScalar(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
using (SqlConnection connection = new SqlConnection(connectionString))
{
PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters);
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
return val;
}
} /// <summary>
/// 执行一条返回第一条记录第一列的SqlCommand命令,通过已经存在的数据库连接。
/// 使用参数数组提供参数
/// </summary>
/// <remarks>
/// 使用示例:
/// Object obj = ExecuteScalar(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="conn">一个已经存在的数据库连接</param>
/// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
/// <param name="commandText">存储过程的名字或者 T-SQL 语句</param>
/// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
/// <returns>返回一个object类型的数据,可以通过 Convert.To{Type}方法转换类型</returns>
public static object ExecuteScalar(SqlConnection connection, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters);
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
return val;
} /// <summary>
/// 缓存参数数组
/// </summary>
/// <param name="cacheKey">参数缓存的键值</param>
/// <param name="cmdParms">被缓存的参数列表</param>
public static void CacheParameters(string cacheKey, params SqlParameter[] commandParameters)
{
parmCache[cacheKey] = commandParameters;
} /// <summary>
/// 获取被缓存的参数
/// </summary>
/// <param name="cacheKey">用于查找参数的KEY值</param>
/// <returns>返回缓存的参数数组</returns>
public static SqlParameter[] GetCachedParameters(string cacheKey)
{
SqlParameter[] cachedParms = (SqlParameter[])parmCache[cacheKey];
if (cachedParms == null)
return null;
//新建一个参数的克隆列表
SqlParameter[] clonedParms = new SqlParameter[cachedParms.Length];
//通过循环为克隆参数列表赋值
for (int i = , j = cachedParms.Length; i < j; i++)
//使用clone方法复制参数列表中的参数
clonedParms[i] = (SqlParameter)((ICloneable)cachedParms[i]).Clone();
return clonedParms;
} /// <summary>
/// 为执行命令准备参数
/// </summary>
/// <param name="cmd">SqlCommand 命令</param>
/// <param name="conn">已经存在的数据库连接</param>
/// <param name="trans">数据库事物处理</param>
/// <param name="cmdType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
/// <param name="cmdText">Command text,T-SQL语句 例如 Select * from Products</param>
/// <param name="cmdParms">返回带参数的命令</param>
private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms)
{
//判断数据库连接状态
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Connection = conn;
cmd.CommandText = cmdText;
//判断是否需要事物处理
if (trans != null)
cmd.Transaction = trans;
cmd.CommandType = cmdType;
if (cmdParms != null)
{
foreach (SqlParameter parm in cmdParms)
cmd.Parameters.Add(parm);
}
} /// <summary>
/// 获取dataset数据
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
public static DataTable ExecuteDataTable(string sql)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
DataTable dst = new DataTable();
da.Fill(dst);
return dst;
}
}
}
}
SqlHelper
Wolfy.BLL业务逻辑层中包含了一个用于继承的基类BaseBLL<T>和用户业务逻辑UserBLL类,这层依赖Wolfy.IDAL,Wolfy.Model,Wolfy.FactoryDAL库
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.BLL
{
public class BaseBLL<T> where T : Wolfy.Model.UserModel, new()
{
protected Wolfy.IDAL.IBaseDAL<T> Dal;
public BaseBLL(string type)
{
//通过工厂得到 dal
Dal = Wolfy.FactoryDAL.DataAccess<Wolfy.IDAL.IBaseDAL<T>>.CreateDAL(type);
}
public virtual bool Add(T model)
{
return Dal.Add(model);
}
public virtual bool Delete(int ID)
{ return Dal.Detele(ID); }
public virtual bool Update(T model)
{ return Dal.Update(model); }
public virtual T GetModel(int ID)
{
return Dal.GetModel(ID);
} }
}
BaseBLL
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.BLL
{
public class UserBLL : BaseBLL<Wolfy.Model.UserModel>
{
private const string _Type = "UserDAL";
private Wolfy.IDAL.IUserDAL _DAL;
public UserBLL()
: base(_Type)
{
_DAL = base.Dal as Wolfy.IDAL.IUserDAL;
if (_DAL == null)
{
throw new NullReferenceException(_Type);
}
}
public bool Exists(string userName)
{
return _DAL.Exists(userName);
}
public Model.UserModel Login(string name, string pwd)
{ return _DAL.Login(name, pwd); }
}
}
UserBLL
web.config程序集名称,连接字符串配置
<?xml version="1.0" encoding="utf-8"?>
<!--
有关如何配置 ASP.NET 应用程序的详细信息,请访问
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" /> </system.web>
<connectionStrings>
<add name="SqlConnect" connectionString="server=.;database=Test;uid=sa;pwd=sa"/>
</connectionStrings>
<appSettings>
<add key="DAL" value="Wolfy.DAL"/>
</appSettings>
</configuration>
web.config
测试
简单的ajax登录,web项目需引用Wolfy.BLL.dll和Wolfy.Model.dll和Wolfy.DAL.dll
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>wolfy信息系统登录</title>
<script type="text/javascript" src="Scripts/jquery-1.11.0.js"></script>
<script type="text/javascript">
$(function () {
$("#btnLogin").click(function () {
var name = $("#txtUserName").val();
var pwd = $("#txtPwd").val();
$.ajax({
url: "Ashx/Login.ashx",
data: "name=" + name + "&pwd=" + pwd,
type: "Post",
dataType: "text",
success: function (msg) {
if (msg == "1") {
$("#divMsg").html("登录成功");
} else if(msg=="2") {
$("#divMsg").html("用户名或密码为空");
} else if(msg=="3"){
$("#divMsg").html("用户名不存在");
} else {
$("#divMsg").html("密码错误");
}
} });
});
});
</script>
</head>
<body>
<table>
<tr>
<td>用户名:</td>
<td><input type="text" id="txtUserName" name="name" value="admin" /></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" id="txtPwd" name="name" value="admin" /></td>
</tr>
<tr>
<td colspan="2"><input type="button" id="btnLogin" name="name" value="登录" /></td>
</tr>
</table>
<div id="divMsg"></div>
</body>
</html>
Login.html
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace Wolfy.LoginDemo.Ashx
{
/// <summary>
/// Login 的摘要说明
/// </summary>
public class Login : IHttpHandler
{ public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
//接收用户名和密码
string name = context.Request["name"];
string pwd = context.Request["pwd"];
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pwd))
{
context.Response.Write("");
}
else
{
BLL.UserBLL bll = new BLL.UserBLL();
Model.UserModel model = new Model.UserModel();
if (!bll.Exists(name))
{
context.Response.Write("");
}
else
{
model = bll.Login(name, pwd);
if (model != null)
{
//登录成功记入cookie
context.Response.Cookies["n"].Value = name;
context.Response.Cookies["n"].Expires = DateTime.Now.AddDays();
context.Response.Cookies["p"].Value = pwd;
context.Response.Cookies["p"].Expires = DateTime.Now.AddDays();
context.Response.Write("");
}
} }
} public bool IsReusable
{
get
{
return false;
}
}
}
}
Login.ashx
结果
源码下载:http://pan.baidu.com/s/1hqqSUrU
总结
参考文章:http://www.cnblogs.com/cmsdn/p/3494461.html
参考着这篇文章,敲了一遍,实践了一下。在博客园,虽然有很多提供代码的园友,但是自己动手实践一下,就可以发现其中好与不好的地方,也可以加深理解。
[c#基础]使用抽象工厂实现三层的更多相关文章
- [c#基础]使用抽象工厂实现三层 和反射
引言 昨天加了一天班,今天闲来无事,就在想如何将之前的三层和最近一直在学的设计模式给联系在一起,然后就动手弄了个下面的小demo. 项目结构 项目各个层实现 Wolfy.Model层中有一个抽象类Ba ...
- .NET重构(一):抽象工厂模式实现登录
导读:一路艰辛,我也走到了重构.在重构之前,师傅让用经典三层(UI.BLL.DAL)敲了登录.用户的增删改查,共五条线.从开始对三层的朦胧,到五条线结束,终于对三层有了逻辑上清晰的理解.然后就画了几天 ...
- C#--抽象工厂设计模式原理
C#--抽象工厂设计模式原理 C#--抽象工厂设计模式--三层框架 C#--使用反射改进简单工厂
- MVC+EF三层+抽象工厂
MVC+EF三层+抽象工厂项目搭建 注意:项目经过两次搭建,所以截图中顶级命名空间有ZHH和ZHH2区别,但是架构的内容是一样的,可以将ZHH和ZHH2视为同一命名空间 一:权限管理 二:搜索 | ...
- MVC基础知识 – 1.抽象工厂模式
1.调用规则 2.简单工厂 问题:在List.aspx里怎么new一个业务层? 2.1.再在 02SBLL 解决方案里建一个类库 BLL_Tow,也有一个 Users.cs 2.2.建立一个工厂 2. ...
- .NET抽象工厂模式微理解--教你在项目中实现抽象工厂
.NET抽象工厂模式微理解--教你在项目中实现抽象工厂 最近在学习MVC,对于MVC里面的一些项目上的东西都和抽象模式有关,今天就微说明一下个人对于抽象工厂模式的理解,以方便学习MVC及工厂模式相关的 ...
- OC编程之道-创建对象之抽象工厂方法
定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类. <AbstractProductA> <AbstractProductB> <Ab ...
- .NET设计模式(2):1.2 抽象工厂模式(Abstract Factory)
概述 抽象工厂模式(Abstract Factory)是所有形态的工厂模式中最为抽象和最具一般性的一种形态.抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口 ...
- 设计模式可复用面向对象软件设计基础之对象创建型模式—ABSTRACT FACTORY( 抽象工厂)
意图 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 适用性 在以下情况可以使用 Abstract Factory模式 • 一个系统要独立于它的产品的创建.组合和表示时. • 一 ...
随机推荐
- 简约而不简单的Django
本文面向:有python基础,刚接触web框架的初学者. 环境:windows7 python3.5.1 pycharm专业版 Django 1.10版 pip3 一.Django简介 百度百 ...
- freemarker模板引擎的使用
freemarker是一套前端模板引擎,在使用时,要先在web项目中添加freemarker.jar的依赖. 我在这里主要演示spring-mvc整合freemarker模板引擎.项目案例的文件包结构 ...
- Groovy 与 DSL
一:DSL 概念 指的是用于一个特定领域的语言(功能领域.业务领域).在这个给出的概念中有 3个重点: 只用于一个特定领域,而非所有通用领域,比如 Java / C++就是用于通用领域,而不可被称为 ...
- MVC – 4.mvc初体验(2)
5.显示学员列表 效果 数据表 5.1 首先,在文件夹Models新建一个新建项(W),选择ADO.NET 实体数据模型 (SingleTest.edmx) 5.2 建一个控制器,StudentsCo ...
- PyQt5点击按钮产生新窗体
import sys from PyQt5.QtWidgets import QApplication,QWidget from form1 import Ui_Form1 from form2 im ...
- 微软企业库5.0 学习之路——扩展学习篇、库中的依赖关系注入(重构 Microsoft Enterprise Library)[转]
这篇文章是我在patterns & practices看到的一篇有关EntLib5.0的文章,主要介绍了EntLib5.0的这次的架构变化由来,觉得很不错,大家可以看一下! 在过去几年中,依赖 ...
- 使用FlashPaper在线转换.doc为.swf_实用技巧
https://yq.aliyun.com/ziliao/160044?spm=5176.8246799.0.0.JBbqjY 摘要: 本文讲的是使用FlashPaper在线转换.doc为.swf_实 ...
- 长沙理工大学第十二届ACM大赛-重现赛 L - 选择困难症
题目描述 小L有严重的选择困难症. 早上起床后,需要花很长时间决定今天穿什么出门. 假设一共有k类物品需要搭配选择,每类物品的个数为Ai,每个物品有一个喜欢值Vj,代表小L对这件物品的喜欢程度. 小L ...
- SpringMVC框架 之 from标签(转)
原文地址:http://blog.csdn.net/kutim/article/details/46682547 spring表单标签 <%@taglib uri="http:// ...
- Arduino可穿戴教程之第一个程序——Blink(一)
Arduino可穿戴教程之第一个程序——Blink(一) 至此我们的硬件和软件部分都准备好了,是时候测试一下他们是否可以和谐地合作了.当然,第一个程序我们并不需要自己来写,因为我们还没有了解过Ardu ...