winform 三層構架 桌面軟件開發 SQLite

基於三層構架的桌面軟件開發

三層架構分爲:表現層(UI)、業務邏輯層(BLL)、數據訪問層(DAL)、實體類庫(Model)
分層次的目的:爲了“高內聚低耦合”的思想

  • 表示層(UI):主要對用戶的請求接受,以及數據的返回,爲客戶端提供應用程序的訪問。
  • 業務邏輯層(BLL):主要負責對數據層的操作。也就是說把一些數據層的操作進行組合。
  • 數據訪問層(DAL):主要看數據層裏面有沒有包含邏輯處理,實際上它的各個函數主要完成各個對數據文件的操作。

各層之間的關係

關係

搭建三層

建立項目,按順序添加層,每添加一層刪除 Programe.cs。

  • 建立其他項目類型-空白解決方法TestFloor
  • 添加TestFloorModel項目類庫,右擊屬性-創建名稱空間修改爲TestFloor.Model
  • 依次添加TestFloorDAL,TestFloorBLL,UI層即爲TestFloor不需要修改
  • 創建聯繫,TestFloorDAL引用項目TestFloorModel,TestFloorBLL引用項目TestFloorDAL和TestFloorModel,TestFloor引用項目TestFloorModel和TestFloorBLL,其中修改Forms類,直接重命名
  • 在文件夾目錄新建DLL文件夾,將外部dll複製過來
  • 在UI中添加應用配置文件App.config用於連接數據庫,修改文件內容,將數據庫參數內容寫入configuration中
<connectionStrings> 
    <add connectionString="Data Source=cater.db;Version=3;" name="conStr"/>
</connectionStrings>
  • 將數據庫文件.db放入到項目UI層,BIN-DEBUG文件夾中
  • 在DAL項目添加引用,SQLite.dll,添加類SqliteHelper,在類頭添加using System.Data.SQLite;using System.Data
  • 編寫SqliteHelper類
    public class SqliteHelper
    {
        //連接字符串
        private static readonly string str = ConfigurationManager.ConnectionStrings["conStr"].ConnectionString;
        /// <summary>
        /// 增刪該
        /// </summary>
        /// <param name="sql">sql語句</param>
        /// <param name="param">sql參數</param>
        /// <returns>受影響的行數</returns>
        public static int ExecuteNonQuery(string sql, params SQLiteParameter[] param)
        {
            using(SQLiteConnection con= new SQLiteConnection(str))//使用完自動釋放資源
            {
                using (SQLiteCommand cmd=new SQLiteCommand(sql,con))
                {
                    con.Open();
                    if (param != null)
                    {
                        cmd.Parameters.AddRange(param);
                    }
                    return cmd.ExecuteNonQuery();
                }
            }
        }
        /// <summary>
        /// 查詢
        /// </summary>
        /// <param name="sql">sql語句</param>
        /// <param name="param">sql參數</param>
        /// <returns>首行首列</returns>
        public static object ExecuteScalar(string sql, params SQLiteParameter[] param)
        {
            using (SQLiteConnection con = new SQLiteConnection(str))
            {
                using (SQLiteCommand cmd = new SQLiteCommand(sql, con))
                {
                    con.Open();
                    if (param != null)
                    {
                        cmd.Parameters.AddRange(param);
                    }
                    return cmd.ExecuteScalar();
                }
            }
        }
        /// <summary>
        /// 多行查詢
        /// </summary>
        /// <param name="sql">sql語句</param>
        /// <param name="param">sql參數</param>
        /// <returns>SQLiteDataReader</returns>
        public static SQLiteDataReader ExecuteReader(string sql, params SQLiteParameter[] param)
        {
            SQLiteConnection con = new SQLiteConnection(str);
            using (SQLiteCommand cmd = new SQLiteCommand(sql, con))
            {
                if (param != null)
                {
                    cmd.Parameters.AddRange(param);
                }
                try
                {
                    con.Open();
                    return cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
                }
                catch (Exception ex)
                {
                    con.Close();
                    con.Dispose();
                    throw ex;
                }
            }
        }
        /// <summary>
        /// 查詢多行數據
        /// </summary>
        /// <param name="sql">sql語句</param>
        /// <param name="param">sql參數</param>
        /// <returns>一個表À</returns>
        public static DataTable ExecuteTable(string sql,params SQLiteParameter[] param)
        {
            DataTable dt = new DataTable();
            using (SQLiteDataAdapter sda = new SQLiteDataAdapter(sql,str))
            {
                if (param != null)
                {
                    sda.SelectCommand.Parameters.AddRange(param);
                }
                sda.Fill(dt);
            }
            return dt;
        }
    }

至此基本功能完成,下面介紹一個簡單的練習數據庫的增刪改查

增刪改查

點擊會員管理,實現對會員的增刪改查

按鈕

點擊會員管理,出現會員管理窗體

會員管理窗體

1加載

數據庫中會員表,表名爲MemberInfo

MemberInfo表

private void btnMember_Click(object sender, EventArgs e)
{
    FrmMmemberInfo fm =new FrmMmemberInfo();
    fm.ShowDialog();
}

在窗口加載時需要將現有會員顯示出來,若要將所有會員顯示出來,傳入標識符,返回會員列表

private void FrmMmemberInfo_Load(object sender, EventArgs e)
{
    //加載會員
    LoadMemberInfoByDelflag(0);
}

下面要去MODEL中根據表名新建一個model類,MemmberInfo類,該類中成員都爲列名

   public class MemmberInfo
    {
        //MemberId MemName MemMobilePhone MemAdress MemType MemNum MemGender MemDiscount MemMoney DelFlag SubTime MemIntegral MemEndServerTime MemBirthdaty
        #region Model
        private int _memmberid;
        private string _memname;
        private string _memphone;
        private string _memmobilephone;
        private string _memaddress;
        private int _memtype;
        private string _memnum;
        private string _memgender;
        private decimal? _memdiscount = 1.00M;
        private decimal? _memmoney = 0M;
        private int? _delflag;
        private DateTime? _subtime;
        private int? _memintegral;
        private DateTime? _memendservertime;
        private DateTime? _membirthdaty;

        //冗餘屬性
        public string MemTpName
        {
            get;
            set;
        }
        /// <summary>
        /// 會員主鍵id
        /// </summary>
        public int MemmberId
        {
            set { _memmberid = value; }
            get { return _memmberid; }
        }
        /// <summary>
        /// 會員名字
        /// </summary>
        public string MemName
        {
            set { _memname = value; }
            get { return _memname; }
        }
        /// <summary>
        /// 會員電話
        /// </summary>
        public string MemPhone
        {
            set { _memphone = value; }
            get { return _memphone; }
        }
        /// <summary>
        /// 會員手機
        /// </summary>
        public string MemMobilePhone
        {
            set { _memmobilephone = value; }
            get { return _memmobilephone; }
        }
        /// <summary>
        /// 會員地址
        /// </summary>
        public string MemAddress
        {
            set { _memaddress = value; }
            get { return _memaddress; }
        }
        /// <summary>
        /// 會員類型
        /// </summary>
        public int MemType
        {
            set { _memtype = value; }
            get { return _memtype; }
        }
        /// <summary>
        /// 會員編號
        /// </summary>
        public string MemNum
        {
            set { _memnum = value; }
            get { return _memnum; }
        }
        /// <summary>
        /// 會員性別
        /// </summary>
        public string MemGender
        {
            set { _memgender = value; }
            get { return _memgender; }
        }
        /// <summary>
        /// 會員折扣
        /// </summary>
        public decimal? MemDiscount
        {
            set { _memdiscount = value; }
            get { return _memdiscount; }
        }
        /// <summary>
        /// 會員餘額
        /// </summary>
        public decimal? MemMoney
        {
            set { _memmoney = value; }
            get { return _memmoney; }
        }
        /// <summary>
        /// 會員刪除標識
        /// </summary>
        public int? DelFlag
        {
            set { _delflag = value; }
            get { return _delflag; }
        }
        /// <summary>
        /// 會員提交時間
        /// </summary>
        public DateTime? SubTime
        {
            set { _subtime = value; }
            get { return _subtime; }
        }
        /// <summary>
        /// 會員積分
        /// </summary>
        public int? MemIntegral
        {
            set { _memintegral = value; }
            get { return _memintegral; }
        }
        /// <summary>
        /// 會員結束時間
        /// </summary>
        public DateTime? MemEndServerTime
        {
            set { _memendservertime = value; }
            get { return _memendservertime; }
        }
        /// <summary>
        /// 會員生日
        /// </summary>
        public DateTime? MemBirthdaty
        {
            set { _membirthdaty = value; }
            get { return _membirthdaty; }
        }
        #endregion Model
    }

在DAL層同樣的方式新建MemmberInfoDAL類,將private改成public,創建公有方法GetAllMemmberInfoDelflag()同時還涉及到一個行轉對象的問題

public List<MemmberInfo> GetAllMemmberInfoDelflag(int delflag)
{
    string sql="select * from MemmberInfo where DelFlag=@DelFlag";
    DataTable dt=SqliteHelper.ExecuteTable(sql,new SQLiteParameter("@DelFlag",delflag));
    List<MemmberInfo> list=new List<MemmberInfo>();
    if(dt.Rows.Count>0)
    {
        foreach (DataRow item in dt.Rows)
        {
            MemmberInfo member=RowToMemberInfo(item); 
            if(list!=null)
            {
                list.Add(member);
            }
        }
    }
    return list;
}
/// <summary>
/// 成員轉類
/// </summary>
/// <param name="dr"></param>
/// <returns></returns>
private MemmberInfo RowToMemberInfo(DataRow dr)
{
    MemmberInfo member=new MemmberInfo();
    member.DelFlag=Convert.ToInt32( dr["DelFlag"]);
    member.MemAddress=dr["MemAddress"].ToString();
    member.MemmberId=Convert.ToInt32(dr["MemmberId"]);
    //member.MemBirthdaty=Convert.ToDateTime(dr["MemBirthdaty"]);
    member.MemDiscount=Convert.ToDecimal(dr["MemDiscount"]);
    //member.MemEndServerTime=Convert.ToDateTime(dr["MemEndServerTime"]);
    member.MemGender=dr["MemGender"].ToString();
    //member.MemIntegral=Convert.ToInt32(dr["MemIntegral"]);
    member.MemMobilePhone=dr["MemMobilePhone"].ToString();
    member.MemMoney=Convert.ToDecimal(dr["MemMoney"]);;
    member.MemName=dr["MemName"].ToString();
    member.MemNum=dr["MemNum"].ToString();
    member.MemType=Convert.ToInt32(dr["MemType"]);
    member.SubTime=Convert.ToDateTime(dr["SubTime"]);  
    return member;
}

在BLL層同樣的方式新建MemmberInfoBLL類,將private改成public,創建公有方法GetAllMemmberInfoDelflag()

public List<MemmberInfo> GetAllMemmberInfoDelflag(int delflag)
{
    return dal.GetAllMemmberInfoDelflag(delflag);
}

在UI層中,加載數據

private void LoadMemberInfoByDelflag(int p)
{
    MemmberInfoBLL bll = new MemmberInfoBLL();
    dgvmember.AutoGenerateColumns = false;//靜止自動生成列
    dgvmember.DataSource = bll.GetAllMemmberInfoDelflag(p);
    dgvmember.SelectedRows[0].Selected = false;//默認不選中
}

刪除

刪除首先要判斷是否選中行,然後通過標識進行刪除操作,UI層

private void btnDelete_Click(object sender, EventArgs e)
{
    //判斷是否選中某行
    if (dgvmember.SelectedRows.Count > 0)
    {
        MemmberInfoBLL bll = new MemmberInfoBLL();
        int id = Convert.ToInt32(dgvmember.SelectedRows[0].Cells[0].Value);
        if (bll.DeleteMemberInfoByMemberID(id))
        {
            MessageBox.Show("操作成功");
            LoadMemberInfoByDelflag(0);
        }
        else
        {
            MessageBox.Show("操作失敗");
        }
    }
    else 
    {
        MessageBox.Show("請先選中要刪除的會員");
    }
}

同樣到DAL和BLL層中編寫DeleteMemberInfoByMemberID()方法
在DAL的MemmberInfoDAL類中

/// <summary>
/// 根據id刪除會員
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public int DeleteMemberInfoByMemberID(int id)
{
    //用戶傳的需要寫參數,不是可以不用寫參數
    string sql = "update MemmberInfo set DelFlag=1 where MemmberId=@MemmberId";
   return   SqliteHelper.ExecuteNonQuery(sql,new SQLiteParameter("@MemmberId",id));
}

在BLL的MemmberInfoBLL類中

/// <summary>
/// 根據ID刪值
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public bool DeleteMemberInfoByMemberID(int id)
{
    return dal.DeleteMemberInfoByMemberID(id)>0 ? true:false;
}

增加和修改

增加和修改窗體

這兩個功能可以放到一起做,通過事件向窗體傳值FrmChanfeMember窗體

//爲了傳值在UI層新建消息類
//窗體傳值用的類
public class FrmEventArgs : EventArgs
{
    /// <summary>
    /// 標識
    /// </summary>
    public int Temp { set; get; }
    /// <summary>
    /// 對象
    /// </summary>
    public Object obj { set; get; }
}
/// <summary>
/// 窗體傳值事件
/// </summary>
public event EventHandler evt;
/// <summary>
/// 事件參數類
/// </summary>
FrmEventArgs fea = new FrmEventArgs();
//點擊增加
private void btnAddMember_Click(object sender, EventArgs e)
{
//ShowFrmChangeMember(2);
fea.Temp = 2;
ShowFrmChangeMember();
}
//點擊修改
private void btnUpdeMember_Click(object sender, EventArgs e)
{
    if (dgvmember.SelectedRows.Count > 0)
    {
        int id = Convert.ToInt32(dgvmember.SelectedRows[0].Cells[0].Value);
        //不能從表中直接拿值,要從數據庫中查詢
        MemmberInfoBLL bll = new MemmberInfoBLL();
        fea.Temp = 1;
        fea.obj = bll.GetMemberInfoByID(id);//從數據庫中根據ID取值
        ShowFrmChangeMember();
    }
    else
    {
        MessageBox.Show("請選中要修改的會員");
    }
    //ShowFrmChangeMember(1);

}
private void ShowFrmChangeMember()
{
    FrmChanfeMember fcm = new FrmChanfeMember();
    this.evt += new EventHandler(fcm.SetText);

    //fea.Temp = p;//新增或修改的表示
    if (this.evt != null)//執行事件之前不能爲空
    {
        this.evt(this, fea);//執行事件

    }
    //fcm.ShowDialog();他關閉將子窗口中值傳遞給父類窗口
    fcm.FormClosed += new FormClosedEventHandler(fcmFrmClosed);
    fcm.ShowDialog();
}
//窗口關閉更新界面
private  void fcmFrmClosed(object sender,EventArgs e)
{
    LoadMemberInfoByDelflag(0);
 }

在FrmChanfeMember中傳值函數

public void SetText(object sender,EventArgs e)
{
    loadMemmberType();
    FrmEventArgs fea = e as FrmEventArgs;
    temp = fea.Temp;
    //if (fea.Temp == 2)//新增修改
    //{

    foreach (var item in this.Controls)
    {
        if (item is TextBox)
        {
            TextBox tb = item as TextBox;
            tb.Text = "";
        }
    }
    //}
    if(fea.Temp==1)
    {
        MemmberInfo member=fea.obj as MemmberInfo;
        if (member != null)
        {
            txtMemNum.Text = member.MemNum.ToString();
            txtAddress.Text = member.MemAddress.ToString();
            txtMemDiscount.Text = member.MemDiscount.ToString();
            txtMemIntegral.Text = member.MemIntegral.ToString();
            txtmemMoney.Text = member.MemMoney.ToString();
            txtMemName.Text = member.MemName.ToString();
            txtMemPhone.Text = member.MemMobilePhone.ToString();
            txtBirs.Text = member.MemBirthdaty.ToString();
            cmbMemType.SelectedIndex = Convert.ToInt32(member.MemType);
            rdoMan.Checked = member.MemGender=="男"?true:false;
            rdoWomen.Checked=member.MemGender=="女"?true:false;
            labId.Text = member.MemmberId.ToString();//將ID存起來
        }


    }
    else
    {
        txtMemIntegral.Text = "0";
    }

}
public void loadMemmberType()
{
    MemmberTypeBLL bll = new MemmberTypeBLL();
    List<MemmberType> list = bll.GetMemmberType();
    list.Insert(0, new MemmberType() { MemType = -1, MemTpName = "請選擇" });
    cmbMemType.DataSource = list;
    cmbMemType.DisplayMember = "MemTpName";
    cmbMemType.ValueMember = "MemType";
}
/// <summary>
/// 判斷是新增還是修改
/// </summary>
private int temp{set;get;}
private void btnOk_Click(object sender, EventArgs e)
{
    //獲取會員信息
    //每個文本框不能爲空
    //判斷性別
    MemmberInfo mem=new MemmberInfo();
    if(CheckMemmberTextEmpty())
    {
        mem.MemAddress = txtAddress.Text;
        mem.MemBirthdaty = Convert.ToDateTime(txtBirs.Text);
        mem.MemDiscount = Convert.ToDecimal(txtMemDiscount.Text);
        mem.MemEndServerTime = dtEndServerTime.Value;
        mem.MemGender = CheckGender();
        mem.MemIntegral = Convert.ToInt32(txtMemIntegral.Text);
        mem.MemMobilePhone = txtMemPhone.Text;
        mem.MemMoney = Convert.ToDecimal(txtmemMoney.Text);
        mem.MemName = txtMemName.Text;
        mem.MemNum = txtMemNum.Text;
        mem.MemType = Convert.ToInt32(cmbMemType.SelectedIndex);
    }
    MemmberInfoBLL bll = new MemmberInfoBLL();
    if (temp == 2)
    {
        mem.DelFlag = 0;
        mem.SubTime = System.DateTime.Now; 
    }
    if (temp == 1)
    {
        mem.MemmberId = Convert.ToInt32(labId.Text);
    }
    string str = bll.SaveMember(mem, this.temp) ? "操作成功" : "操作失敗";
    MessageBox.Show(str);
    this.Close();
}
public bool CheckMemmberTextEmpty()
{
    if (string.IsNullOrEmpty(txtBirs.Text))
    {
        MessageBox.Show("生日不能爲空");
        return false;
    }
    if (string.IsNullOrEmpty(txtMemDiscount.Text))
    {
        MessageBox.Show("折扣不能爲空");
        return false;
    }
    if (string.IsNullOrEmpty(txtMemIntegral.Text))
    {
        MessageBox.Show("積分不能爲空");
        return false;
    }
    if (string.IsNullOrEmpty(txtmemMoney.Text))
    {
        MessageBox.Show("餘額不能爲空");
        return false;
    }
    if (string.IsNullOrEmpty(txtMemName.Text))
    {
        MessageBox.Show("名字不能爲空");
        return false;

    }
    if (string.IsNullOrEmpty(txtMemNum.Text))
    {
        MessageBox.Show("編號不能爲空");
        return false;
    }
    if (string.IsNullOrEmpty(txtMemPhone.Text))
    {
        MessageBox.Show("電話不能爲空");
        return false;
    }
    if (string.IsNullOrEmpty(dtEndServerTime.Text))
    {
        MessageBox.Show("有效期不能爲空");
        return false;
    }
    return true;
}
public string CheckGender()
{
    string str="";
    if (rdoMan.Checked)
    {
         str = "男";
    }
    if(rdoWomen.Checked)
    {
         str = "女";
    }
    return str;
}

點擊OK將數據保存數據庫,BLL層在該層中要進行邏輯判斷是新增還是修改

public bool SaveMember(MemmberInfo memmber, int temp)
{
    int flag = -1;
    if (temp == 2)
    {
       flag= dal.AddMemmberInfo(memmber);
    }
    if (temp == 1)
    {
        flag= dal.UpdataAddMemberInfo(memmber);
    }
    return flag>0?true:false;
}
/// <summary>
/// 根據id查值
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public MemmberInfo GetMemberInfoByID(int id)
{
    return dal.GetMemberInfoByID(id);
}

DAL層


public int AddMemmberInfo(MemmberInfo memmber)
{
    string sql = "insert into MemmberInfo(MemName,MemMobilePhone,MemAddress,MemType,MemNum,MemGender,MemDiscount,MemMoney,DelFlag,SubTime,MemIntegral,MemEndServerTime,MemBirthdaty)values(@MemName,@MemMobilePhone,@MemAddress,@MemType,@MemNum,@MemGender,@MemDiscount,@MemMoney,@DelFlag,@SubTime,@MemIntegral,@MemEndServerTime,@MemBirthdaty)";
    return AddAndUpdate(memmber, sql, 1);
}
public int UpdataAddMemberInfo(MemmberInfo memmber)
{
    string sql = "update MemmberInfo set MemName=@MemName,MemMobilePhone=@MemMobilePhone,MemAddress=@MemAddress,MemType=@MemType,MemNum=@MemNum,MemGender=@MemGender,MemDiscount=@MemDiscount,MemMoney=@MemMoney,MemIntegral=@MemIntegral,MemEndServerTime=@MemEndServerTime,MemBirthdaty=@MemBirthdaty where MemmberId=@MemmberId";
    return AddAndUpdate(memmber, sql, 2);
}
//新增和修改的合併方法
private int AddAndUpdate(MemmberInfo memmber, string sql, int temp)
{
    SQLiteParameter[] param = { 
          new SQLiteParameter("@MemName",memmber.MemName),
          new SQLiteParameter("@MemMobilePhone",memmber.MemMobilePhone),
           new SQLiteParameter("@MemAddress",memmber.MemAddress),
            new SQLiteParameter("@MemType",memmber.MemType),
             new SQLiteParameter("@MemNum",memmber.MemNum),
              new SQLiteParameter("@MemGender",memmber.MemGender),
               new SQLiteParameter("@MemDiscount",memmber.MemDiscount),
                new SQLiteParameter("@MemMoney",memmber.MemMoney),
                 // new SQLiteParameter("@MemmberId",memmber.MemmberId),
                      new SQLiteParameter("@MemIntegral",memmber.MemIntegral),
                      new SQLiteParameter("@MemEndServerTime",memmber.MemEndServerTime),
                      new SQLiteParameter("@MemBirthdaty",memmber.MemBirthdaty)

                              };
    List<SQLiteParameter> list = new List<SQLiteParameter>();
    list.AddRange(param);
    if (temp == 1)//新增
    {
        list.Add(new SQLiteParameter("@SubTime", memmber.SubTime));
        list.Add(new SQLiteParameter("@DelFlag", memmber.DelFlag));
    }
    else if (temp == 2)//修改
    {
        list.Add(new SQLiteParameter("@MemmberId", memmber.MemmberId));
    }

    return SqliteHelper.ExecuteNonQuery(sql, list.ToArray());
}
public MemmberInfo GetMemberInfoByID(int id)
{
    MemmberInfo member = null;
    string sql = "select * from MemmberInfo where MemmberId=@MemmberId";
    DataTable dt = SqliteHelper.ExecuteTable(sql, new SQLiteParameter("@MemmberId", id));
    if (dt.Rows.Count > 0)
    {
        member = RowToMemberInfo(dt.Rows[0]);
    }
    return member;
}

自此三層框架中的增刪改查介紹完畢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章