[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
{
}
}
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; }
}
}
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
1 <!DOCTYPE html>
2 <html xmlns="http://www.w3.org/1999/xhtml">
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>wolfy信息系统登录</title>
6 <script type="text/javascript" src="Scripts/jquery-1.11.0.js"></script>
7 <script type="text/javascript">
8 $(function () {
9 $("#btnLogin").click(function () {
10 var name = $("#txtUserName").val();
11 var pwd = $("#txtPwd").val();
12 $.ajax({
13 url: "Ashx/Login.ashx",
14 data: "name=" + name + "&pwd=" + pwd,
15 type: "Post",
16 dataType: "text",
17 success: function (msg) {
18 if (msg == "1") {
19 $("#divMsg").html("登录成功");
20 } else if(msg=="2") {
21 $("#divMsg").html("用户名或密码为空");
22 } else if(msg=="3"){
23 $("#divMsg").html("用户名不存在");
24 } else {
25 $("#divMsg").html("密码错误");
26 }
27 }
28
29
30 });
31 });
32 });
33 </script>
34 </head>
35 <body>
36 <table>
37 <tr>
38 <td>用户名:</td>
39 <td><input type="text" id="txtUserName" name="name" value="admin" /></td>
40 </tr>
41 <tr>
42 <td>密码:</td>
43 <td><input type="password" id="txtPwd" name="name" value="admin" /></td>
44 </tr>
45 <tr>
46 <td colspan="2"><input type="button" id="btnLogin" name="name" value="登录" /></td>
47 </tr>
48 </table>
49 <div id="divMsg"></div>
50 </body>
51 </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
结果
[c#基础]使用抽象工厂实现三层 和反射的更多相关文章
- [c#基础]使用抽象工厂实现三层
引言 昨天加了一天班,今天闲来无事,就在想如何将之前的三层和最近一直在学的设计模式给联系在一起,然后就动手弄了个下面的小demo. 项目结构 项目各个层实现 Wolfy.Model层中有一个抽象类Ba ...
- .NET重构(一):抽象工厂模式实现登录
导读:一路艰辛,我也走到了重构.在重构之前,师傅让用经典三层(UI.BLL.DAL)敲了登录.用户的增删改查,共五条线.从开始对三层的朦胧,到五条线结束,终于对三层有了逻辑上清晰的理解.然后就画了几天 ...
- 设计模式<2>------工厂模式和抽象工厂模式------创建型
简单工厂: 拿我们的简单三层举例子 先定义dal层 class Dal { public void Delete() { } } 工厂类 class Factory { //这样掉的好处是 当dal层 ...
- C#--抽象工厂设计模式原理
C#--抽象工厂设计模式原理 C#--抽象工厂设计模式--三层框架 C#--使用反射改进简单工厂
- C#设计模式——抽象工厂模式(Abstract Factory Pattern)
一.概述在软件开发中,常常会需要创建一系列相互依赖的对象,同时,由于需求的变化,往往存在较多系列对象的创建工作.如果采用常规的创建方法(new),会造成客户程序和对象创建工作的紧耦合.对此,抽象工厂模 ...
- 设计模式:抽象工厂模式(Abstract Factory)
定 义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 结构图: 示例结构图: 实体类: class User { public int Id { get; set; } p ...
- 设计模式之抽象工厂模式(附带类似反射功能的实现/c++)
问题描述 假设我们要开发一款游戏, 当然为了吸引更多的人玩, 游戏难度不能太大(让大家都没有信心了,估计游戏也就没有前途了),但是也不能太简单(没有挑战性也不符合玩家的心理).于是我们就可以采用这样一 ...
- C#设计模式之:抽象工厂模式与反射
抽象工厂模式[实例]:定义一个用于创建对象的接口,让子类决定实例化哪一个类 UML 代码class User{ private int _id; public int Id { get = ...
- MVC+EF三层+抽象工厂
MVC+EF三层+抽象工厂项目搭建 注意:项目经过两次搭建,所以截图中顶级命名空间有ZHH和ZHH2区别,但是架构的内容是一样的,可以将ZHH和ZHH2视为同一命名空间 一:权限管理 二:搜索 | ...
随机推荐
- 解决javah生成c头文件时找不到android类库的问题
问题描述: cmd下面进入工程的bin/classes下面,执行 javah xxx.xxx.A 生成头文件, 一般来说都是可以成功执行的,但是如果xxx.xxx.A类里面引用了android类库里面 ...
- MySql之视图的使用
一:视图是什么 视图相当于一个窗口,一个基于具体数据库表.定义了相关查询规则 的窗口. 建立视图,可以重用一些复杂的查询语句. 建立视图,相当于定义了一系列查询操作:从视图查询数据,相当于在调用 ...
- (原)pycharm中使用CUDA_VISIBLE_DEVICES
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/8576825.html 如果使用多gpu运行程序,可以直接使用CUDA_VISIBLE_DEVICES= ...
- RabbitMQ ——“Hello World”
介绍 RabbitMQ是一个消息实体服务(broker):它接收及转发消息.你可以把它想象成一个邮局:当你把你想要寄送的邮件放进邮箱里时,你能够确信邮局的派送员最终会把你的这封邮局送到这信的收件者手中 ...
- 3.翻译系列:EF Code-First 示例(EF 6 Code-First系列)
原文链接:http://www.entityframeworktutorial.net/code-first/simple-code-first-example.aspx EF 6 Code-Firs ...
- 设置tomcat 编译文件位置【转】
问题: 将项目发布到tomcat时,发现tomcat的cclasses目录下无任何编译后的文件. 解决方法:设置MyEclipse的文件编译目录即可: http://my.oschina.net/u/ ...
- css table样式
1.table样式首先设置表格边框,属性设置表格的边框是否被合并为一个单一的边框. table{ border-collapse: collapse; border-spacing: 0;} 2.固定 ...
- MemoryFile偷取安卓内存
参考链接:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0111/3859.html MemoryFile memoryFile ...
- 脚本加密http://www.datsi.fi.upm.es/~frosal/sources/
shc的官网下载地址: http://www.datsi.fi.upm.es/~frosal/sources/ 安装: 复制代码 代码如下: tar xzvf shc-.tgz cd shc- mkd ...
- 透彻理解Spring事务设计思想之手写实现
前言 事务,是描述一组操作的抽象,比如对数据库的一组操作,要么全部成功,要么全部失败.事务具有4个特性:Atomicity(原子性),Consistency(一致性),Isolation(隔离性),D ...