zoukankan      html  css  js  c++  java
  • TP6中数据库操作

    TP6中数据库操作

    要使用Db类必须使用门面方式(thinkfacadeDb)调用

    use thinkfacadeDb;

    一、数据库连接配置

    配置文件位于,config/database.php

    或者开发环境 位于根目录下的 .env 文件

    APP_DEBUG = true
    [APP]
    DEFAULT_TIMEZONE = Asia/Shanghai
    [DATABASE]
    TYPE = mysql  //数据库类型  
    HOSTNAME = 127.0.0.1 //连接地址
    DATABASE = test  //数据库名称
    USERNAME = username  //数据库用户名
    PASSWORD = password  //数据库密码
    HOSTPORT = 3306  //端口
    CHARSET = utf8  //字符集
    DEBUG = true   //是否开启debug
    [LANG]
    default_lang = zh-cn
    动态配置数据库连接查询

    	hinkfacadeDb::connect('demo')->table('user')->find();
    数据模型中定义connection属性

    protected $connection = 'demo';
    ThinkPHP的数据库连接是惰性的,只有实际的数据操作的时候才会去连接数据库。

    二、数据库分布式支持

    如果需要支持分布式数据库,包括读写分离,需要设置配置参数 deploy 的值为 1

    // 启用分布式数据库
    'deploy'    =>  1,
    'hostname'  => '192.168.1.1,192.168.1.2', //默认情况下第一个地址就是主服务器
    // 数据库用户名
    'username' => 'root,slave,slave',
    // 数据库密码
    'password' => '123456',
    关于 hostname,username,password,hostport,database,dsn,charset 要么值相同就配置一个,不然就分别设置

    建议使用数组定义参数,例如:

    'hostname' =>[ '192.168.1.1','192.168.1.2','192.168.1.3'],
    'password' => ['123456','abc,def','hello']

    三、数据库支持读写分离

    开启读写分类配置:

    'rw_separate' => true,
    默认第一个是主数据库,负责写入数据。如果设置 master_num ,则可以支持多个主服务器写入。

    如果用原生SQL,写操作必须用 execute 方法,读操作必须用 query方法

    刚写入数据之后,从库数据还没来得及同步完成,你可以使用 master() 进行主库查询

    Db::name('user')->master(true)->find(1);
    也可以开启:当我们对某个数据表进行了写操作,那么当前请求的后续所有对该表的查询都会使用主库读取

    'read_master' => true,

    四、链式操作

    查询单个数据
    Db::table('think_user')->where('id', 1)->find();
    查询为空返回空数组
    Db::table('think_user')->where('id', 1)->findOrEmpty();
    说明:
    如果没有任何的查询条件,也没有调用order方法的话 ,find查询不会返回任何结果。

    查询结果集:

    Db::table('think_user')->where('status', 1)->select();

     select 方法查询结果是一个数据集对象,如果需要转换为数组可以使用

    Db::table('think_user')->where('status', 1)->select()->toArray();

     查询一个字段

    Db::table('think_user')->where('id', 1)->value('name');

     查询一列

    // 返回数组
    Db::table('think_user')->where('status',1)->column('name');
    // 指定id字段的值作为索引
    Db::table('think_user')->where('status',1)->column('name', 'id');

     添加数据:

    $data = ['foo' => 'bar', 'bar' => 'foo'];
    Db::name('user')->save($data);
    或
    Db::name('user')->insert($data);

     使用save方法时,数据中有ID则为更新,没有ID则为新增

    insert 方法添加数据成功返回添加成功的条数,通常情况返回 1
     
    如果不希望因为存在数据表中没有的字段而抛出异常,可以使用以下方法

    Db::name('user')->strict(false)->insert($data);

     添加后返回主键

    $userId = Db::name('user')->strict(false)->insertGetId($data);

     更新数据:

    Db::name('user')->save(['id' => 1, 'name' => 'thinkphp']);
    或
    Db::name('user')->where('id', 1)->update(['name' => 'thinkphp']);

     支持表达式更新

    Db::name('user')->where('id',1)->exp('name','UPPER(name)')->update();
    或使用raw
    Db::name('user')->where('id', 1)->update([
            'name'    =>    Db::raw('UPPER(name)'),
            'score'    =>    Db::raw('score-3'),
            'read_time'    =>    Db::raw('read_time+1')
        ]);

     自增自减

    // score 字段加 1
    Db::table('think_user')->where('id', 1)->inc('score')->update();
    // score 字段加 5
    Db::table('think_user')->where('id', 1)->inc('score', 5)->update();
    // score 字段减 1
    Db::table('think_user')->where('id', 1)->dec('score')->update();
    // score 字段减 5
    Db::table('think_user')->where('id', 1)->dec('score', 5)->update();
    删除数据:
    // 根据主键删除
    Db::table('think_user')->delete(1);
    Db::table('think_user')->delete([1,2,3]);
    
    // 条件删除    
    Db::table('think_user')->where('id',1)->delete();
    Db::table('think_user')->where('id','<',10)->delete();

    没有任何条件调用delete会返回错误。如果确实需要删除所有数据,可以使用

    // 无条件删除所有数据
    Db::name('user')->delete(true);

     查询表达式:

     格式如下:

    where('字段名','查询表达式','查询条件');
    // = 等于
    Db::name('user')->where('id','=',100)->select();    
    //<> 不等于
    Db::name('user')->where('id','<>',100)->select();
    //>    大于
    Db::name('user')->where('id','>',100)->select();    
    //>=    大于等于    
    Db::name('user')->where('id','>=',100)->select();
    //<    小于
    Db::name('user')->where('id', '<', 100)->select();    
    <=    小于等于
    Db::name('user')->where('id', '<=', 100)->select();
    //[NOT] LIKE 模糊查询
    Db::name('user')->where('name', 'like', 'thinkphp%')->select();
    //[NOT] BETWEEN    (不在)区间查询    
    Db::name('user')->where('id','between','1,8')->select();
    //[NOT] IN    (不在)IN 查询
    Db::name('user')->where('id','in','1,5,8')->select();
    或
    Db::name('user')->where('id','in',[1,5,8])->select();
    //[NOT] NULL :
    Db::name('user')->where('name', null)->where('email','null')
    ->where('name','not null')->select();

     链式操作示例:

    Db::table('think_user')
        ->where('status',1)
        ->order('create_time')
        ->limit(10)
        ->select();
    链式where条件:

    //1、表达式条件
    Db::table('think_user')->where('id','>',1)->where('name','thinkphp')->select(); 
    
    //2、数组条件
    Db::table('think_user')->where(['name'=>'thinkphp','status'=>1])->select(); 
    //3、字符串条件
    Db::table('think_user')->whereRaw('type=1 AND status=1')->select(); 
    或需要传入变量,配合预处理机制,确保更加安全
    Db::table('think_user')
    ->whereRaw("id=:id and username=:name", ['id' => 1 , 'name' => 'thinkphp'])
    ->select();
    链式table操作

    Db::field('user.name,role.title')
    ->table([
        'think_user'=>'user',
        'think_role'=>'role'
    ])
    ->limit(10)->select();
    链式alias操作,设置表的别名

    Db::table('think_user')
    ->alias('a')
    ->join('think_dept b ','b.user_id= a.id')
    ->select();
    field操作

    Db::table('user')->field('id,title,content')->select();
    或使用别名
    Db::table('user')->field('id,nickname as name')->select();
    或使用SQL函数
    Db::table('user')->fieldRaw('id,SUM(score)')->select();
    strict操作

    提交了非法字段会抛出异常,可以在配置中关闭严格字段检查

    'fields_strict'    =>    false,
    也可以临时关闭

    // 关闭字段严格检查
    Db::name('user')->strict(false)->insert($data);
    limit操作

    //获取满足要求的10个用户
    Db::table('user')->where('status',1)->field('id,name')->limit(10)->select();
    //limit方法也可以用于写操作,例如更新满足要求的3条数据:
    Db::table('user')->where('score',100)->limit(3)->update(['level'=>'A']);
    
    //分页查询,查询从第20行开始的10条数据
    Db::table('article')->limit(20,10)->select();
    page操作

    // 查询第一页数据
    Db::table('article')->page(1,10)->select(); 
    // 查询第二页数据
    Db::table('article')->page(2,10)->select(); 
    order操作

    //没有指定排序规则,默认 asc
    Db::table('user')->where('status', 1)->order('id')->select();
    //指定排序规则
    Db::table('user')->where('status', 1)->order('id', 'desc')->select();
    group操作

    通常用于结合合计函数,根据一个或多个列对结果集进行分组。

    Db::table('user')->field('user_id,username,max(score)')
        ->group('user_id')->select();
    对多个字段进行分组
    Db::table('user')->field('user_id,test_time,username,max(score)')
        ->group('user_id,test_time')->select();
    having操作

    Db::table('score')
        ->field('username,max(score)')->group('user_id')
        ->having('count(test_time)>3')->select(); 
    join操作

    INNER JOIN: 等同于 JOIN(默认的JOIN类型),如果表中有至少一个匹配,则返回行
    LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行
    RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行
    FULL JOIN: 只要其中一个表中存在匹配,就返回行
    //join 方式
    Db::table('think_artist')
    ->alias('a')
    ->join('work w','a.id = w.artist_id')
    ->join('card c','a.card_id = c.id')
    ->select();
    //left join 方式
    Db::table('think_user')
    ->alias('a')
    ->leftJoin('word w','a.id = w.artist_id')
    ->select();

    五、聚合查询

    count:Db::table('think_user')->count();
    max:Db::table('think_user')->max('score');
    min:Db::table('think_user')->min('score');
    avg: Db::table('think_user')->avg('score');
    sum: Db::table('think_user')->sum('score');

    六、分页查询

     控制器代码:

    // 查询状态为1的用户数据 并且每页显示10条数据
    $list = Db::name('user')->where('status',1)->order('id', 'desc')->paginate(10);
    // 获取分页显示
    $page = $list->render();
    return view('index', ['list' => $list, 'page' => $page]);

     HTML代码:

    <div>
    <ul>
    {volist name='list' id='user'}
        <li> {$user.nickname}</li>
    {/volist}
    </ul>
    </div>
    {$page|raw}
    获取总数据

    // 获取总记录数
    $count = $list->total();
    分页后数据处理

    $list = Db::name('user')->where('status',1)->order('id', 'desc')
    ->paginate()->each(function($item, $key){
        $item['nickname'] = 'think';
        return $item;
    });
    模型中分页数据处理,无需return

    $list = User::where('status',1)->order('id', 'desc')->paginate()->each(function($item, $key){
        $item->nickname = 'think';
    });
    分页参数:

    $list = Db::name('user')->where('status',1)->paginate([
        'list_rows'=> 20,
        'query'    => $data
    ]);

    七、时间查询 whereTime

    // 大于某个时间
    Db::name('user')->whereTime('birthday', '>=', '1970-10-1')->select();
    // 小于某个时间
    Db::name('user')->whereTime('birthday', '<', '2000-10-1')->select();
    // 时间区间查询
    Db::name('user')->whereTime('birthday', 'between', ['1970-10-1', '2000-10-1'])
        ->select();
    // 不在某个时间区间
    Db::name('user')->whereTime('birthday', 'not between', ['1970-10-1', '2000-10-1'])
        ->select();

    八、原生查询

    V6.0.3+版本开始,原生查询仅支持Db类操作

    query方法

    Db::query("select * from think_user where status=:id", ['id' => 1]);
    //从主库读取
    Db::query("select * from think_user where status=:id", ['id' => 1], true);
    execute方法

    Db::execute("update think_user set name='thinkphp' where status=1");
    参数绑定

    //问号占位符绑定
    Db::query("select * from think_user where id=? AND status=?", [8, 1]);
    // 命名绑定
    Db::execute("update think_user set name=:name where status=:status",
     ['name' => 'thinkphp', 'status' => 1]);
     //注意不支持对表名使用参数绑定

    九:事务操作

    使用事务处理的话,需要数据库引擎支持事务处理。比如 MySQL 的 MyISAM 不支持事务处理,需要使用 InnoDB 引擎。

    最简单的事务闭包操作:

    Db::transaction(function () {
        Db::table('think_user')->find(1);
        Db::table('think_user')->delete(1);
    });
    手动运行事务:

    // 启动事务
    Db::startTrans();
    try {
        Db::table('think_user')->find(1);
        Db::table('think_user')->delete(1);
        // 提交事务
        Db::commit();
    } catch (Exception $e) {
        // 回滚事务
        Db::rollback();
    }

    十:存储过程

    //数据访问层调用存储过程
    $resultSet = Db::query('call procedure_name');
    foreach ($resultSet as $result) {
    
    }
    
    //存储过程可以支持输入和输出参数,以及进行参数绑定操作。
    $resultSet = Db::query('call procedure_name(:in_param1,:in_param2,:out_param)', [
        'in_param1' => $param1,
        'in_param2' => [$param2, PDO::PARAM_INT],
        'out_param' => [$outParam, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 4000],
    ]);
    数据集:

    // 获取数据集
    $users = Db::name('user')->select();
    // 直接操作第一个元素
    $item  = $users[0];
    // 获取数据集记录数
    $count = count($users);
    // 遍历数据集
    foreach($users as $user){
        echo $user['name'];
        echo $user['id'];
    }
    判断数据集是否为空,不能直接使用empty判断,而必须使用数据集对象的isEmpty方法判断,

    $users = Db::name('user')->select();
    if($users->isEmpty()){
        echo '数据集为空';
    }

    但行好事,莫问前程!

    本文来自博客园,作者:yangphp,转载请注明原文链接:https://www.cnblogs.com/ypeih/p/15509092.html

  • 相关阅读:
    第一次冲次(补)
    软件工程概论个人总结
    第16周进度条
    读《梦断代码》第2章有感
    java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver
    传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确。参数 1 (""): 数据类型 0x38 未知。
    怎么卸载VS2005呢?控制面板里内容太多,找不出哪些是属于VS2005?我的VS2005出问题了
    常用正则表达式的写法
    Http响应头字段详解,MyEclipse配置tomcat,servlet运行方式
    html框架 字体颜色 列表 表格 图片 定义列表 a标签
  • 原文地址:https://www.cnblogs.com/ypeih/p/15509092.html
Copyright © 2011-2022 走看看