写多条SQL语句来实现对数据库的操作,那确实是件比较繁琐的事情,但是如果有了自定义的SQL生成器便可以在壹定程度上提高开发效率。
/*
Navicat Premium Data Transfer
Source Server : MariaDB
Source Server Type : MariaDB
Source Server Version : 100411
Source Host : localhost:3306
Source Schema : ankium
Target Server Type : MariaDB
Target Server Version : 100411
File Encoding : 65001
Date: 20/03/2020 18:04:53
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for news
-- ----------------------------
DROP TABLE IF EXISTS `news`;
CREATE TABLE `news` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`author` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 40 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of news
-- ----------------------------
INSERT INTO `news` VALUES (1, 'ankium.com', '云已', 'C#图解教程');
INSERT INTO `news` VALUES (2, 'ankium.omc', '文文', 'C#高级编程');
INSERT INTO `news` VALUES (3, 'ankium.moc', '云文', 'C#核心指南');
SET FOREIGN_KEY_CHECKS = 1;
namespace Database;
use PDO;
use Exception;
class DB
{
protected $link;
protected $options = ['table' => '', 'field' => '*', 'order' => '', 'limit' => '', 'where' => ''];
public function __construct(array $config)
{
$this->connect($config);
}
//PDO连接
protected function connect(array $config)
{
$dsn = sprintf(
'mysql:host=%s;dbname=%s;charset=%s',
$config['host'],
$config['dbname'],
$config['charset']
);
$this->link = new PDO($dsn, $config['user'], $config['password']);
$this->link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$this->link->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL);
}
//预准备查询
public function query(string $sql, array $vars = [])
{
$sth = $this->link->prepare($sql);
$sth->execute($vars);
return $sth->fetchAll(PDO::FETCH_ASSOC);
}
//预准备执行
public function execute(string $sql, array $vars = [])
{
$sth = $this->link->prepare($sql);
return $sth->execute($vars);
}
//构建SQL组件
public function table(string $table)
{
$this->options['table'] = $table;
return $this;
}
public function field(...$fields)
{
$this->options['field'] = '`' . implode('`,`', $fields) . '`';
return $this;
}
public function limit(...$limit)
{
$this->options['limit'] = " LIMIT " . implode(',', $limit);
return $this;
}
public function order(string $order)
{
$this->options['order'] = "ORDER BY " . $order;
return $this;
}
public function where(string $where)
{
$this->options['where'] = " WHERE " . $where;
return $this;
}
//查询
public function select()
{
//EX:SELECT * FROM news WHERE ORDER LIMIT 1
$sql = "SELECT {$this->options['field']} FROM {$this->options['table']}{$this->options['where']}{$this->options['order']}{$this->options['limit']}";
return $this->query($sql);
}
//增加
public function insert(array $vars)
{
//EX:INSERT INTO news ('title','author') VALUES (?,?)
$fields = '`' . implode('`,`', array_keys($vars)) . '`';
$values = implode(',', array_fill(0, count($vars), '?'));
$sql = "INSERT INTO {$this->options['table']} ($fields) VALUES ($values)";
return $this->execute($sql, array_values($vars));
}
//更新
public function update(array $vars)
{
//EX:UPDATE news SET title=?,author=? WHERE ...
if (empty($this->options['where'])) {
throw new Exception("更新必须设置条件");
}
$sql = "UPDATE {$this->options['table']} SET " . implode('=?,', array_keys($vars)) . "=? {$this->options['where']}";
return $this->execute($sql, array_values($vars));
}
//删除
public function delete()
{
//EX:DELETE FROM news WHERE
if (empty($this->options['where'])) {
throw new Exception("删除必须设置条件");
}
$sql = "DELETE FROM {$this->options['table']} {$this->options['where']}";
return $this->execute($sql);
}
}
DB处理类主要做的事情:通过PDO方式连接数据库(Connect方法实现)、预准备(包括查询和执行,目的是将解析与参数分开处理,可以有效的防止SQL注入)、构建SQL组件、提供增删改查方法以供外部调用。
use Database\DB;
include "database.php";
header("Content-type:text/html;charset=utf8");
$config = [
'host'=>'127.0.0.1',
'user'=>'root',
'password'=>'123456',
'dbname'=>'ankium',
'charset'=>'utf8'
];
try {
$db = new DB($config);
//更新操作
$db->table('news')->where('id>20')->update(['title'=>'三年级','author'=>'郭明']);
//添加操作
$db->table('news')->insert(['title'=>'万里','author'=>'无云']);
//查询操作
$rows = $db->table('news')->limit(1)->select();
print_r($rows);
//删除操作
$db->table('news')->where('id>4')->delete();
}catch(Exception $e){
die($e->getMessage());
}
在定义DB处理类的SQL组件方法时指定返回值都是当前对象,所以在调用的时候可以通过链式操作完成。