mirror of
https://gitee.com/fastadminnet/framework.git
synced 2026-07-01 12:42:48 +08:00
改进Model类
This commit is contained in:
@@ -18,6 +18,8 @@ class Model {
|
||||
const MODEL_BOTH = 3; // 包含上面两种方式
|
||||
// 当前数据库操作对象
|
||||
protected $db = null;
|
||||
// 数据库对象池
|
||||
private $_db = [];
|
||||
// 主键名称
|
||||
protected $pk = 'id';
|
||||
// 数据表前缀
|
||||
@@ -188,7 +190,7 @@ class Model {
|
||||
// 重置数据
|
||||
$this->data = [];
|
||||
}else{
|
||||
$this->error = L('_DATA_TYPE_INVALID_');
|
||||
$this->error = Lang::get('_DATA_TYPE_INVALID_');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -201,15 +203,22 @@ class Model {
|
||||
}
|
||||
// 写入数据到数据库
|
||||
$result = $this->db->insert($data,$options,$replace);
|
||||
if(false !== $result ) {
|
||||
if(false !== $result && is_numeric($result)) {
|
||||
$pk = $this->getPk();
|
||||
// 增加复合主键支持
|
||||
if (is_array($pk)) return $result;
|
||||
$insertId = $this->getLastInsID();
|
||||
if($insertId) {
|
||||
// 自增主键返回插入ID
|
||||
$data[$this->getPk()] = $insertId;
|
||||
$this->_after_insert($data,$options);
|
||||
$data[$pk] = $insertId;
|
||||
if(false === $this->_after_insert($data,$options)){
|
||||
return false;
|
||||
}
|
||||
return $insertId;
|
||||
}
|
||||
$this->_after_insert($data,$options);
|
||||
if(false === $this->_after_insert($data,$options)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
@@ -218,9 +227,9 @@ class Model {
|
||||
// 插入成功后的回调方法
|
||||
protected function _after_insert($data,$options) {}
|
||||
|
||||
public function addAll($dataList,$options=array(),$replace=false){
|
||||
public function addAll($dataList,$options=[],$replace=false){
|
||||
if(empty($dataList)) {
|
||||
$this->error = L('_DATA_TYPE_INVALID_');
|
||||
$this->error = Lang::get('_DATA_TYPE_INVALID_');
|
||||
return false;
|
||||
}
|
||||
// 数据处理
|
||||
@@ -254,33 +263,54 @@ class Model {
|
||||
// 重置数据
|
||||
$this->data = [];
|
||||
}else{
|
||||
$this->error = L('_DATA_TYPE_INVALID_');
|
||||
$this->error = Lang::get('_DATA_TYPE_INVALID_');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 数据处理
|
||||
$data = $this->_write_data($data);
|
||||
if(empty($data)){
|
||||
// 没有数据则不执行
|
||||
$this->error = Lang::get('_DATA_TYPE_INVALID_');
|
||||
return false;
|
||||
}
|
||||
// 分析表达式
|
||||
$options = $this->_parseOptions();
|
||||
if(false === $this->_before_update($data,$options)) {
|
||||
return false;
|
||||
}
|
||||
$pk = $this->getPk();
|
||||
if(!isset($options['where']) ) {
|
||||
// 如果存在主键数据 则自动作为更新条件
|
||||
if(isset($data[$this->getPk()])) {
|
||||
$pk = $this->getPk();
|
||||
$where[$pk] = $data[$pk];
|
||||
$options['where'] = $where;
|
||||
$pkValue = $data[$pk];
|
||||
if (is_string($pk) && isset($data[$pk])) {
|
||||
$where[$pk] = $data[$pk];
|
||||
unset($data[$pk]);
|
||||
}else{
|
||||
} elseif (is_array($pk)) {
|
||||
// 增加复合主键支持
|
||||
foreach ($pk as $field) {
|
||||
if(isset($data[$field])) {
|
||||
$where[$field] = $data[$field];
|
||||
} else {
|
||||
// 如果缺少复合主键数据则不执行
|
||||
$this->error = Lang::get('_OPERATION_WRONG_');
|
||||
return false;
|
||||
}
|
||||
unset($data[$field]);
|
||||
}
|
||||
}
|
||||
if(!isset($where)){
|
||||
// 如果没有任何更新条件则不执行
|
||||
$this->error = Lang::get('_OPERATION_WRONG_');
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
$options['where'] = $where;
|
||||
}
|
||||
}
|
||||
if(isset($options['where'][$pk])){
|
||||
$pkValue = $options['where'][$pk];
|
||||
}
|
||||
if(false === $this->_before_update($data,$options)) {
|
||||
return false;
|
||||
}
|
||||
$result = $this->db->update($data,$options);
|
||||
if(false !== $result) {
|
||||
if(false !== $result && is_numeric($result)) {
|
||||
if(isset($pkValue)) $data[$pk] = $pkValue;
|
||||
$this->_after_update($data,$options);
|
||||
}
|
||||
@@ -298,29 +328,53 @@ class Model {
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete($options=[]) {
|
||||
$pk = $this->getPk();
|
||||
if(empty($options) && empty($this->options['where'])) {
|
||||
// 如果删除条件为空 则删除当前数据对象所对应的记录
|
||||
if(!empty($this->data) && isset($this->data[$this->getPk()]))
|
||||
return $this->delete($this->data[$this->getPk()]);
|
||||
else
|
||||
if(!empty($this->data) && isset($this->data[$pk])){
|
||||
return $this->delete($this->data[$pk]);
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(is_numeric($options) || is_string($options)) {
|
||||
// 根据主键删除记录
|
||||
$pk = $this->getPk();
|
||||
if(strpos($options,',')) {
|
||||
$where[$pk] = ['IN', $options];
|
||||
}else{
|
||||
$where[$pk] = $options;
|
||||
}
|
||||
$pkValue = $where[$pk];
|
||||
$options = [];
|
||||
$options['where'] = $where;
|
||||
}
|
||||
// 根据复合主键删除记录
|
||||
if (is_array($options) && (count($options) > 0) && is_array($pk)) {
|
||||
$count = 0;
|
||||
foreach (array_keys($options) as $key) {
|
||||
if (is_int($key)) $count++;
|
||||
}
|
||||
if ($count == count($pk)) {
|
||||
$i = 0;
|
||||
foreach ($pk as $field) {
|
||||
$where[$field] = $options[$i];
|
||||
unset($options[$i++]);
|
||||
}
|
||||
$options['where'] = $where;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 分析表达式
|
||||
$options = $this->_parseOptions($options);
|
||||
$result= $this->db->delete($options);
|
||||
if(false !== $result) {
|
||||
if(empty($options['where'])){
|
||||
// 如果条件为空 不进行删除操作 除非设置 1=1
|
||||
return false;
|
||||
}
|
||||
if(isset($options['where'][$pk])){
|
||||
$pkValue = $options['where'][$pk];
|
||||
}
|
||||
$result = $this->db->delete($options);
|
||||
if(false !== $result && is_numeric($result)) {
|
||||
$data = [];
|
||||
if(isset($pkValue)) $data[$pk] = $pkValue;
|
||||
$this->_after_delete($data,$options);
|
||||
@@ -338,9 +392,9 @@ class Model {
|
||||
* @return mixed
|
||||
*/
|
||||
public function select($options=[]) {
|
||||
$pk = $this->getPk();
|
||||
if(is_string($options) || is_numeric($options)) {
|
||||
// 根据主键查询
|
||||
$pk = $this->getPk();
|
||||
if(strpos($options,',')) {
|
||||
$where[$pk] = ['IN',$options];
|
||||
}else{
|
||||
@@ -348,8 +402,24 @@ class Model {
|
||||
}
|
||||
$options = [];
|
||||
$options['where'] = $where;
|
||||
}elseif (is_array($options) && (count($options) > 0) && is_array($pk)) {
|
||||
// 根据复合主键查询
|
||||
$count = 0;
|
||||
foreach (array_keys($options) as $key) {
|
||||
if (is_int($key)) $count++;
|
||||
}
|
||||
if ($count == count($pk)) {
|
||||
$i = 0;
|
||||
foreach ($pk as $field) {
|
||||
$where[$field] = $options[$i];
|
||||
unset($options[$i++]);
|
||||
}
|
||||
$options['where'] = $where;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}elseif(false === $options){ // 用于子查询 不查询只返回SQL
|
||||
return $this->buildSql();
|
||||
$options['fetch_sql'] = true;
|
||||
}
|
||||
|
||||
// 分析表达式
|
||||
@@ -358,7 +428,7 @@ class Model {
|
||||
if(isset($options['cache'])){
|
||||
$cache = $options['cache'];
|
||||
$key = is_string($cache['key'])?$cache['key']:md5(serialize($options));
|
||||
$data = S($key,'',$cache);
|
||||
$data = Cache::get($key,'',$cache);
|
||||
if(false !== $data){
|
||||
return $data;
|
||||
}
|
||||
@@ -390,7 +460,7 @@ class Model {
|
||||
}
|
||||
|
||||
if(isset($cache)){
|
||||
S($key,$resultSet,$cache);
|
||||
Cache::set($key,$resultSet,$cache);
|
||||
}
|
||||
|
||||
return $resultSet;
|
||||
@@ -496,11 +566,30 @@ class Model {
|
||||
* @return mixed
|
||||
*/
|
||||
public function find($options=[]) {
|
||||
$pk = $this->getPk();
|
||||
if(is_numeric($options) || is_string($options)) {
|
||||
$where[$this->getPk()] = $options;
|
||||
$where[$pk] = $options;
|
||||
$options = [];
|
||||
$options['where'] = $where;
|
||||
}
|
||||
// 根据复合主键查找记录
|
||||
if (is_array($options) && is_array($pk) && (count($options) > 0) ) {
|
||||
// 根据复合主键查询
|
||||
$count = 0;
|
||||
foreach (array_keys($options) as $key) {
|
||||
if (is_int($key)) $count++;
|
||||
}
|
||||
if ($count == count($pk)) {
|
||||
$i = 0;
|
||||
foreach ($pk as $field) {
|
||||
$where[$field] = $options[$i];
|
||||
unset($options[$i++]);
|
||||
}
|
||||
$options['where'] = $where;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 总是查找一条记录
|
||||
$options['limit'] = 1;
|
||||
// 分析表达式
|
||||
@@ -509,7 +598,7 @@ class Model {
|
||||
if(isset($options['cache'])){
|
||||
$cache = $options['cache'];
|
||||
$key = is_string($cache['key'])?$cache['key']:md5(serialize($options));
|
||||
$data = S($key,'',$cache);
|
||||
$data = Cache::get($key,'',$cache);
|
||||
if(false !== $data){
|
||||
$this->data = $data;
|
||||
return $data;
|
||||
@@ -530,7 +619,7 @@ class Model {
|
||||
// 数据对象赋值
|
||||
$this->data = $data;
|
||||
if(isset($cache)){
|
||||
S($key,$data,$cache);
|
||||
Cache::set($key,$data,$cache);
|
||||
}
|
||||
return $this->data;
|
||||
}
|
||||
@@ -573,7 +662,7 @@ class Model {
|
||||
}
|
||||
// 验证数据
|
||||
if(empty($data) || !is_array($data)) {
|
||||
$this->error = L('_DATA_TYPE_INVALID_');
|
||||
$this->error = Lang::get('_DATA_TYPE_INVALID_');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -620,24 +709,20 @@ class Model {
|
||||
if(''===$linkNum && $this->db) {
|
||||
return $this->db;
|
||||
}
|
||||
static $_linkNum = [];
|
||||
static $_db = [];
|
||||
if(!isset($_db[$linkNum]) || (isset($_db[$linkNum]) && $config && $_linkNum[$linkNum]!=$config) ) {
|
||||
if(!isset($this->_db[$linkNum])) {
|
||||
// 创建一个新的实例
|
||||
if(!empty($config) && is_string($config) && false === strpos($config,'/')) { // 支持读取配置参数
|
||||
$config = C($config);
|
||||
$config = Config::get($config);
|
||||
}
|
||||
$_db[$linkNum] = Db::instance($config);
|
||||
$this->_db[$linkNum] = Db::instance($config);
|
||||
}elseif(null === $config){
|
||||
$_db[$linkNum]->close(); // 关闭数据库连接
|
||||
unset($_db[$linkNum]);
|
||||
$this->_db[$linkNum]->close(); // 关闭数据库连接
|
||||
unset($this->_db[$linkNum]);
|
||||
return ;
|
||||
}
|
||||
|
||||
// 记录连接信息
|
||||
$_linkNum[$linkNum] = $config;
|
||||
// 切换数据库连接
|
||||
$this->db = $_db[$linkNum];
|
||||
$this->db = $this->_db[$linkNum];
|
||||
$this->_after_db();
|
||||
return $this;
|
||||
}
|
||||
@@ -737,7 +822,18 @@ class Model {
|
||||
// 记录字段类型
|
||||
$type[$key] = $val['type'];
|
||||
if($val['primary']) {
|
||||
$this->fields['_pk'] = $key;
|
||||
// 增加复合主键支持
|
||||
if (!empty($this->fields['_pk'])) {
|
||||
if (is_string($this->fields['_pk'])) {
|
||||
$this->pk = array($this->fields['_pk']);
|
||||
$this->fields['_pk'] = $this->pk;
|
||||
}
|
||||
$this->pk[] = $key;
|
||||
$this->fields['_pk'][] = $key;
|
||||
} else {
|
||||
$this->pk = $key;
|
||||
$this->fields['_pk'] = $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 记录字段类型信息
|
||||
@@ -756,24 +852,56 @@ class Model {
|
||||
* SQL查询
|
||||
* @access public
|
||||
* @param string $sql SQL指令
|
||||
* @param array $bind 参数绑定
|
||||
* @param mixed $parse 是否需要解析SQL
|
||||
* @return mixed
|
||||
*/
|
||||
public function query($sql,$bind=[]) {
|
||||
$sql = strtr($sql,['__TABLE__'=>$this->getTableName(),'__PREFIX__'=>$this->tablePrefix]);
|
||||
return $this->db->query($sql,$bind);
|
||||
public function query($sql,$parse=false) {
|
||||
if(!is_bool($parse) && !is_array($parse)) {
|
||||
$parse = func_get_args();
|
||||
array_shift($parse);
|
||||
}
|
||||
$sql = $this->parseSql($sql,$parse);
|
||||
return $this->db->query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行SQL语句
|
||||
* @access public
|
||||
* @param string $sql SQL指令
|
||||
* @param array $bind 参数绑定
|
||||
* @param mixed $parse 是否需要解析SQL
|
||||
* @return false | integer
|
||||
*/
|
||||
public function execute($sql,$bind=[]) {
|
||||
$sql = strtr($sql,['__TABLE__'=>$this->getTableName(),'__PREFIX__'=>$this->tablePrefix]);
|
||||
return $this->db->execute($sql,$bind);
|
||||
public function execute($sql,$parse=false) {
|
||||
if(!is_bool($parse) && !is_array($parse)) {
|
||||
$parse = func_get_args();
|
||||
array_shift($parse);
|
||||
}
|
||||
$sql = $this->parseSql($sql,$parse);
|
||||
return $this->db->execute($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析SQL语句
|
||||
* @access public
|
||||
* @param string $sql SQL指令
|
||||
* @param boolean $parse 是否需要解析SQL
|
||||
* @return string
|
||||
*/
|
||||
protected function parseSql($sql,$parse) {
|
||||
// 分析表达式
|
||||
if(true === $parse) {
|
||||
$options = $this->_parseOptions();
|
||||
$sql = $this->db->parseSql($sql,$options);
|
||||
}elseif(is_array($parse)){ // SQL预处理
|
||||
$parse = array_map(array($this->db,'escapeString'),$parse);
|
||||
$sql = vsprintf($sql,$parse);
|
||||
}else{
|
||||
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>$this->tablePrefix));
|
||||
$prefix = $this->tablePrefix;
|
||||
$sql = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $sql);
|
||||
}
|
||||
$this->db->setModel($this->name);
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -791,7 +919,7 @@ class Model {
|
||||
}elseif(is_string($data)){
|
||||
parse_str($data,$data);
|
||||
}elseif(!is_array($data)){
|
||||
E(L('_DATA_TYPE_INVALID_'));
|
||||
E(Lang::get('_DATA_TYPE_INVALID_'));
|
||||
}
|
||||
$this->data = $data;
|
||||
return $this;
|
||||
@@ -848,7 +976,7 @@ class Model {
|
||||
$options = $union;
|
||||
}
|
||||
}else{
|
||||
E(L('_DATA_TYPE_INVALID_'));
|
||||
E(Lang::get('_DATA_TYPE_INVALID_'));
|
||||
}
|
||||
$this->options['union'][] = $options;
|
||||
return $this;
|
||||
@@ -1104,6 +1232,28 @@ class Model {
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对数据集进行索引
|
||||
* @access public
|
||||
* @param string $index 索引名称
|
||||
* @return Model
|
||||
*/
|
||||
public function index($index){
|
||||
$this->options['index'] = $index;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定强制索引
|
||||
* @access public
|
||||
* @param string $force 索引名称
|
||||
* @return Model
|
||||
*/
|
||||
public function force($force){
|
||||
$this->options['force'] = $force;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数绑定
|
||||
* @access public
|
||||
|
||||
Reference in New Issue
Block a user