zoukankan      html  css  js  c++  java
  • 面向对象基础----封装数据库操作类

    思考:现在掌握了很多面向对象相关的内容,但是什么时候封装类?怎么封装?如果使用类成员?

    引入:其实类的封装没有多么复杂,但是需要一个熟练的过程来确定哪些东西可以放到类里,该用什么样的形式等。我们通过封装一个数据库的操作来综合练习下

    封装数据库类 掌握

    定义:封装数据库操作类,即根据数据库的操作需求,来确认数据库操作类该有什么样的功能,以及这些功能该如何实现。

    1.一个类通常就是一个文件,所以要先确定文件的名字:通常类文件命名规范有两种。

    •   文件名字与类名一样,如Sql.php
    •   为了区分普通php文件,增加中间类描述,如Sql_class.php
    •   现在php几乎都是面向对象变成,所以通常采用第一种方式:因此当前命名规范数据类的文件为:Sql_php

    2.确定类文件名字后其实也就是确定了类名字,因此可以创建一个Sql类。

    <?php
    //数据库操作类
    class Sql{
    
    }
    
    
    ?>

    3.类的创建分两种:一是特定使用,即类里面的所有内容只为某次使用;二是通用,即工具类,以后很多地方可以用;

      特定使用,功能可以不同太灵活

      通用工具,功能应该大众化,数据的变化会比较多

    数据库类以后凡是要操作数据库的地方都可以用得到,很多项目都会用到,所以应该是个通用类工具,因此要考虑其到处可用的特性,让其能够灵活。

    4.数据库的错操最基本的特性不会改变,即需要连接认证  而连接认证的信息是灵活的,所以可以通过设定属性来控制,这些信息也都是不同使用这不同的

    应该可以改变,所以可以通过__construct来实现数据传入

    <?php
    //数据库操作类
    class Sql{
    
        //设置属性
        public $host;
        public $user;
        public $pwd;
        public $port;
        public $dbname;
        public $charset;
        //构造方法初始化数据,数据较多,应该使用数组来传递数据,关联数组,而绝大部分的开发者本意是用来测试,
        //所以基本都是本地,因此可以给默认数据
    
        public function __construct(array $info=array())
        {
            //这里的??表示为 $a=$c??$b 等同于 $a=isset($c)?$c:$b; 如果变量c存在就等于c否则等于b
            $this->host=$info['host']??'localhost';
            $this->user=$info['user']??'root';
            $this->pwd=$info['pwd']??'root';
            $this->port=$info['port']??'3306';
            $this->dbname=$info['dbname']??'t1';
            $this->charset=$info['charset']??'utf8';
        }
    }
    
    $info =array(0=>'sdfsdf',1=>'sdf',2=>'sdfsdf');
    print_r($info);
    
    ?>

    注意:方法设定的原则是一个方法只实现一个简单的功能,不要多个功能堆积到一个方法中。

    5.数据库属性会在实例化sql对象的时候自动初始化

    <?php
    //数据库操作类
    class Sql{
    
        //设置属性
        public $host;
        public $user;
        public $pwd;
        public $port;
        public $dbname;
        public $charset;
    
        //初始化构造方法
        public function __construct(array $info=array())
        {
            //这里的??表示为 $a=$c??$b 等同于 $a=isset($c)?$c:$b; 如果变量c存在就等于c否则等于b
            //以上功能只有php 版本7.0 以上可以用
            $this->host=$info['host'] ?? 'localhost';
            $this->user=$info['user'] ?? 'root';
            $this->pwd=$info['pwd'] ?? 'root';
            $this->port=$info['port'] ?? '3306';
            $this->dbname=$info['dbname'] ?? 't1';
            $this->charset=$info['charset'] ?? 'utf8';
        }
    }
    
    
        $s1=new Sql();     //使用默认数据库信息
        $db=array(
            'host'=>'localhost',
            'user'=>'root',
            'pwd'=>'root',
            'dbname'=>'t1'
        );
        $s2=new Sql($db);
        var_dump($s1);
        var_dump($s2)
    
    ?>

    6.数据库要操作的第一件事情就是要验证,所以需要一个连接认证的功能,这里可以使用mysqli面向对象的方法,但是需要建立一个方法来实现连接认证

    连接是否成功?

      

    <?php
    //数据库操作类
    class Sql{
    
        //设置属性
        public $host;
        public $user;
        public $pwd;
        public $port;
        public $dbname;
        public $charset;
    
        //初始化构造方法
        public function __construct(array $info=array()){
            //这里的??表示为 $a=$c??$b 等同于 $a=isset($c)?$c:$b; 如果变量c存在就等于c否则等于b
            //以上功能只有php 版本7.0 以上可以用
            $this->host=$info['host'] ?? 'localhost';
            $this->user=$info['user'] ?? 'root';
            $this->pwd=$info['pwd'] ?? 'root';
            $this->port=$info['port'] ?? '3306';
            $this->dbname=$info['dbname'] ?? 't1';
            $this->charset=$info['charset'] ?? 'utf8';
        }
        //认证数据库连接
        public function sql_connet(){
            //利用mysqli属性可以跨方法访问:5个参数分别为:主机,用户,密码,数据库,端口
            $link=new mysqli($this->host,$this->user,$this->pwd,$this->dbname,$this->port);
            if($link->connect_errno){
                die( $link->connect_error);
            }
        }
    }
    
    $s=new Sql();
    $s->sql_connet();    //正常 没有错误

    7.用户调用sql类的目的一定是为了操作数据库,那么用户在实例化之后就需要调用连接认证方法,为了方便用户操作,可以帮助用户省去调用这一步骤:在构造方法中调用该方法

    <?php
    //数据库操作类
    class Sql{
    
        //设置属性
        public $host;
        public $user;
        public $pwd;
        public $port;
        public $dbname;
        public $charset;
    
        //初始化构造方法
        public function __construct(array $info=array()){
            //这里的??表示为 $a=$c??$b 等同于 $a=isset($c)?$c:$b; 如果变量c存在就等于c否则等于b
            //以上功能只有php 版本7.0 以上可以用
            $this->host=$info['host'] ?? 'localhost';
            $this->user=$info['user'] ?? 'root';
            $this->pwd=$info['pwd'] ?? 'root';
            $this->port=$info['port'] ?? '3306';
            $this->dbname=$info['dbname'] ?? 't1';
            $this->charset=$info['charset'] ?? 'utf8';
            $this->sql_connet();
        }
        //认证数据库连接
        public function sql_connet(){
            //利用mysqli属性可以跨方法访问:5个参数分别为:主机,用户,密码,数据库,端口
            $link=new mysqli($this->host,$this->user,$this->pwd,$this->dbname,$this->port);
            if($link->connect_errno){
                die( $link->connect_error);
            }
        }
    }
    
    $s=new Sql();
    // $s->sql_connet();    //正常 没有错误
    
    
    
    
        
    ?>

    8.至此,一旦实例化sql类对象,就可以实现数据库的连接,但是此时还存在一个细节问题,字符集,为了保证数据库连接正常操作,需要新增一个方法设定字符集

    <?php
    //数据库操作类
    class Sql{
    
        //设置属性
        public $host;
        public $user;
        public $pwd;
        public $port;
        public $dbname;
        public $charset;
        //增加一个属性来保存mysqli返回的连接(对象),需要跨方法使用
        public $link;
    
        //初始化构造方法
        public function __construct(array $info=array()){
            //这里的??表示为 $a=$c??$b 等同于 $a=isset($c)?$c:$b; 如果变量c存在就等于c否则等于b
            //以上功能只有php 版本7.0 以上可以用
            $this->host=$info['host'] ?? 'localhost';
            $this->user=$info['user'] ?? 'root';
            $this->pwd=$info['pwd'] ?? 'root';
            $this->port=$info['port'] ?? '3306';
            $this->dbname=$info['dbname'] ?? 't1';
            $this->charset=$info['charset'] ?? 'utf8';
            //调用连接认证方法
            $this->sql_connet();
            //调用字符集方法
            $this->sql_charset();
        }
        //认证数据库连接
        public function sql_connet(){
            //利用mysqli属性可以跨方法访问:5个参数分别为:主机,用户,密码,数据库,端口
            $this->link=new mysqli($this->host,$this->user,$this->pwd,$this->dbname,$this->port);
            if($this->link->connect_errno){
                die( $this->link->connect_error);
            }
        }
        //设置字符集
        public function sql_charset(){
            $sql="set names {$this->charset}";
            //mysqli::query();
            $res=$this->link->query($sql);
            //有外部调用就会有错误,判断
            if(!$res){
                die('charset error'.$this->link->error);
            }
        }
    }
    
    $s=new Sql(array('charset'=>'utf-8'));    //会报错   应该是utf8
    var_dump($s);

    9.至此:数据库的初始化操作已经完成,此时要考虑的事情使用户调用数据库类是为了干什么?为了执行sql指令,也就是增删改查,在mysqli中所有的sql执行都是通过mysqli::query()方法执行

    但是我们可以根据需求封装两个函数,写方法和查方法(包含一条和多条查询)。

    <?php
    //数据库操作类
    class Sql{
    
        //设置属性
        public $host;
        public $user;
        public $pwd;
        public $port;
        public $dbname;
        public $charset;
        //增加一个属性来保存mysqli返回的连接(对象),需要跨方法使用
        public $link;
    
        //初始化构造方法
        public function __construct(array $info=array()){
            //这里的??表示为 $a=$c??$b 等同于 $a=isset($c)?$c:$b; 如果变量c存在就等于c否则等于b
            //以上功能只有php 版本7.0 以上可以用
            $this->host=$info['host'] ?? 'localhost';
            $this->user=$info['user'] ?? 'root';
            $this->pwd=$info['pwd'] ?? 'root';
            $this->port=$info['port'] ?? '3306';
            $this->dbname=$info['dbname'] ?? 't1';
            $this->charset=$info['charset'] ?? 'utf8';
            //调用连接认证方法
            $this->sql_connet();
            //调用字符集方法
            $this->link->set_charset($this->charset);
    
            // 调用字符集方法
            // $this->sql_charset();   //也是可以的
        }
        //认证数据库连接
        public function sql_connet(){
            //利用mysqli属性可以跨方法访问:5个参数分别为:主机,用户,密码,数据库,端口
            $this->link=new mysqli($this->host,$this->user,$this->pwd,$this->dbname,$this->port);
            if($this->link->connect_errno){
                die( $this->link->connect_error);
            }
        }
        // //设置字符集,这么写有点麻烦
        // public function sql_charset(){
        //     $sql="set names {$this->charset}";
        //     //mysqli::query();
        //     $res=$this->link->query($sql);
        //     //有外部调用就会有错误,判断
        //     if(!$res){
        //         die('charset error'.$this->link->error);
        //     }
        // }
    
    
        //写操作
        public function sql_insert($sql){
            $result=$this->link->query($sql);
            return $result;
        }
    }
    
    $s=new Sql();
    $sql="insert into b1 (name,age,sex) values ('杜家铭',9,'男')";
    $s->sql_insert($sql);
    <?php
    //数据库操作类
    class Sql{
    
        //设置属性
        public $host;
        public $user;
        public $pwd;
        public $port;
        public $dbname;
        public $charset;
        //增加一个属性来保存mysqli返回的连接(对象),需要跨方法使用
        public $link;
    
        //初始化构造方法
        public function __construct(array $info=array()){
            //这里的??表示为 $a=$c??$b 等同于 $a=isset($c)?$c:$b; 如果变量c存在就等于c否则等于b
            //以上功能只有php 版本7.0 以上可以用
            $this->host=$info['host'] ?? 'localhost';
            $this->user=$info['user'] ?? 'root';
            $this->pwd=$info['pwd'] ?? 'root';
            $this->port=$info['port'] ?? '3306';
            $this->dbname=$info['dbname'] ?? 't1';
            $this->charset=$info['charset'] ?? 'utf8';
            //调用连接认证方法
            $this->sql_connet();
            //调用字符集方法
            $this->link->set_charset($this->charset);
    
            // 调用字符集方法
            // $this->sql_charset();   //也是可以的
        }
        //认证数据库连接
        public function sql_connet(){
            //利用mysqli属性可以跨方法访问:5个参数分别为:主机,用户,密码,数据库,端口
            $this->link=new mysqli($this->host,$this->user,$this->pwd,$this->dbname,$this->port);
            if($this->link->connect_errno){
                die( $this->link->connect_error);
            }
        }
        // //设置字符集,这么写有点麻烦
        // public function sql_charset(){
        //     $sql="set names {$this->charset}";
        //     //mysqli::query();
        //     $res=$this->link->query($sql);
        //     //有外部调用就会有错误,判断
        //     if(!$res){
        //         die('charset error'.$this->link->error);
        //     }
        // }
    
    
        //写操作
        public function sql_insert($sql){
            $result=$this->link->query($sql);
            return $result;
        }
    
        //  读操作sql_select() 第一个参数为sql语句,第二个参数表示返回单条还是多条默认单条
        public function sql_select($sql,$all=false){
            $result=$this->link->query($sql);     
            if(!$all){
                // 获取一个数据
                return $result->fetch_assoc();
            }else{
                //获取所有数据
                return $result->fetch_all(MYSQLI_ASSOC);
            }
    
        }
    }
    
    $s=new Sql();
    $sql="select * from b1";
    print_r($s->sql_select($sql,true));

    10.上述已经完成了数据库类要实现的基本功能,实现sql指令的执行和结果返回,但是从功能细节的角度触发还需要进行完善,插入操作后,要获取自增长id,更新和删除操作受影响的行数,查询操作中

    记录数量。这种使可以通过设置方式来实现获取(自增长id),也可以通过增加属性来实现(属性简单)

    增加属性:受影响的行数,自增长id ,查询记录数

    <?php
    //数据库操作类
    class Sql{
    
        //设置属性
        public $host;
        public $user;
        public $pwd;
        public $port;
        public $dbname;
        public $charset;
        //增加一个属性来保存mysqli返回的连接(对象),需要跨方法使用
        public $link;
    
        //初始化构造方法
        public function __construct(array $info=array()){
            //这里的??表示为 $a=$c??$b 等同于 $a=isset($c)?$c:$b; 如果变量c存在就等于c否则等于b
            //以上功能只有php 版本7.0 以上可以用
            $this->host=$info['host'] ?? 'localhost';
            $this->user=$info['user'] ?? 'root';
            $this->pwd=$info['pwd'] ?? 'root';
            $this->port=$info['port'] ?? '3306';
            $this->dbname=$info['dbname'] ?? 't1';
            $this->charset=$info['charset'] ?? 'utf8';
            //调用连接认证方法
            $this->sql_connet();
            //调用字符集方法
            $this->link->set_charset($this->charset);
    
            // 调用字符集方法
            // $this->sql_charset();   //也是可以的
        }
        //认证数据库连接
        public function sql_connet(){
            //利用mysqli属性可以跨方法访问:5个参数分别为:主机,用户,密码,数据库,端口
            $this->link=new mysqli($this->host,$this->user,$this->pwd,$this->dbname,$this->port);
            if($this->link->connect_errno){
                die( $this->link->connect_error);
            }
        }
        // //设置字符集,这么写有点麻烦
        // public function sql_charset(){
        //     $sql="set names {$this->charset}";
        //     //mysqli::query();
        //     $res=$this->link->query($sql);
        //     //有外部调用就会有错误,判断
        //     if(!$res){
        //         die('charset error'.$this->link->error);
        //     }
        // }
    
    
        //写操作
        //自增id
        public $auto_id;
        public function sql_insert($sql){
            $result=$this->link->query($sql);
            //赋值受影响的自增列id
            $this->auto_id=$this->link->insert_id;
            return $result;
        }
    
        //  读操作sql_select() 第一个参数为sql语句,第二个参数表示返回单条还是多条默认单条
        //受影响行数
        public $rows;
        public function sql_select($sql,$all=false){
            $result=$this->link->query($sql);   
            // 赋值受影响的行数
            $this->rows=$result->num_rows; 
            if(!$all){
                // 获取一个数据
                return $result->fetch_assoc();
                //赋值受影响行数
            }else{
                //获取所有数据
                return $result->fetch_all(MYSQLI_ASSOC);
                //赋值受影响行数
            }
    
        }
    }
    
    // $s=new Sql();
    // $sql="insert into b1 (name,age,sex) values ('杜建',33,'女')";
    // $s->sql_insert($sql);
    // echo $s->auto_id;    //返回7   
    
    $s=new Sql();
    $sql="select * from b1 where id=7";
    print_r($s->sql_select($sql));
    echo '<hr>';
    echo $s->rows;
    
    
    
    
    
        
    ?>

    至此:数据库类的功能已经实现,接下里要考虑的定义规范:类对成员的控制性,

      属性如果不需要给外部访问   私有

      方法如果只是内部调用       私有

    总结:

      类的封装是以功能驱动为前提,相关操作存放到一个类中

      一个类通常是一个独立的文件,文件名与类名相同(方便后期维护和自动加载)

      类中如果有数据需要管理,设定属性(固定可以使用类常量)

      类中如果有功能需要实现,(数据加工)  设定方法

      一个功能通常使用一个方法实现,方法的颗粒度应该尽可能小   方便复用

  • 相关阅读:
    程序员高效学习
    红黑树(平衡操作详解)
    【设计模式】JDK源码中用到的设计模式
    pymysql.err.InternalError: (1205, 'Lock wait timeout exceeded; try restarting transaction')错误处理
    UPC:ABS
    洛谷:P1182:数列分段`Section II`
    python:数据库连接操作入门
    2018百度之星资格赛:1002:子串查询
    Educational Codeforces Round 48 (Rated for Div. 2)——A. Death Note ##
    python:pip命令使用
  • 原文地址:https://www.cnblogs.com/xiaowie/p/12237747.html
Copyright © 2011-2022 走看看