动态地创建查询使用对象和方法使得查询可以非常迅速地写在一个不可知的方式。查询器也添加了标识符(表和列名)引用,以及引用的值。
每种类型的数据库查询是由不同的类来表示,每个都有自己的方法。例如,要创建一个SELECT查询中,我们使用DB ::select是返回一个新的快捷方式Database_Query_Builder_Select对象:
$query = DB::select();
from()方法。在from()方法接受它可以是表名(字符串),两个字符串(表名和别名)的数组或对象(见子查询在下面的高级查询部分)一个参数。
$query= DB::select()->from(‘users‘);
限制查询的结果是通过使用,IN,
BETWEEN and_where()和or_where()方法。这些方法需要三个参数:一个列,运算符和值。
$query= DB::select()->from(‘users‘)->where(‘username‘,‘=‘,‘john‘);
方法可以用来串起来用在方法的前缀布尔运算符连接多个子句。方法是,仅仅调用一个包装and_where() 。
$query= DB::select()->from(‘users‘)->where(‘username‘,‘=‘,‘john‘)->or_where(‘username‘,‘=‘,‘jane‘);
你可以使用任何你想要的。例子包括IN,
BETWEEN, >, =<, !=,等。使用数组用于需要多个值运算符。
$query= DB::select()->from(‘users‘)->where(‘logins‘,‘<=‘, 1);$query= DB::select()->from(‘users‘)->where(‘logins‘,‘>‘, 50);$query= DB::select()->from(‘users‘)->where(‘username‘,‘IN‘,array(‘john‘,‘mark‘,‘matt‘));$query= DB::select()->from(‘users‘)->where(‘joindate‘,‘BETWEEN‘,array($then,$now));
默认情况下,DB::select
将选择所有列(SELECT
* ...),但您也可以指定哪些列你想通过传递参数来返回DB::select:$query= DB::select(‘username‘,‘password‘)->from(‘users‘)->where(‘username‘,‘=‘,‘john‘);
现在,花一分钟来看看这是什么方法链在做什么。首先,我们创建一个使用新的选择对象的DB::select方法。接下来,我们使用设置桌from()方法。最后,我们搜索使用特定的记录,方法。我们可以显示,将通过铸造的查询字符串被执行的SQL语句:where()
echoDebug::vars((string)$query);// Should display:// SELECT `username`, `password` FROM `users` WHERE `username` = ‘john‘
请注意列名和表名会自动转义,以及价值观?这是使用查询生成器的主要优势之一。
它也可以创建AS选择,通过传递一个数组作为每个参数的别名时,DB::select:
这个查询将生成的SQL语句:$query= DB::select(array(‘username‘,‘u‘),array(‘password‘,‘p‘))->from(‘users‘);
SELECT `username` AS `u`, `password` AS `p` FROM `users`
唯一的列值可以通过传递TRUE或FALSE,分别在开启或关闭(默认)方法。distinct()
这个查询将生成的SQL语句:$query= DB::select(‘username‘)->distinct(TRUE)->from(‘posts‘);
SELECT DISTINCT `username` FROM `posts`
当查询大型数据集,它往往是更好的通过数据一大块的时间限制结果和页面。这是通过使用limit() and
offset() 方法.$query= DB::select()->from(`posts`)->limit(10)->offset(30);
通常你会想要的结果以特定的顺序和,而不是排序的结果,最好是有结果的正确顺序退还给您。您可以通过使用ORDER_BY()方法做到这一点。它采用列名和一个可选的方向字符串作为参数。多个ORDER_BY()方法可用于添加其他排序功能。
这个查询将生成的SQL语句:$query= DB::select()->from(`posts`)->order_by(`published`, `DESC`);
SELECT * FROM `posts` ORDER BY `published` DESC
对于可用的方法,同时建立一个选择查询的完整列表,请参阅Database_Query_Builder_Select。
创建记录到数据库中,使用DB
::插入创建一个INSERT查询,使用来传递数据:values()
这个查询将生成的SQL语句:$query= DB::insert(‘users‘,array(‘username‘,‘password‘))->values(array(‘fred‘,‘p@5sW0Rd‘));
INSERT INTO `users` (`username`, `password`) VALUES (‘fred‘,‘p@5sW0Rd‘)
对于可用的方法,同时建立一个插入查询的完整列表,请参阅Database_Query_Builder_Insert。
要修改现有的记录,使用DB::update创建一个UPDATE查询:
这个查询将生成的SQL语句:$query= DB::update(‘users‘)->set(array(‘username‘=>‘jane‘))->where(‘username‘,‘=‘,‘john‘);
For a complete list of methods available while building an update query see Database_Query_Builder_Update.UPDATE `users` SET `username` =‘jane‘WHERE `username` =‘john‘
要删除现有的记录,使用DB::delete创建一个DELETE查询:
这个查询将生成的SQL语句:$query= DB::delete(‘users‘)->where(‘username‘,‘IN‘,array(‘john‘,‘jane‘));
对于可用的方法,同时建立一个删除查询看到一个完整的列表Database_Query_Builder_Delete。DELETEFROM `users` WHERE `username` IN (‘john‘,‘jane‘)
多个表可以使用被加入join()方法,on()方法。在join()方法有两个参数。首先可以是一个表名,包含表和别名的数组或对象(子查询或表达式)。第二个参数是连接类型:LEFT,
RIGHT, INNER, etc.
在方法设置为先前的条件on()方法,并且是非常相似的join(),中,它有三个参数的方法;左栏(名称或对象),一个操作,以及右列(或名称对象)。多个where()方法可被用来提供多个条件,他们将用“AND”操作符被附加。on()
这个查询将生成的SQL语句:$query// This query will find all the posts related to "smith" with JOIN= DB::select(‘authors.name‘,‘posts.content‘)->from(‘authors‘)->join(‘posts‘)->on(‘authors.id‘,‘=‘,‘posts.author_id‘)->where(‘authors.name‘,‘=‘,‘smith‘);
如果你想要做一个LEFT, RIGHT or INNER JOIN你会做这样的SELECT `authors`.`name`, `posts`.`content` FROM `authors` JOIN `posts` ON (`authors`.`id` = `posts`.`author_id`) WHERE `authors`.`name` =‘smith‘
加入(‘colum_name‘,‘type_of_join‘) :这个查询将生成的SQL语句:$query// This query will find all the posts related to "smith" with LEFT JOIN= DB::select()->from(‘authors‘)->join(‘posts‘,‘LEFT‘)->on(‘authors.id‘,‘=‘,‘posts.author_id‘)->where(‘authors.name‘,‘=‘,‘smith‘);
当类似的列名连接多个表,这是最好的前缀列的表名或表别名来避免错误。使它们可以被引用更容易。SELECT `authors`.`name`, `posts`.`content` FROM `authors` LEFT JOIN `posts` ON (`authors`.`id` = `posts`.`author_id`) WHERE `authors`.`name` =‘smith‘
最终,你可能会遇到一个情况下,你需要调用COUNT您的查询中或其他一些数据库的功能。查询生成器以两种方式支持这些功能。首先是通过使用别名:
这看起来几乎完全一样的标准$query= DB::select(array(‘COUNT("username")‘,‘total_users‘))->from(‘users‘);
AS别名,但是注意列名被包裹在双引号。双引号的值出现在列名内的任何时间,只有在双引号内的部分将被转义。这个查询将生成的SQL语句:在构建复杂的查询,你需要得到将要返回的总行数的计数,建立与一个空列列表中的第一个表现。然后克隆的查询,并新增COUNT函数来一份,列清单到另一个。这将减少代码的总行数,使更新的查询更加容易。SELECTCOUNT(`username`) AS `total_users` FROM `users`
$query= DB::select()->from(‘users‘)->join(‘posts‘)->on(‘posts.username‘,‘=‘,‘users.username‘)->where(‘users.active‘,‘=‘, TRUE)->where(‘posts.created‘,‘>=‘,$yesterday);$total=clone$query;$total->select(array(‘COUNT( DISTINCT "username")‘,‘unique_users‘));$query->select(‘posts.username‘)->distinct();
汇总功能,如COUNT() ,SUM() ,AVG()等将最有可能与使用GROUP_BY()和可能的有() ,以组方法和筛选的一组列的结果。
这将产生以下查询:$query= DB::select(‘username‘,array(‘COUNT("id")‘,‘total_posts‘)->from(‘posts‘)->group_by(‘username‘)->having(‘total_posts‘,‘>=‘, 10);
SELECT `username`,COUNT(`id`) AS `total_posts` FROM `posts` GROUP BY `username` HAVING `total_posts` >= 10
查询生成器对象可以作为参数传递给众多的创建子查询的方法。让我们以前面的例子中的查询,并将它传递到一个新的查询。
这将产生以下查询:$sub= DB::select(‘username‘,array(‘COUNT("id")‘,‘total_posts‘)->from(‘posts‘)->group_by(‘username‘)->having(‘total_posts‘,‘>=‘, 10);$query= DB::select(‘profiles.*‘,‘posts.total_posts‘)->from(‘profiles‘)->join(array($sub,‘posts‘),‘INNER‘)->on(‘profiles.username‘,‘=‘,‘posts.username‘);
插入查询,也可以使用一个SELECT查询的输入值SELECT `profiles`.*, `posts`.`total_posts` FROM `profiles` INNER JOIN( SELECT `username`,COUNT(`id`) AS `total_posts` FROM `posts` GROUP BY `username` HAVING `total_posts` >= 10 ) AS postsON `profiles`.`username` = `posts`.`username`
这将产生以下查询:$sub= DB::select(‘username‘,array(‘COUNT("id")‘,‘total_posts‘)->from(‘posts‘)->group_by(‘username‘)->having(‘total_posts‘,‘>=‘, 10);$query= DB::insert(‘post_totals‘,array(‘username‘,‘posts‘))->select($sub);
INSERT INTO `post_totals` (`username`, `posts`)SELECT `username`,COUNT(`id`) AS `total_posts` FROM `posts` GROUP BY `username` HAVING `total_posts` >= 10
多个WHERE和HAVING子句添加到查询与布尔运算符连接的每个表达式。默认值操作符对于这两种方法是与它是相同的and_前缀的方法。OR运算符可以通过前缀来OR_的方法来指定。WHERE和HAVING子句可以嵌套或邮寄分组固定两种方法_open,然后接着用_close的方法。
这将产生以下查询:$query= DB::select()->from(‘users‘)->where_open()->or_where(‘id‘,‘IN‘,$expired)->and_where_open()->where(‘last_login‘,‘<=‘,$last_month)->or_where(‘last_login‘,‘IS‘, NULL)->and_where_close()->where_close()->and_where(‘removed‘,‘IS‘, NULL);
SELECT * FROM `users` WHERE ( `id` IN (1, 2, 3, 5) OR ( `last_login` <= 1276020805 OR `last_login` IS NULL ) ) AND `removed` IS NULL
在有些情况下是需要一个复杂的表达式或其它数据库功能,你不希望查询生成器,试图逃跑。在这些情况下,您将需要使用与创建的数据库表达式DB :: expr的。 数据库表达式取为直接输入,没有逃脱被执行。
这将产生以下查询,假设$query= DB::update(‘users‘)->set(array(‘login_count‘=> DB::expr(‘login_count + 1‘)))->where(‘id‘,‘=‘,$id);
$
ID = 45:UPDATE `users` SET `login_count` = `login_count` + 1 WHERE `id` = 45
另一个例子:您必须验证或逃避任何用户输入数据库里面:: expr的,因为它显然不会被转义它$query= DB::select(array(DB::expr(‘degrees(acos(sin(radians(‘.$lat.‘)) * sin(radians(`latitude`)) + cos(radians(‘.$lat.‘)) * cos(radians(`latitude`)) * cos(radians(abs(‘.$lng.‘ - `longitude`))))) * 69.172‘),‘distance‘))->from(‘locations‘);
一旦你完成建立,您可以用执行查询的execute()并使用结果。
要使用不同的数据库配置组通过名称或配置对象来$result=$query->execute();
execute() 。$result=$query->execute(‘config_name‘)
http://kohanaframework.org/3.2/guide/database/query/builder 翻译地址原文
http://kohanaframework.org/3.2/guide/api/DB#select
原文:http://blog.csdn.net/phpfenghuo/article/details/20281429