以一个权限系统来告别WebForm —(一)项目整休架构设计与数据库设计
在本节我想与大家与分享一下,我所将要做的权限系统的架构和数据库的表的设计。请各位大神们对我项目中设计的不足之处进行指导,让我得以更好的写完它,留给需要它的人。
我的项目架构如下图所示:
如上图所示,在数据访问层,我采用了抽象工厂的方式,来对数据访问层和业务逻辑层解耦,当然如果你想更高大上一些,可以用第三方的框架,比如Spring.Net ,Autofac来实现。解耦的好处在于可以方便的切换数据库,当数据库变更时,只需换一下对应的数据访问DAL就行,本系列中,我所采用的是SQLServer。写到这我想在如下这个大数据时代,MongoDB其实也是不错的。后面有机会,可以开一个MongoDB的专题和大家一起来使用一下MongoDB学习一下它。对于抽象工厂来实现业务逻辑层与数据访问层的解耦实现代码如下,主要用到了反射,面向接口编程。
配置:
<appSettings> <add key="DAL" value="MCFramework.SQLDAL"/> <!--页容量-->
<add key="PageSize" value=""/> </appSettings>
抽象工厂:
namespace MCFramework.RepositoryFactory
{
public class RepositoryFactory
{
public RepositoryFactory()
{ } private static readonly string AssemblyPath =ConfigurationSettings.AppSettings["DAL"]; #region CreateObject //不使用缓存
private static object CreateObjectNoCache(string AssemblyPath, string classNamespace)
{
try
{
object objType = Assembly.Load(AssemblyPath).CreateInstance(classNamespace);
return objType;
}
catch(System.Exception ex)
{
string str=ex.StackTrace;// 记录错误日志
return null;
} }
//使用缓存
//private static object CreateObject(string AssemblyPath, string classNamespace)
//{
// object objType = DataCache.GetCache(classNamespace);
// if (objType == null)
// {
// try
// {
// objType = Assembly.Load(AssemblyPath).CreateInstance(classNamespace);
// DataCache.SetCache(classNamespace, objType);// 写入缓存
// }
// catch//(System.Exception ex)
// {
// //string str=ex.Message;// 记录错误日志
// }
// }
// return objType;
//}
#endregion /// <summary>
/// 用户仓储
/// </summary>
public static ISystem_EmployeeRepository System_EmployeeRepository { get { return (ISystem_EmployeeRepository)CreateObjectNoCache(AssemblyPath, AssemblyPath + ".System_EmployeeRepository"); } } /// <summary>
///菜单仓储
/// </summary>
public static ISystem_MenuRepository System_MenuRepository { get { return (ISystem_MenuRepository)CreateObjectNoCache(AssemblyPath, AssemblyPath + ".System_MenuRepository"); } } /// <summary>
///角色仓储
/// </summary>
public static ISystem_RoleRepository System_RoleRepository { get { return (ISystem_RoleRepository)CreateObjectNoCache(AssemblyPath, AssemblyPath + ".System_RoleRepository"); } } /// <summary>
///按钮仓储
/// </summary>
public static ISystem_ButtonRepository System_ButtonRepository { get { return (ISystem_ButtonRepository)CreateObjectNoCache(AssemblyPath, AssemblyPath + ".System_ButtonRepository"); } } }
}
所有的访问数据库的操作都用接口来约束:
namespace MCFramework.IDAL
{
public interface IBaseRepository<T> where T:class
{
int Add(T model); int UpdateDel(string ids, bool isDel); int Del(string ids); int Update(T model); DataSet GetListByProc(string procName, System.Data.SqlClient.SqlParameter[] paras); DataSet GetModel(string Id); DataSet GetList(string strWhere); }
}
namespace MCFramework.IDAL
{
public interface ISystem_ButtonRepository:IBaseRepository<System_ButtonModel>
{
bool IsExit(string ButtonCode);
}
}
接口的实现:
namespace MCFramework.SQLDAL
{
/// <summary>
/// Author: MaChun
/// Description: DALTier -- the DAL class of System_Button.
/// Datetime:2015/6/8 13:00:35
/// </summary>
public class BaseSystem_ButtonRepository: IBaseRepository<System_ButtonModel>
{ //创建企业库连接
public SqlDataAccess db = SqlDataAccess.CreateDataAccess(); #region 新增一条记录 Add(System_ButtonModel model)
/// <summary>
/// 新增一条记录
/// </summary>
public int Add(System_ButtonModel model)
{
int result = ;
try
{ StringBuilder strSql = new StringBuilder();
strSql.Append("insert into System_Button(");
strSql.Append("SBT_Guid,SBT_ButtonCode,SBT_ButtonName,SBT_IconUrl,SBT_IconCss,SBT_CreateBy,SBT_CreatedDate)");
strSql.Append(" values (");
strSql.Append("@SBT_Guid,@SBT_ButtonCode,@SBT_ButtonName,@SBT_IconUrl,@SBT_IconCss,@SBT_CreateBy,@SBT_CreatedDate)");
strSql.Append(";select @@IDENTITY");
SqlParameter[] parameters = {
new SqlParameter("@SBT_Guid", SqlDbType.VarChar,),
new SqlParameter("@SBT_ButtonCode", SqlDbType.VarChar,),
new SqlParameter("@SBT_ButtonName", SqlDbType.VarChar,),
new SqlParameter("@SBT_IconUrl", SqlDbType.VarChar,),
new SqlParameter("@SBT_IconCss", SqlDbType.VarChar,),
new SqlParameter("@SBT_CreateBy", SqlDbType.VarChar,),
new SqlParameter("@SBT_CreatedDate", SqlDbType.DateTime,)};
parameters[].Value = model.SBTGuid;
parameters[].Value = model.SBTButtonCode;
parameters[].Value = model.SBTButtonName;
parameters[].Value = model.SBTIconUrl;
parameters[].Value = model.SBTIconCss;
parameters[].Value = model.SBTCreateBy;
parameters[].Value = model.SBTCreatedDate; result = db.ExecuteNonQuery(strSql.ToString(), parameters);
}
catch (Exception ex)
{
throw ex;
}
return result;
}
#endregion #region 逻辑删除 UpdateDel(string ids, bool isDel)
/// <summary>
/// 逻辑删除
/// </summary>
public int UpdateDel(string ids, bool isDel)
{ StringBuilder strSql = new StringBuilder();
strSql.Append("update System_Button set noDelKey='" + isDel.ToString() + "' where SBT_Guid in (" + ids + ")"); return db.ExecuteNonQuery(strSql.ToString());
}
#endregion #region 物理删除 Del(string id)
/// <summary>
/// 物理删除
/// </summary>
public int Del(string id)
{ StringBuilder strSql = new StringBuilder();
strSql.Append("delete System_Button where SBT_Guid ='"+id+"' ");
return db.ExecuteNonQuery(strSql.ToString());
}
#endregion #region 修改记录 Update(System_ButtonModel model)
/// <summary>
/// 修改记录
/// </summary>
public int Update(System_ButtonModel model)
{
int res = -;
StringBuilder strSql = new StringBuilder();
strSql.Append("update System_Button set ");
strSql.Append("SBT_ButtonCode=@SBT_ButtonCode,");
strSql.Append("SBT_ButtonName=@SBT_ButtonName,");
strSql.Append("SBT_IconUrl=@SBT_IconUrl,");
strSql.Append("SBT_IconCss=@SBT_IconCss,");
strSql.Append("SBT_CreateBy=@SBT_CreateBy,");
strSql.Append("SBT_CreatedDate=@SBT_CreatedDate");
strSql.Append(" where SBT_Guid=@SBT_Guid ");
SqlParameter[] parameters = {
new SqlParameter("@SBT_Guid", SqlDbType.VarChar,),
new SqlParameter("@SBT_ButtonCode", SqlDbType.VarChar,),
new SqlParameter("@SBT_ButtonName", SqlDbType.VarChar,),
new SqlParameter("@SBT_IconUrl", SqlDbType.VarChar,),
new SqlParameter("@SBT_IconCss", SqlDbType.VarChar,),
new SqlParameter("@SBT_CreateBy", SqlDbType.VarChar,),
new SqlParameter("@SBT_CreatedDate", SqlDbType.DateTime,)};
parameters[].Value = model.SBTGuid;
parameters[].Value = model.SBTButtonCode;
parameters[].Value = model.SBTButtonName;
parameters[].Value = model.SBTIconUrl;
parameters[].Value = model.SBTIconCss;
parameters[].Value = model.SBTCreateBy;
parameters[].Value = model.SBTCreatedDate; try
{
res = db.ExecuteNonQuery(strSql.ToString(), parameters);
}
catch (Exception ex)
{
throw ex;
}
finally { }
return res;
}
#endregion #region 根据主键查询出DataSet GetModel(string Id)
/// <summary>
/// 根据主键查询出DataSet
/// </summary>
public DataSet GetModel(string Id)
{ StringBuilder strSql = new StringBuilder();
strSql.Append("select SBT_Guid,SBT_ButtonCode,SBT_ButtonName,SBT_IconUrl,SBT_IconCss,SBT_CreateBy,SBT_CreatedDate from System_Button ");
strSql.Append(" where SBT_Guid=@SBT_Guid ");
SqlParameter[] parameters = {
new SqlParameter("@SBT_Guid", SqlDbType.Char,)};
parameters[].Value = Id; DataSet ds = db.ExecuteDataSet(strSql.ToString(), parameters); return ds;
} #endregion #region 根据where 条件查询出DataSet GetList(string strWhere)
/// <summary>
/// 根据where 条件查询出DataSet
/// </summary>
public DataSet GetList(string strWhere)
{ StringBuilder strSql = new StringBuilder();
strSql.Append("select SBT_Guid,SBT_ButtonCode,SBT_ButtonName,SBT_IconUrl,SBT_IconCss,SBT_CreateBy,SBT_CreatedDate ");
strSql.Append(" FROM System_Button ");
if (strWhere.Trim() != "")
{
strSql.Append(" where " + strWhere);
} DataSet ds = db.ExecuteDataSet(strSql.ToString()); return ds;
}
#endregion #region 根据存储过程查询出DataSet GetListByProc(string procName,SqlParameter[] paras)
/// <summary>
///根据存储过程查询出DataSet
/// </summary>
/// <param name="procName">procName</param>
/// <param name="paras">paras</param>
public DataSet GetListByProc(string procName,SqlParameter[] paras)
{ DataSet ds = db.ExecuteDataSet(procName, paras); return ds;
}
#endregion }
}
namespace MCFramework.SQLDAL
{
/// <summary>
/// Author: MaChun
/// Description: DALTier -- the DAL class of System_Button.
/// Datetime:2015/4/20 16:01:42
/// </summary>
public class System_ButtonRepository:BaseSystem_ButtonRepository,ISystem_ButtonRepository
{ public bool IsExit(string ButtonCode)
{
bool flag = false;
string sql = string.Format(@"SELECT * FROM dbo.System_Button WHERE SBT_ButtonCode='{0}'", ButtonCode);
DataSet ds = db.ExecuteDataSet(sql);
if (ds.Tables.Count > )
{
flag = ds.Tables[].Rows.Count > ;
} return flag;
}
}
}
数据访问层操作数据库我没有用ORM框架,用的是传统的ADO.Net,我个人觉得这样可控性会更好,也利于以后的优化。
业务逻辑层的调用:
namespace MCFramework.BLL
{
/// <summary>
/// Author: MaChun
/// Description: BLLTier -- the BLL class of System_Button.
/// Datetime:2015/5/6 17:00:35
/// </summary>
public class BaseSystem_ButtonService
{
protected static readonly ISystem_ButtonRepository dal = RepositoryFactory.RepositoryFactory.System_ButtonRepository; #region 新增一条记录 Add(System_ButtonModel model)
/// <summary>
/// 新增一条记录
/// </summary>
public int Add(System_ButtonModel model)
{
return dal.Add(model);
}
#endregion #region 根据ID 逻辑删除一条记录 UpdateDel(string ids, bool isDel)
/// <summary>
/// 根据ID 逻辑删除一条记录
/// </summary>
public int UpdateDel(string ids, bool isDel)
{
return dal.UpdateDel(ids, isDel);
}
#endregion #region 根据ID物理删除一条记录 Del(string id)
/// <summary>
/// 根据ID物理删除一条记录
/// </summary>
public int Del(string id)
{
return dal.Del(id);
}
#endregion #region 更新一条记录 Update(System_ButtonModel model)
/// <summary>
/// 更新一条记录
/// </summary>
public int Update(System_ButtonModel model)
{
return dal.Update(model);
}
#endregion #region 根据存储过程来查询返回一个list 集合 GetListByProc
/// <summary>
///根据存储过程来查询返回一个list 集合
/// </summary>
/// <param name="procName">procName</param>
/// <param name="paras">paras</param>
public List<System_ButtonModel> GetListByProc(string procName,System.Data.SqlClient.SqlParameter[] paras)
{
DataTable dt= dal.GetListByProc(procName,paras).Tables[]; List<System_ButtonModel> list = null;
list = new List<System_ButtonModel>();
LoadListData(ref list, dt);
if (list.Count > )
{
return list;
}
else
{
return null;
}
}
#endregion #region 根据主键来查询得到一个实体 GetModel(string Id)
/// <summary>
/// 根据主键来查询得到一个实体
/// </summary>
public System_ButtonModel GetModel(string Id)
{ DataTable dt= dal.GetModel(Id).Tables[]; System_ButtonModel model = new System_ButtonModel();
if (dt.Rows.Count > )
{
LoadEntityData(ref model, dt.Rows[]);
return model;
}
else
{
return null;
}
}
#endregion #region 根据 where 条件来查询得到一个list集合 GetList(string strWhere)
/// <summary>
/// 根据 where 条件来查询得到一个list集合
/// </summary>
public List<System_ButtonModel> GetList(string strWhere)
{
DataTable dt= dal.GetList(strWhere).Tables[]; List<System_ButtonModel> list = null;
list = new List<System_ButtonModel>();
LoadListData(ref list, dt);
if (list.Count > )
{
return list;
}
else
{
return null;
} }
#endregion #region 将DataTable转换为 List 对象集合 LoadListData
/// <summary>
/// 将DataTable转换为 List 对象集合
/// </summary>
/// <param name="list">GenericList</param>
/// <param name="dt">DataTable</param>
public void LoadListData(ref List<System_ButtonModel> list, DataTable dt)
{
if (dt.Rows.Count > )
{
System_ButtonModel model;
foreach (DataRow dr in dt.Rows)
{
model = new System_ButtonModel();
LoadEntityData(ref model, dr);
list.Add(model);
}
}
}
#endregion #region 将Datatable中的Dr 转换成 Model 实体 LoadEntityData
/// <summary>
/// 将Datatable中的Dr 转换成 Model 实体
/// </summary>
/// <param name="model">Entity</param>
/// <param name="dr">DataRow</param>
public void LoadEntityData(ref System_ButtonModel model, DataRow dr)
{
model.SBTGuid = dr["SBT_Guid"].ToString();
model.SBTButtonCode = dr["SBT_ButtonCode"].ToString();
model.SBTButtonName = dr["SBT_ButtonName"].ToString();
model.SBTIconUrl = dr["SBT_IconUrl"].ToString();
model.SBTIconCss = dr["SBT_IconCss"].ToString();
model.SBTCreateBy = dr["SBT_CreateBy"].ToString();
if (dr["SBT_CreatedDate"].ToString() != "")
{
model.SBTCreatedDate = DateTime.Parse(dr["SBT_CreatedDate"].ToString());
} }
#endregion }
}
public class System_ButtonService:BaseSystem_ButtonService
{ #region 单例模式 private System_ButtonService()
{
} private static readonly System_ButtonService instance = new System_ButtonService(); public static System_ButtonService Instance
{
get { return instance; }
} #endregion public bool IsExit(string ButtonCode)
{ return dal.IsExit(ButtonCode);
}
}
}
对于,业务层到UI层之间的解耦,我没有按架构图中的去实现,我觉在一般中的项目中没有这个必要,为了简化 ,我所以省去了,如果你想加上,完全可以按抽象工厂的方式加上。以上就是我对整个项目的架构上做的一个说明。接下来我们再看看我数据库的设计。
权限的细化颗粒度到各页面的按钮。对于以上的架构和表设计,如果有什么好的建议可以给我留言。下一节,我们将完成主页面的主休框架和登录验证。
以一个权限系统来告别WebForm —(一)项目整休架构设计与数据库设计的更多相关文章
- 以一个权限系统来告别WebForm —开篇
前言: 当今是互联网的时代,我们己经阻止不了它的发展了,只有跟上脚步,才不会被抛弃,松散了这么久,该紧紧了. 背景: 我之所以说以一个权限应用系统来告别我的WebForm内部系统的生涯,是缘于我自 ...
- 转:RBAC如何设计一个权限系统
前言 权限管理是所有后台系统的都会涉及的一个重要组成部分,主要目的是对不同的人访问资源进行权限的控制,避免因权限控制缺失或操作不当引发的风险问题,如操作错误,隐私数据泄露等问题.目前在公司负责权限这块 ...
- Java秒杀系统实战系列~整体业务流程介绍与数据库设计
摘要: 本篇博文是“Java秒杀系统实战系列文章”的第三篇,本篇博文将主要介绍秒杀系统的整体业务流程,并根据相应的业务流程进行数据库设计,最终采用Mybatis逆向工程生成相应的实体类Entity.操 ...
- AngularJs打造一个简易权限系统
AngularJs打造一个简易权限系统 一.引言 上一篇博文已经向大家介绍了AngularJS核心的一些知识点,在这篇博文将介绍如何把AngularJs应用到实际项目中.本篇博文将使用AngularJ ...
- Spring Security和 JWT两大利器来打造一个简易的权限系统。
写在前面 关于 Spring Security Web系统的认证和权限模块也算是一个系统的基础设施了,几乎任何的互联网服务都会涉及到这方面的要求.在Java EE领域,成熟的安全框架解决方案一般有 A ...
- [后端人员耍前端系列]AngularJs篇:使用AngularJs打造一个简易权限系统
一.引言 上一篇博文已经向大家介绍了AngularJS核心的一些知识点,在这篇博文将介绍如何把AngularJs应用到实际项目中.本篇博文将使用AngularJS来打造一个简易的权限管理系统.下面不多 ...
- phpcms中的RBAC权限系统
PHPCMS中的RBAC权限系统主要用到了4张数据表:管理员表,角色表,菜单表,菜单权限表.先来看看数据库的数据表结构: admin 管理员表 ID 字段 类型 Null 默认 索引 额外 注释 1 ...
- 高校手机签到系统——第一部分Authority权限系统(下)
很抱歉,之前寝室光纤断了,所以到现在才更新这个系列的第二篇博客.点击访问高校手机签到系统——第一部分Authority权限系统(上) 这几天我反思了一下上一篇写博上的方式,一味的贴代码式的,是否应该更 ...
- ubuntu chmod 无法更改 文件夹权限 系统提示“不允许的操作 2、linux 如何修改只读文件 3、ubuntu安装
1.ubuntu chmod 无法更改 文件夹权限 系统提示“不允许的操作 答案:需要超级用户权限 sudo 2.linux 如何修改只读文件 答案:可以使用chmod命令,为改文件提供其他的权限.u ...
随机推荐
- POJ 1182 食物链
G - 食物链 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit Stat ...
- LUA GC 简单测试
function table.count(t) if type(t) ~= "table" then assert(false) return end for k, _ in pa ...
- IP+IDC-chinaz抓取
#-*-coding:gbk-*- #code by anyun.org import urllib import re import time def getHtml(url): page = ur ...
- 设计模式——1.概述&UML类图和时序图
声明:本博客设计模式相关文章均整理和修改自网络,原文地址:图说设计模式 学习设计模式的3个层次—— 1.熟悉所有设计模式: 2.能够用代码实现: 3.运用到工作的项目中. 设计模式指导软件开发,学习设 ...
- 使用JQuery能做什么(zz)
jQuery库为Web脚本编程提供了通用(跨浏览器)的抽象层,使得它几乎适用于任何脚本编程的情形.jQuery通常能为我们提供以下功能: 1.方便快捷获取DOM元素 如果使用纯JavaScript的方 ...
- .NET中常用的几种解析JSON方法
一.基本概念 json是什么? JSON:JavaScript 对象表示法(JavaScript Object Notation). JSON 是一种轻量级的数据交换格式,是存储和交换文本信息的语法. ...
- JavaScript基础2---控制权DOM操作
文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM将HTML文档呈现为带有元素,属性和文本的树结构(节点树). HTML文档可以说由节点构成的 ...
- State Pattern -- 状态模式原理及实现(C++)
主要参考<大话设计模式>和<设计模式:可复用面向对象软件的基础>两本书.本文介绍命令模式的实现. 问题出发点 在实际开发中,我们经常会遇到这种情况:一个对象有多种状态,在每一个 ...
- Unity3D 的摄像机
什么是摄像机 Unity3D中,摄像机是一个非常非常重要的组件. 他的作用就是:将你设计的场景投影到设备的屏幕上. 摄像机的属性 1 clear flags 确定屏幕的哪一部分将被清除. 每个摄像机在 ...
- [poj3274]排排站(Hash)
题目:http://poj.org/problem?id=3274 题目大意:http://www.wikioi.com/problem/1247/ (此题中文版) 分析: 令sum[i][j]表示a ...