小白学C#:1、三层架构

本人小白,写博客主要是记录本人学习c#的有关历程,有可以参考的同学也可以参考学习,有关代码如涉及侵权请联系删除,谢谢。

简介:本人计算机专业,个人在校期间学习的主动性不够,属于老师教什么就学习什么的类型(这点希望后面的大学生能够在学校期间,主动学习该领域就业的新知识),毕业后从事软件测试,目前从事工作与编程基本无关。
在校期间主要学习了c#基础语法,ajax网络通信技术听说过,但不是很了解。

再次学习c#目的:现在工作归纳总结留痕的较多,现在想利用空余时间编写一个综合管理系统,用于记录工作有关信息,本来想直接学习.net8的,看了有关学习视频,基础太薄弱了,很多都不懂,只有先从winform入手了。

1、学习三层架构。以前老是听说,个人理解就是在同一个解决方案中,多建几个类库,每个类库实现各自的功能。如下图:

(1)hrms是主要程序。里面的Program是应用程序的主入口点,可以配置程序开始时,启动的winform窗体,里面可以自己建很多winform窗体。

 internal static class Program
 {
     /// <summary>
     /// 应用程序的主入口点。
     /// </summary>
     [STAThread]
     static void Main()
     {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);
          Application.Run(new loginform());//loginform就是我程序的启动窗体
     }
 }

(2)model:就是实体,对应的是数据库里面的每一个表,比如下面我会用到登陆用户信息表(BaseUser),就会在这个类库中建一个对应的model实体,其余几个都是我会用到的,不一一举例,BaseUser代码如下:

 //这是model中的代码,与数据表格式对应

 public class BaseUser 
    {   public int BaseUserid { get; set; }
        public string BaseUsername { get; set; }
        public string BaseUserrealname { get; set; }
        public string BaseUserpwd { get; set; }
        public string BaseUsercreatedate { get; set; }
    }

//这是数据库创建此表的代码,与model对应

/*************   1.创建登录人员信息表****************/
create table BaseUser
(
BaseUserid int  IDENTITY(1,1) PRIMARY KEY, /* 自增序号 */
BaseUsername    varchar(255),      /* 用户名 */
BaseUserrealname    varchar(255),      /* 真实姓名 */
BaseUserpwd    varchar(255),      /* 密码 */
BaseUsercreatedate    datetime        /* 创建时间 */   
)

(3)DBUtility:这个类库中新建了SqlHelper类,主要存放数据库连接和增、删、改、查方法,后续程序只需要在这里调用对应的方法,就可以返回相应数据,太香了(主要是从某音看的:繁體記憶  老师的视频)。

namespace DBUtility
{
    public class SqlHelper
    {

       //这里是调用配置文件中的连接字符串
        public static string connStr =                 ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;//连接字符串
        private static int  result = 0;

        ///查询是否存在,调用此语句,返回查询的第一行第一列数据,我主要搭count语句使用。例如:SELECT COUNT(*) FROM Table
        public static int Getsingle(string sql, params SqlParameter[] para)
        {
            using (SqlConnection conn = new SqlConnection(connStr))
            {
                SqlCommand cmd = new SqlCommand(sql, conn);
                if (conn.State == ConnectionState.Closed)
                 {
                    conn.Open();   //打开数据库
                 }                     
                if (para != null && para.Length > 0)
                {
                    cmd.Parameters.Clear(); //清空上一个数据
                    cmd.Parameters.AddRange(para);
                }
                result= Convert.ToInt32(cmd.ExecuteScalar());
                return result;
            }
        }
        
        
        
        //用于执行不返回结果集的SQL语句或存储过程,如INSERT、UPDATE、DELETE 等操作
        //它返回受影响的行数,即执行SQL语句后所影响的行数
        public static int WriteDB(string sql,params SqlParameter[] para)
        {
                SqlConnection conn =new SqlConnection(connStr);
                
                try
                {                    
                     if (conn.State == ConnectionState.Closed)
                     {
                        conn.Open();   //打开数据库
                     }    
                     SqlCommand cmd =new SqlCommand(sql,conn);    
                 
                    if (para != null && para.Length > 0)
                    {
                        cmd.Parameters.Clear(); //清空上一个数据
                        cmd.Parameters.AddRange(para);
                    }
                    //执行sql语句
                    result= Convert.ToInt32(cmd.ExecuteNonQuery());
                }
                catch(Exception ex)
                {
                     //如果有必要在这里写个记录日志
                    string errorMessage = "调用ExecuteNonQuery方法发生异常:"+ex.Message;
                    throw new Exception(errorMessage);
                }
                finally
                {
                    conn.Close();
                }
                return result;
        }


        //个人理解,这个是返回数据表
        public static DataTable getDateTable(string sql, params SqlParameter[] parms)
        {
           
            using (SqlDataAdapter adapter = new SqlDataAdapter(sql, connStr))
            {
                DataTable dt = new DataTable();
                if (parms != null)
                {
                    adapter.SelectCommand.Parameters.AddRange(parms);
                }
                adapter.Fill(dt);
                return dt;

            }
        }

     }
}

(4)Common存放通用功能,主要建了两个类:Encrytion.cs 用于数据加密、SerializeObject.cs用于序列化(这个项目我主要用于把图片序列化成文本存放于数据库,数据库读出来反序列化成图片显示)

//Encrytion.cs 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//导入此库
using System.Security.Cryptography;
using System.IO;

namespace Common
{
    public class Encrytion
    {
        public string GetMd5x(string inputStr)
        {
            //创建md5对象
            MD5 md5 = MD5.Create();
            //现将字符串转换为数组,再开始加密
            byte[] buffer = Encoding.Default.GetBytes(inputStr);
            //加密,返回一个加密好的字节数组
            byte[] Md5Buffer = md5.ComputeHash(buffer);
            //将字节数组转换成字符串
            string newstr = "";
            for (int i = 0; i < Md5Buffer.Length; i++)
            {
                newstr += Md5Buffer[i].ToString("x");
            }
            return newstr;
        }

        public string GetMd5x2(string inputStr)
        {
            //创建md5对象
            MD5 md5 = MD5.Create();
            //现将字符串转换为数组,再开始加密
            byte[] buffer = Encoding.Default.GetBytes(inputStr);
            byte[] Md5Buffer = md5.ComputeHash(buffer);
            //将字节数组转换成字符串
            string str = "";
            for (int i = 0; i < Md5Buffer.Length; i++)
            {
                str += Md5Buffer[i].ToString("x2");
            }
            return str;
        }


    }
}
 

//SerializeObject.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//引入三个命名空间
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;


namespace Common
{
    public class SerializeObject
    {
        #region ObjectTostring
        将Object类型对象(注:必须是可序列化的对象)转换为二进制序列字符串
        public string SerializeObjectToString(object obj)
        {
            IFormatter formatter = new BinaryFormatter();
            string result = string.Empty;
            using (MemoryStream stream = new MemoryStream())
            {
                formatter.Serialize(stream, obj);
                byte[] byt = new byte[stream.Length];
                byt = stream.ToArray();
                result = Convert.ToBase64String(byt);
                stream.Flush();
            }
            return result;
        }
        #endregion


        #region tringTosObject
        //将二进制序列字符串转换为Object类型对象
        public object DeserializeObjectFromString(string str)
        {
            IFormatter formatter = new BinaryFormatter();
            byte[] byt = Convert.FromBase64String(str);
            object obj = null;
            using (Stream stream = new MemoryStream(byt, 0, byt.Length))
            {
                obj = formatter.Deserialize(stream);
            }
            return obj;
        }
        #endregion


    }

}

最后再说连接字符串,是在主程序类库中的App.config中的<configuration>节点下新增  <connectionStrings>节点,具体如下:

<connectionStrings>
<add name="connStr" connectionString="server=.;database=HRMSDBB;uid=sa;pwd=123456" />
</connectionStrings>

到这里,程序架构基本完成,另外需要说明的是,正规的应该还要建BLL类库(业务逻辑层,里面建Loginmanager,名字可自行修改,主要用于调用数据访问层,判断是否登陆成功)、DAL类库(数据访问层,里面建Loginserver类,可根据自己情况命名,主要用于实现调用数据库,DBUtility的对应方法)

下面是登陆的整个流程:

//登陆winform窗体的 确定按钮,代码:

private void buttonlogin_Click(object sender, EventArgs e)
{
    //用户名、密码非空判断。这个代码是用的express,所以textbox、messagebox名字是textEditusername、XtraMessageBox。
    if (textEditusername.Text.Length==0) 
    {
        XtraMessageBox.Show("用户名为空,请输入用户名!", "登录提示");
        textEditusername.Focus();
        return;
    }
    if (textEditpwd.Text.Length==0)
    {
        XtraMessageBox.Show("密码为空,请输入密码!", "登录提示");
        textEditpwd.Focus();
        return;
    }

    //封装对象。以前老是听说封装,感觉好高大上,结果就是这样的,嘿嘿。
    BaseUser baseUser = new BaseUser()
    {
        BaseUsername = textEditusername.Text.Trim(),
        BaseUserpwd = textEditpwd.Text
    };
    //提交数据
    try
    {

//创建业务逻辑层中的LoginManager类对象,用于调用其中的登陆方法。因为登陆界面要调用业务逻辑层,所有在这里要添加引用,引用BLL类库。
        LoginManager loginManager = new LoginManager();
        int i = loginManager.Login(baseUser);

        if (i != 1)
        {
            XtraMessageBox.Show("用户名或密码错误!", "登录提示");
        }
        else
        {
            this.Hide();
            RibbonFormMain ribbonFormMain = new RibbonFormMain();
            ribbonFormMain.Show();
        }
    }
    catch(Exception ex)
    {
        XtraMessageBox.Show(ex.Message);
    }
}

//BLL业务逻辑层,中的login方法代码如下,我写得比较简单,按理说登陆是否成功应该在这里判断是否成功,我弄到界面那里判断了,小白的思维体现无疑。

 public int Login(BaseUser objBaseUser)
 {

//这里创建DAL数据访问层对象,用于访问数据库
     LoginServer dal = new LoginServer();
     return dal.Login(objBaseUser);
 }

//DAL类库中Login方法代码:

 public  int Login(BaseUser objBaseUser)
 {
     string sql = "SELECT COUNT(*) FROM BaseUser WHERE BaseUsername=@BaseUsername AND BaseUserpwd=@BaseUserpwd";
     SqlParameter[] para = new SqlParameter[]
         {
             new SqlParameter("@BaseUsername",objBaseUser.BaseUsername),
             new SqlParameter("@BaseUserpwd",objBaseUser.BaseUserpwd),
         };

        //这里调用DBUtility类库中的Getsingle方法,判断是否有此条数据
     return SqlHelper.Getsingle(sql, para);
 }

//DBUtility类库中的Getsingle方法代码,执行数据库操作方法ExecuteScalar,返回第一行第一列的值

 public static int Getsingle(string sql, params SqlParameter[] para)
 {
     using (SqlConnection conn = new SqlConnection(connStr))
     {
         SqlCommand cmd = new SqlCommand(sql, conn);
            if (conn.State == ConnectionState.Closed)
             {
                conn.Open();   //打开数据库
             }                     
         if (para != null && para.Length > 0)
         {
                cmd.Parameters.Clear(); //清空上一个数据
             cmd.Parameters.AddRange(para);
         }

        //执行ExecuteScalar方法,返回第一行第一列的值
         result= Convert.ToInt32(cmd.ExecuteScalar());
            return result;
     }
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值