用户
 找回密码
 入住 CI 中国社区
搜索
查看: 15985|回复: 21
收起左侧

[辅助方法 Helper] 震撼你的method,试试在CI里面用LINQ!爽!

[复制链接]
发表于 2009-4-29 01:10:22 | 显示全部楼层 |阅读模式
本帖最后由 visvoy 于 2009-4-30 11:53 编辑

听说标题一定要雷人!废话不说了,先看实例:
PHP复制代码
$user = from('c')->in('db.user')->where('c.userid', $id)->select('c.*')->first();
echo $user->username;
复制代码


一组:
PHP复制代码
$users = from('c')->in('db.user')->where('c.sex', 1)
->left('m')->join('db.online')->on('c.userid=m.userid')
->where('c.userid')->in($some_list)
->select('c.*,m.last_logined')
->orderby('c.userid')->descending();
 
if($users->count() > 0){
    foreach($users->lists() as $rs){
        echo $rs->username;
    }
}
 
复制代码

更改:
PHP复制代码
$updated = from('db.user')->where('userid', $id)->set('credit', $new_credit)->update();
$inserted = from('db.user')->insert($new_user_array);
$deleted = from('db.user')->where('userid', $id)->delete();
$table_deleted = from('db.user')->kill();
if($updated) echo 'updated'; ...
复制代码


没错!是LINQ to SQL for CI,基于CI 1.7.1编写,不修改CI核心,随用随时加载

因为老板的缘故,现在支持LINQ to MSSQL/MySQL/MySQLi,大家有性趣没?

评分

参与人数 1威望 +5 收起 理由
Hex + 5 原创内容

查看全部评分

发表于 2009-4-29 10:12:20 | 显示全部楼层
这么强!看起来很优雅呀!!希望楼主多多介绍一下!
 楼主| 发表于 2009-4-29 11:30:37 | 显示全部楼层
本帖最后由 visvoy 于 2009-4-29 12:20 编辑

发现加上小海豚数据库支持也比较容易的说~ 现在支持仨DB了:MSSQL/MySQL/MySQLi

安装方法:下载解压附件,将内容放到 application/helpers/ 目录,DB配置不用改,哦了

在CI里面调用LINQ:controller任意方法内 $this->load->helper('linq'); 就可以用了

具体语法请看楼下,其实大部分都是按照LINQ的语法写的,用过LINQ的童鞋一看就爽,嘿嘿

这个支持MSSQL的limit(当然在LINQ里面叫skip/take),去掉了原来ar的缓存部分,因为偶滴项目也没用到ar缓存,所以就去掉了,代码量比ar小,加载速度快,还可以和ar同时使用,方便乃们想同时用ar的forge/util

另外,提示一下,我只写了LINQ to SQL的部分,LINQ to Array/Object/XML都没写,可不要尝试哦,尝试也不支持滴,呵呵

更新:附件 linq_lang.zip 是语言文件,下载解压之后放到 application/language/english/ 目录里面

LINQ_for_CI-2009-0428.zip

27.18 KB, 下载次数: 71

主程序,解压到application/helpers/目录下

linq_lang.zip

828 Bytes, 下载次数: 55

语言文件,解压到application/language/english/目录

 楼主| 发表于 2009-4-29 11:30:51 | 显示全部楼层
本帖最后由 visvoy 于 2009-4-30 11:52 编辑

【常用 LINQ to SQL for CI 例子】
from('db.user') 表示使用 config/database.php 里面的 $db['default'] 配置
如何使用多数据库?
from('db2.user') 使用 $db[2] 的数据库配置
from('db3.user') 使用 $db[3] 的数据库配置。。。以此数字类推

PHP复制代码
// 基础查询,从数据库user表取回所有列
// LINQ to SQL的in()必须以 db[DB配置序列] 开头
$query = from('c')->in('db.user')->select('c');
 
// 简化:如果只有一个from数据表,可以省略所有 "c." 开头,例如:
$query = from('c')->in('db.user')->select('id,name');
 
// 简化:针对一个 from 数据表,还可以省略 in() 方法,
//       此时会自动赋予 db.user 别名 me ,例如:
$query = from('db.user')->where('id', 1)->select('id,name');
 
// 取得单个数据(使用first/last/next/element_at陈述)
$rs = from('db.user')->where('id', 1)->select('*')->first();
echo $rs->username;
 
// 获取每个列并且输出每列内容
// count()方法将执行查询SQL动作,获得查询资源ID,和查询到的列数量
if ($query->count() < 1) {
print 'user表没有数据列';
} else {
foreach($query->lists() as $row) {
  print $row->username;
}
}
 
// 即使没取到数据,$query->lists() 用在 foreach 里面仍然不会出错,
// 此时 $query->lists() 返回的是空数组 array()
 
// 条件查询,指定column取回
$q = from('c')->in('db.user')->where('c.id', 1)->select('c.username');
 
// or where,使用 maybe 方法替代 orwhere 方法
$q = from('c')->in('db.user')->where('c.id', 1)->maybe('c.username', 'myname')->select('c');
 
// where in
$q = from('c')->in('db.user')->where('c.id')->in(array(1, 2, 3, 4, 5))->select('c');
 
// where not in,用 out 方法,使符合 out 条件的列出局
$q = from('c')->in('db.user')->where('c.id')->out(array(6, 7, 8))->select('c');
 
// or where not in,用 out 方法,使符合 out 条件的列出局
$q = from('c')->in('db.user')->maybe('c.id')->out(array(6, 7, 8))->select('c');
 
// like
$q = from('c')->in('db.user')->where('c.name')->like('bob')->select ();
 
// or like
$q = from('c')->in('db.user')->maybe('c.name')->like('bob')->select ();
 
// not like,使用differ方法
$q = from('c')->in('db.user')->where('c.name')->differ('ana')->select ();
 
// or not like,使用differ方法
$q = from('c')->in('db.user')->maybe('c.name')->differ('ana')->select ();
 
// orderby,descending和ascending
$q = from('c')->in('db.user')->select('c')->orderby('c.id')->descending()->orderby('c.name')->ascending();
 
// groupby
$q = from('c')->in('db.user')->select('c')->groupby('c.level');
 
// take 在 php 里面不延迟!!
// take 之后,LINQ 主体就变成 LINQ Record 了!注意!
// 分页,用 skip + take,下面表示略过10列,然后选8列
$q = from('c')->in('db.user')->select('c.*')->skip(10)->take(8);
 
// $total_rows 是所有符合条件的列数
// $page_rows 是当前页的列数,也就是 take 能取回的列数
$page_rows = $q->count ();
 
// 若你想去的总列数,使用如下例子:
$total_rows = from('c')->in('db.user')->count();
 
// join,支持这几种join:left/right/inner/outer/left_outer/right_outer
$q = from('a')->in('db.A')->left('b')->join('db.B')->on('a.id=b.uid')->select('a.id, b.photo');
 
// delete,必须有where,否则会抛出异常,不允许以 delete 表达式清空数据表
// 当只有一个表的时候,delete可以省去参数
$q = from('c')->in('db.A')->where('c.id', 1)->delete('c');
 
// kill,要清空数据表,不可以有where条件,不能与delete同时出现
// !!请谨慎使用 kill 方法!!
$q = from('c')->in('db.A')->kill();
 
// insert,以下几种都可以
$q = from('c')->in('db.A')->set(array ('name' => 'ana', 'email' => 'n/a'))->insert ();
$q = from('c')->in('db.A')->set('name', 'ana')->set('email', 'n/a')->insert ();
$q = from('c')->in('db.A')->insert(array ('name' => 'ana', 'email' => 'not_have'));
 
// update,使用格式与insert相同,但update必须有where,否则会抛出异常
$result = from('c')->in('db.A')->where('c.id=', 1)->update(array ('name' => 'ana', 'email' => 'not_have'));
 
// 检查 update 是否成功,可以检测写入型SQL的执行结果(up/insert/del等)
if ($result) {
print '上面的更新成功';
}
复制代码
 楼主| 发表于 2009-4-29 11:55:26 | 显示全部楼层
本帖最后由 visvoy 于 2009-4-30 11:51 编辑

【其他例子】

PHP复制代码
// 获取循环列表(很常用)
$q = from('db.user')->select('*');
 
while ($item = $q->next()) { // 以映射物件的形式获取(逐个记录迭代)
echo $item->name;
}
 
foreach ($q->arrays() as $item) { // 以数组的形式获取(一次性读取再迭代)
echo $list['name'];
}
 
foreach ($q->lists() as $item): // 以映射物件的形式获取(一次性读取再迭代)
echo $item->name;
endforeach;
 
// 使用数据库事务模式
from('db.user')->transaction()->select('*')->skip(10)->take(5);
/*中间做点其他处理*/
if(from('db.user')->complete()) echo '事务处理成功';
else echo '事务处理失败,已自动rollback';
 
// 判断是否在事务中
if(from('db.user')->transacting()) echo '正在进行事务';
复制代码
 楼主| 发表于 2009-4-29 12:30:14 | 显示全部楼层
本帖最后由 visvoy 于 2009-4-29 12:50 编辑

【几个注意事项】

1. 乃必须完成一次完整的LINQ陈述,才能进行下一个LINQ陈述,比如from()->select(),这不是完整陈述,因为select()是延迟查询(不立即执行query),若此时再创建一个LINQ陈述会报错(如from()->where(xxx))。
    解决方法:使用不延迟的陈述完成这次LINQ查询即可,例如用first/last/next/element_at/lists/arrays/count/take/insert/update/delete/kill 都是不延迟陈述

2. 为什么呢?因为linq to sql物件是单件物件,程序运行过程中,每个db库只有一个linq to sql物件实例。没办法~,为了省资源,要不每次from()都新建一个linq实例,那消耗很大的说。。。

3. 不同数据库之间是不会互相干扰的,例如from('db2.xx')和from('db3.xx')不会互相干扰

4. 总之,一般提示“from 与 in 陈述不匹配”错误,就说明乃有某个LINQ陈述未执行,就进行下一个LINQ操作了,请检查对应的代码

5. 重要一点!这个只支持PHP5,若你想在PHP4中使用。。。升级吧。。。只能怪PHP4不支持func()->next()写法。。。
 楼主| 发表于 2009-4-30 11:49:19 | 显示全部楼层
都没人下载。。。唉,明天收回了
发表于 2009-4-30 12:00:26 | 显示全部楼层
7# visvoy
还没看清呢,别忙着回收啊
发表于 2009-4-30 12:20:43 | 显示全部楼层
个人觉得只是一个linq的语法解析器,或者说是另一个AR
发表于 2009-4-30 12:33:41 | 显示全部楼层
个人觉得只是一个linq的语法解析器,或者说是另一个AR
bcb51 发表于 2009-4-30 12:20

有这个感觉

本版积分规则