Yii数据库操作方法指南

CDbConnection: 一个抽象数据库连接

CDbCommand: SQL statement
CDbDataReader: 匹配结果集的一行记录
CDbTransaction:数据库事务

访问数据库前需要建立数据库连接;使用DAO建立一个抽象数据库链接:
connection=newCDbConnection(connection=newCDbConnection(dsn, username,username,password);
connection>active=true;//使connection>active=true;//使connection->active = false;  // 关闭连接 

CDbConnection继承自CApplicationComponent,所以他可以像组件一样在任何地方使用。因此可以这样访问:
Yii::app()->db  

//执行SQL语句需要CDbCommand对象,而该对象由CdbConnection::createCommand()返回,因此:
connection=Yii::app()>db;connection=Yii::app()>db;command=connection>createCommand(connection>createCommand(sql);
// 如果SQL语句想要完全有自己写,可以这样:
newSQL=SQL;newSQL=SQL;command->text=newSQL;//CDbCommandexecute()SQLquery()SELECT//execute()INSERT,UPDATEandDELETE//query()CDbDataReader使CDbDataReadernewSQL;//CDbCommandexecute()SQLquery()SELECT//execute()INSERT,UPDATEandDELETE//query()CDbDataReader使CDbDataReaderrowCount=command>execute();//executethenonquerySQLcommand>execute();//executethenonquerySQLdataReader=command>query();//executeaquerySQL//CDbDataReadercommand>query();//executeaquerySQL//CDbDataReaderrows=command>queryAll();//queryandreturnallrowsofresultcommand>queryAll();//queryandreturnallrowsofresultrow=command>queryRow();//queryandreturnthefirstrowofresultcommand>queryRow();//queryandreturnthefirstrowofresultcolumn=command>queryColumn();//queryandreturnthefirstcolumnofresultcommand>queryColumn();//queryandreturnthefirstcolumnofresultvalue=command>queryScalar();//queryandreturnthefirstfieldinthefirstrow//query()command>queryScalar();//queryandreturnthefirstfieldinthefirstrow//query()dataReader=command>query();//CDbDataReader::read()falsewhile((command>query();//CDbDataReader::read()falsewhile((row=dataReader>read())!==false)//CDbDataReader使foreachforeach(dataReader>read())!==false)//CDbDataReader使foreachforeach(dataReader as row)//()row)//()rows=dataReader>readAll();queryXXX()query()//YIICDbTransaction//dataReader>readAll();queryXXX()query()//YIICDbTransaction//connection = Yii::app()->db;
// 第二,开始事务
transaction=transaction=connection->beginTransaction();
// 第三,执行SQL,如果错误就抛出异常,在异常处理中回滚。
try
{
connection>createCommand(connection>createCommand(sql1)->execute();
connection>createCommand(connection>createCommand(sql2)->execute();
//.... other SQL executions
// 如果SQL执行都没有抛出异常,那就提交。
transaction->commit();  } catch(Exceptiontransaction->commit();  } catch(Exceptione) {
    [Math Processing Error]connection = Yii::app()->db;
// 第二,写下无敌的SQL语句,比如:
sql="INSERTINTOtbluser(username,email)VALUES(:username,:email)";//CDbCommandSQLsql="INSERTINTOtbluser(username,email)VALUES(:username,:email)";//CDbCommandSQLcommand=connection>createCommand(connection>createCommand(sql);
// 接下来,将SQL语句中的形式参数,替换为实际参数
command>bindParam(":username",command>bindParam(":username",username,PDO::PARAM STR);   // 这与PDO有点不同,PDO中不带冒号
command>bindParam(":email",command>bindParam(":email",email,PDO::PARAM STR);    // 同样
// 最后,执行
command>execute();////使CDbDataReaderbindColumn()PHP//PHP//command>execute();////使CDbDataReaderbindColumn()PHP//PHP//connection = Yii::app()->db;
sql="SELECTusername,emailFROMtbluser";sql="SELECTusername,emailFROMtbluser";dataReader = connection>createCommand(connection>createCommand(sql)->query();    //很赞的方法链, 可惜不能接着.each()
dataReader>bindColumn(1,dataReader>bindColumn(1,username);  //第一列值绑定到usernameusernamedataReader->bindColumn(2, email);//email);//email
//接着循环读取并操作数据
while( dataReader>read()!==false)...//while(($row=$dataReader>read())!==false)//使CDbConnection::tablePrefix////YiiSQLdataReader>read()!==false)...//while(($row=$dataReader>read())!==false)//使CDbConnection::tablePrefix////YiiSQLuser = Yii::app()->db->createCommand();    
        ->select('id, username, profile')
        ->from('tbl_user u')
        ->join('tbl_profile p', 'u.id=p.user_id')
        ->where('id=:id', array(':id'=>id)>queryRow();////id)>queryRow();////newSQL ='SELECT id, username, profile from tbl_user u INNER JOIN tbl_profile p ON u.id = p.user_id WHERE u.id =:id'

// yii提供了一种构建SQL的机制(也就是说不用自己写长长的SQL)
// 首相要实例化一个CDbCommand对象
command=Yii::app()>db>createCommand();////>select():SELECT>selectDistinct():SELECT>from():FROM>where():WHERE>join():FROMINNERJOIN>leftJoin():FROM>rightJoin():FROM>crossJoin():()>naturalJoin():>group():GROUPBY>having():WHEREGROUPBY>order():ORDERBY>limit():LIMIT>offset():LIMIT>union():appendsaUNIONqueryfragmentselect()//select(username,email);//使使select(tbluser.id,usernamename);//使select(array(id,count()asnum));//使form()使SQLfrom(tbluser,tblpost,tblprofile);//使,使from(tbluseru,public.tblprofilep);WHERE//where()使ANDwhere(array(and,id=:id,username=:username),array(:id=>command=Yii::app()>db>createCommand();////>select():SELECT>selectDistinct():SELECT>from():FROM>where():WHERE>join():FROMINNERJOIN>leftJoin():FROM>rightJoin():FROM>crossJoin():()>naturalJoin():>group():GROUPBY>having():WHEREGROUPBY>order():ORDERBY>limit():LIMIT>offset():LIMIT>union():appendsaUNIONqueryfragmentselect()//select(username,email);//使使select(tbluser.id,usernamename);//使select(array(id,count()asnum));//使form()使SQLfrom(tbluser,tblpost,tblprofile);//使,使from(tbluseru,public.tblprofilep);WHERE//where()使ANDwhere(array(and,id=:id,username=:username),array(:id=>id, ':username'=>[Math Processing Error]id, ':username'=>username));//INwhere(array(in,id,array(1,2,3)))//LIKEwhere(array(like,name,username));//INwhere(array(in,id,array(1,2,3)))//LIKEwhere(array(like,name,keyword=GET[q];//escapeGET[q];//escapekeyword=strtr(keyword,array(keyword,array(command->where(array('like', 'title', '%'.keyword.keyword.command = Yii::app()->db->createCommand();
users=users=command->select('*')->from('tbl_users')->queryAll();
command>reset();//cleanupthepreviousquerycommand>reset();//cleanupthepreviousqueryposts = command>select()>from(tblposts)>queryAll();///YIISQL//ActiveRecord//使AR访ARORM//Posttblpost使command>select()>from(tblposts)>queryAll();///YIISQL//ActiveRecord//使AR访ARORM//Posttblpost使post = new Post();
post>title=newtitle;post>title=newtitle;post->content = 'new content';
[Math Processing Error]post = new Post;
post>title=samplepost;post>title=samplepost;post->content = 'content for the sample post';
post>createtime=time();post>createtime=time();post->save();  // 保存/插入

// 通过AR读取记录 find() findByPk() findByAttributes() findBySql()
post=Post::model()>find(post=Post::model()>find(condition,params);//Post,NULLparams);//Post,NULLpost=Post::model()->findByPk(postID,postID,condition,params);params);post=Post::model()->findByAttributes(attributes,attributes,condition,params);params);post=Post::model()->findBySql(sql,sql,params);

// find()的一个例子:
post=Post::model()>find(postID=:postID,array(:postID=>10));//使CDbCriteriapost=Post::model()>find(postID=:postID,array(:postID=>10));//使CDbCriteriacriteria = new CDbCriteria;
criteria>select=title;criteria>select=title;creteria->condition='postID=:postID';
criteria>params=array(:postID=>10);criteria>params=array(:postID=>10);post=Post::model()->find(criteria);////criteria);////post=Post::model()->find(array(
        'select' => 'title',
        'condition' => 'postID=:postID',
        'params' => array(':postID' => 10)
        ));

// 如果查找的是多行记录可以使用 findAll() findAllByPk() findAllByAttributes() findAllBySql()
// find all rows satisfying the specified condition
posts=Post::model()>findAll(posts=Post::model()>findAll(condition,params);//findallrowswiththespecifiedprimarykeysparams);//findallrowswiththespecifiedprimarykeysposts=Post::model()->findAllByPk(postIDs,postIDs,condition,params);//findallrowswiththespecifiedattributevaluesparams);//findallrowswiththespecifiedattributevaluesposts=Post::model()->findAllByAttributes(attributes,attributes,condition,params);//findallrowsusingthespecifiedSQLstatementparams);//findallrowsusingthespecifiedSQLstatementposts=Post::model()->findAllBySql(sql,sql,params);
// 如果没有匹配的行,将返回一个空数组,这可以用empty()去检测

// 另外的一些可以使用的方法:
// get the number of rows satisfying the specified condition
n=Post::model()>count(n=Post::model()>count(condition,params);//getthenumberofrowsusingthespecifiedSQLstatementparams);//getthenumberofrowsusingthespecifiedSQLstatementn=Post::model()->countBySql(sql,sql,params);
// check if there is at least a row satisfying the specified condition
exists=Post::model()>exists(exists=Post::model()>exists(condition,params);//使AR//params);//使AR//post=Post::model()->findByPk(10);
post>title=newposttitle;post>title=newposttitle;post->save(); // save the change to database
// 怎么知道这是一条新纪录还是一条旧的记录呢?使用如下方法:
if( CActiveRecord::isNewRecord )
// update the rows matching the specified condition
Post::model()->updateAll(attributes,attributes,condition,params);//updatetherowsmatchingthespecifiedconditionandprimarykey(s)Post::model()>updateByPk(params);//updatetherowsmatchingthespecifiedconditionandprimarykey(s)Post::model()>updateByPk(pk,attributes,attributes,condition,params);//updatecountercolumnsintherowssatisfyingthespecifiedconditionsPost::model()>updateCounters(params);//updatecountercolumnsintherowssatisfyingthespecifiedconditionsPost::model()>updateCounters(counters,condition,condition,params);

// 删除记录
post=Post::model()>findByPk(10);//assumingthereisapostwhoseIDis10post=Post::model()>findByPk(10);//assumingthereisapostwhoseIDis10post->delete(); // delete the row from the database table
// 注意,当删除记录之后,post,////deletetherowsmatchingthespecifiedconditionPost::model()>deleteAll(post,////deletetherowsmatchingthespecifiedconditionPost::model()>deleteAll(condition,params);//deletetherowsmatchingthespecifiedconditionandprimarykey(s)Post::model()>deleteByPk(params);//deletetherowsmatchingthespecifiedconditionandprimarykey(s)Post::model()>deleteByPk(pk,condition,condition,params);

// 数据验证
// 将用户提交的数据保存到AR对象中
post>title=post>title=_POST['title'];
post>content=post>content=_POST['content'];
post>save();//assumepost>save();//assume POST['Post'] is an array of column values indexed by column names
post>attributes=post>attributes= POST['Post'];
post>save();//RAR:RelativedActieRecord//RAR//ARAR//4self::BELONGSTOself::HASMANYself::HASONEself::MANYMANY();//Postpublicfunctionrelations()returnarray(author=>array(self::BELONGSTO,User,authorid),//Usercategories=>array(self::MANYMANY,Category,tblpostcategory(postid,categoryid)),);//Userpublicfunctionrelations()returnarray(posts=>array(self::HASMANY,Post,authorid),profile=>array(self::HASONE,Profile,ownerid));//ARARAR,post>save();//RAR:RelativedActieRecord//RAR//ARAR//4self::BELONGSTOself::HASMANYself::HASONEself::MANYMANY();//Postpublicfunctionrelations()returnarray(author=>array(self::BELONGSTO,User,authorid),//Usercategories=>array(self::MANYMANY,Category,tblpostcategory(postid,categoryid)),);//Userpublicfunctionrelations()returnarray(posts=>array(self::HASMANY,Post,authorid),profile=>array(self::HASONE,Profile,ownerid));//ARARAR,author = User::model()->findByPk(1);
author>posts;//posts//1).lazyloadingapproach//retrievethepostwhoseIDis10author>posts;//posts//1).lazyloadingapproach//retrievethepostwhoseIDis10post=Post::model()->findByPk(10);
// retrieve the post's author: a relational query will be performed here
author=author=post->author;  // 如果先前没有执行过,现在才执行这个关系查询(事情拖到这一步才做,真的是很懒啊!)

// 如果关系查询执行后没有匹配的结果,返回将会是NULL或空的数组。

2).eager loading approach   热心的关系查询 //这名字真的很萌!
// 也就是说一次性取回所有你想要的记录。管你要不要,这这这,太热心了吧!
posts=Post::model()>with(author)>findAll();//SQL=>SELECTtblpost.,author.FROMtblposttINNERJOINtbluserauthorONt.author=tbluser.idposts=Post::model()>with(author)>findAll();//SQL=>SELECTtblpost.,author.FROMtblposttINNERJOINtbluserauthorONt.author=tbluser.idposts=Post::model()->with('author','categories')->findAll();
// SQL => 'SELECT * FROM tbl_post t INNER JOIN tbl_user u ON t.author = u.id INNER JOIN categories c ON t.id = c.post_id'

posts=Post::model()>with(author.profile,author.posts,categories)>findAll();posts=Post::model()>with(author.profile,author.posts,categories)>findAll();criteria=new CDbCriteria;
criteria>with=array(author.profile,author.posts,categories,);posts=Post::model()->findAll(criteria);posts=Post::model()->findAll(array(
                                    'with'=>array(
                                    'author.profile',
                                    'author.posts',
                                    'categories',
                                    )
                             );

// 如果我们想知道用户中谁发过帖子,并且帖子的状态是“公开”。我们并不关心用户发表过的帖子的内容。
user=User::model()>with(posts)>findAll();VSuser = User::model()->with(array(
                                    'posts' => array(
                                                        'select' => false,
                                                        'joinType' => 'INNER JOIN',
                                                        'condition' => 'posts.published = 1'
                                                    ),
                                 )
                           )->findAll();
// 返回的将会是所有发过帖子(且帖子已经公开)的用户

// 在relatinos()中定义更加复杂的关系
class User extends CActiveRecord
{
    public function relations()
    {
            return array(
                    'posts'=>array(self::HAS MANY, 'Post', 'author id',
                    'order'=>'posts.create time DESC',
                    'with'=>'categories'),
                    'profile'=>array(self::HAS ONE, 'Profile', 'owner id'),
                    );
    }
}

// 利用别名解决歧义
posts=Post::model()>with(comments)>findAll(array(order=>t.createtime,comments.createtime));//DynamicRelationalQuerySQLUser::model()>with(array(posts=>array(order=>posts.createtimeASC),profile,))>findAll();user=User::model()->findByPk(1);
posts=user->posts(array('condition'=>'status=1'));        // 返回的都是AR对象, 而不是数据

// 统计查询
class Post extends CActiveRecord
{
    public function relations()
    {
        return array(
            'commentCount'=>array(self::STAT, 'Comment', 'post_id'),
            'categoryCount'=>array(self::STAT, 'Category', 'post_category(post_id, category_id)'),
        );
    }

}

posted @   joshua317  阅读(125)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示