黑马程序员_精简三层架构DAL(初步认识DAL,Model,DBNull.Value的作用)

一.精简三层架构DAL认识

之前都是直接在界面(UI)中写SQL,对于大的项目这样做很难维护,而且复用性不强,三层架构是企业开发中常用的设计模式,把数据库访问,业务逻辑,界面分离。

初学者直接学习三层架构会比较难,因此这次用精简的三层架构,只用DAL(Data Access Layer)层,把数据库访问封装到DAL中,UI调用DAL,原则“UI中不出现SQL” 

二.精简版DAL的学习

创建StudentDAL类,用于实现数据访问

1.没有参数:如查询数据库中对应表的总条数,在UI层,只需要调用StudentDAL类中的对应方法就可以,不用写任何有关的SQL语句

UI层:(.cs

 private void button1_Click(object sender, RoutedEventArgs e)

        {

            int count=StudentDAL.GetCount();

            MessageBox.Show(count.ToString());

        }

DAL层:(StudentDAL.cs)

  /// <summary>

        /// 获取数据总条数

        /// </summary>

        /// <returns></returns>

        public static int GetCount()

        {

            return (int)SqlHelper.ExecuteScalar("select count(*) from T_Student");

        }

2.少量参数(如一个),如删除编号为3的学生,同上,在 UI层,只需要调用StudentDAL类中的对应方法就可以了,不用写任何有关数据访问的SQL语句,只要把对应的少量参数传递就可以

UI层:(.cs

 private void button2_Click(object sender, RoutedEventArgs e)

        {

            StudentDAL.DelStudentById(3);

            MessageBox.Show("删除成功!");

        }

DAL层:(StudentDAL.cs

  /// <summary>

        /// 通过编号删除数据

        /// </summary>

        /// <param name="id"></param>

        public static void DelStudentById(long id)

        {

            SqlHelper.ExecuteNonQuery("delete from T_Student where Id=@id", new SqlParameter("@id", id));

        }

 

3.大量参数操作,如需要向数据库中添加一个学生的信息,字段量非常大,并且有可空,有不可空的情况,处理起来再按照如上的参数一个一个写是非常费时费事的,这样就需要引入一个新的概念Model(我把它暂时理解为对象类),直接传对象

写一个Student类:

namespace 初学三层架构DAL精简版

{

    //在构建Student Model时候切记要与数据库保持一致,并且数据库中可空的,在Model中要有标识

    //Model的好处是:在插入一个学生,添加的参数会很多,可是把这许多参数都放在Student类中,

    //添加一个对象就可以了,存取非常方便,打点就能实现

    class Student

    {

        public long Id { get; set; }//数据空中这个字段是bigint类型,对应C#中的long类型

        public string StudentName { get; set; }

        public int StudentAge { get; set; }

        public string StudentTel { get; set; }

        public string StudentAddress { get; set; }//这个字段可为空,但是它是string类型的,

        //本身就是可空类型,所以不用加?加了反而会出错

        public DateTime? StudentBirthday { get; set; }//这个字段可为空,它是DataTime类型,

        //如同int ,bool ,decimal类型不能为空,要加?,变为可空类型

    }

}

现在考虑一个问题:如果项目中对于有些字段没有要求,可空传递,如何解决?

如以下情况,学生地址,和学生出生日期可以为空,但是作为Student对象的属性,参数传递到DAL层,DAL层对应的插入方法是找不到参数的,这里必须要将null转换成DBNull.Value

UI层(.cs

 private void button3_Click(object sender, RoutedEventArgs e)

        {

            Student student = new Student();

            student.StudentName = "张三";

            student.StudentAge = 22;

            student.StudentTel = "13523659529";

            //student.StudentAddress = "南阳";

            //student.StudentBirthday = DateTime.Now;

            StudentDAL.InsertStudent(student);

            MessageBox.Show("添加成功!");

            

        }

 

 

 

DAL层:(StudentDAL.cs

   /// <summary>

        /// 添加一条数据

        /// </summary>

        /// <param name="student"></param>

        public static void InsertStudent(Student student)

        {

            //object StudentBirthday;

            //if (student.StudentBirthday == null)

            //{

            //    StudentBirthday = DBNull.Value;

            //}

            //else

            //{

            //    StudentBirthday = student.StudentBirthday;

            //}

            SqlHelper.ExecuteNonQuery(@"insert into T_Student(StudentName,StudentAge,StudentTel,StudentAddress,StudentBirthday) 

                    values(@StudentName,@StudentAge,@StudentTel,@StudentAddress,@StudentBirthday)",

                new SqlParameter("@StudentName",student.StudentName),

                new SqlParameter("@StudentAge",student.StudentAge),

                new SqlParameter("@StudentTel",student.StudentTel),

                new SqlParameter("@StudentAddress", ToDBValue(student.StudentAddress)),//所有可空字段都要经过转换,

                //才能正确存储数据库

                new SqlParameter("@StudentBirthday",ToDBValue(student.StudentBirthday)));

        }

写一个从null转换为DBNull.Value的方法:

  /// <summary>

        /// ToDBValue方法,将空字段,转换为DBNull.Value传入数据库中

        /// </summary>

        /// <param name="value"></param>

        /// <returns></returns>

        public static object ToDBValue(object value)

        {

            if (value == null)

            {

                return DBNull.Value;

            }

            else

            {

                return value;

            }

        }

4.大量参数操作,从数据库中读取数据,这部分主要考虑一个问题:数据库中Null不知道如何转换为项目中的null,还需要通过DBNull.Value

UI层:(.cs

private void button4_Click(object sender, RoutedEventArgs e)

        {

            StudentDAL.GetStudentById(4);

        }

DAL层:(StudentDAL.cs

       /// <summary>

        /// 通过编号获取学生信息

        /// </summary>

        /// <param name="id"></param>

        /// <returns></returns>

        public static Student GetStudentById(long id)

        {

            DataTable dt=SqlHelper.ExecuteDataTable("select * from T_Student where Id=@id",new SqlParameter("@id",id));

            if(dt.Rows.Count<=0)

            {

                return null;

            }

            else if(dt.Rows.Count>1)

            {

                throw new Exception("学生重复!");

            }

            else

            {

                Student student = new Student();

                student.StudentName=(string)dt.Rows[0]["StudentName"];

                student.StudentAge=(int)dt.Rows[0]["StudentAge"];

                student.StudentTel=(string)dt.Rows[0]["StudentTel"];

                student.StudentAddress=(string)FromDBValue(dt.Rows[0]["StudentAddress"]);

                student.StudentBirthday = (DateTime?)FromDBValue(dt.Rows[0]["StudentBirthday"]);

                //好好研究这行代码,从数据库中获取的可能为DBNull.Value,经过FromDBValue方法反向转换,可能为空,

                //但是不能直接再类型转换为DataTime类型,因为DataTime类型为不可空类型,所有要转换为DataTime?类型

                return student;

            }

           

 

        }

写一个从DBNull.Value转换为null的方法:

  /// <summary>

        /// 反向转换,如果value这个数据库中的值为DBNull.Value,则转换为null

        /// </summary>

        /// <param name="value"></param>

        /// <returns></returns>

        public static object FromDBValue(object value)

        {

            if (value == DBNull.Value)

            {

                return null;

            }

            else

            {

                return value;

            }

        }

三.总结DBNull.Value

DBNull与数据库中的Null(不知道)是对等的!

Object是所有类的父类,在这里得到了最好的诠释!

目的:项目中的可空字段(null)传入数据库(NULL)

过程:null(用户没有输入)---------Null(数据库不知道),没有值不能传,需要过渡,所有需要了DBNull.Value来解决这个问题,Null(用户没有输入),在插入之前进行判断,如果缺少用户没有输入的参数,就将其转换成DBNull.Value再插入;

目的:数据库中(NULL)传入项目(null

项目中需要获取数据库中可为空的数据,Null(数据库不知道)------------null(项目中显示为空),同样需要DBNull.Value来解决,在取值之前判断,如果从数据库中获取的值为DBNull.Value,则把要获取的值赋值为null

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值