MySQL++3.1.0用户手册翻译:4. 模板查询,4. Template Queries

- no title specified

MySQL++3.1.0用户手册翻译:4. 模板查询,4. Template Queries

4. 模板查询

上一章

下一章

4. 模板查询

MySQL++的另一个强大技能是使用模板查询。这些东西与C语言的printf()类似:妳向MySQL++提供一个字符串,其中包含查询语句的不变部分,也包含可变部分的占位符,稍后再将参数值填充到占位符中。

下面的程序演示咯如何使用这个技能。对应的文件是examples/tquery1.cpp:

#include “cmdline.h”

#include “printdata.h”

#include <iostream>

using namespace std;

int

main(int argc, char *argv[])

{

//从命令行获取数据库连接参数

const char* db = 0, *server = 0, *user = 0, *pass = “”;

if (!parse_command_line(argc, argv, &db, &server, &user, &pass)) {

return 1;

}

try {

//连接到数据库服务器。

mysqlpp::Connection con(db, server, user, pass);

//构造一个模板查询,根据条目名字查询存货条目。

mysqlpp::Query query = con.query(

“select * from stock where item = %0q”);

query.parse();

//获取一个由resetdb 添加的条目;如果在执行resetdb 之后运行过tquery*或ssqls3,则它会消失。

mysqlpp::StoreQueryResult res1 = query.store(“Nürnberger Brats”);

if (res1.empty()) {

throw mysqlpp::BadQuery(“UTF-8 bratwurst item not found in “

“table, run resetdb”);

}

//使用另一个模板查询,将原来的德文名字替换成一个7位的ASCII近似单词。

query.reset(); //清除上次使用的模板查询数据

query << “update stock set item = %0q where item = %1q”;

query.parse();

mysqlpp::SimpleResult res2 = query.execute(“Nuerenberger Bratwurst”,

res1[0][0].c_str());

//输出新的表格内容。

print_stock_table(query);

}

catch (const mysqlpp::BadQuery& er) {

//处理查询错误

cerr << “Query error: ” << er.what() << endl;

return -1;

}

catch (const mysqlpp::BadConversion& er) {

//处理转换过程中的错误

cerr << “Conversion error: ” << er.what() << endl <<

“\tretrieved data size: ” << er.retrieved <<

“, actual size: ” << er.actual_size << endl;

return -1;

}

catch (const mysqlpp::Exception& er) {

//处理其它MySQL++异常

cerr << “Error: ” << er.what() << endl;

return -1;

}

return 0;

}

query.parse()之前的那一行就是用来设置模板的,而随后调用的parse 使它生效。从这个时候开始,妳可以通过调用Query 的任意支持查询模板参数的成员函数来重用这个查询对象咯。在这个示例中,我们使用的是Query::execute()

让我们来深入研究一下这个技能。

4.1. 设置模板查询

要设置一个模板查询的话,妳只需简单地在Query 对象中想要改变查询语句的地方插入带编号的占位符。然后,调用parse()函数,告诉Query 对象,这是一个模板查询,需要分析:

query << “select (%2:field1, %3:field2) from stock where %1:wheref = %0q:what”;

query.parse();

占位符的格式是:

%###(modifier)(:name)(:)

其中,“###”是一个数,最多有3位数字。它表示的是参数被赋予给SQLQueryParms对象的顺序,从0开始计数。

modifier”可以是以下值:

%

输出一个真正的“%”

“”

无论如何,不要引用,不要转义。

q

这将会使用MySQL 的C语言API 中的mysql_escape_string()函数来对当前条目进行转义处理。并且会根据实际使用的值进行判断,在必要的情况下用单引号引用起来。

Q

按照与“q”相同的规则来引用,但不进行转义处理。如果妳确定妳的字符串不需要经过转义处理,则可以通过这个来节约一点处理时间

:name”是一个可选的名字,用来辅助填充SQLQueryParms。名字可包含任意的字母、数字和下划线。妳可以带上一个冒号,但是它会被忽略。如果妳确实需要在名字末尾带上一个冒号的话,则写上两个冒号。第一个冒号表示名字的结尾,第二个冒号会被原样保留。

4.2. 在执行时设置参数

要想要执行查询时指定参数,只需使用Query::store(const SQLString &parm0, [..., const SQLString &parm11])。这种多次重载的情况也存在于Query::storein()Query::use()Query::execute()中。“parm0”对应于第一个参数,如此类推。妳最多可以指定25个参数。例如:

StoreQueryResult res = query.store(“Dinner Rolls”, “item”, “item”, “price”)

对于前面说过的模板查询,会产生以下查询语句:

select (item, price) from stock where item = “Dinner Rolls”

至于这里我们为什么不按照数字顺序来写上模板参数勒。

select (%0:field1, %1:field2) from stock where %2:wheref = %3q:what

稍后再向妳解释。

4.3. 默认参数

模板查询机制允许妳设置默认参数值。妳只需将一个值赋予Query::template_defaults 数组中对应位置的参数即可。妳可以用位置或名字来引用对应的参数:

query.template_defaults[1] = “item”;

query.template_defaults["wheref"] = “item”;

上面两条语句是同样的效果。

这个机制与C++的默认函数参数机制类似:如果妳在参数列表的末尾设置咯某些参数的默认值,则妳无需传递所有参数值便可以调用Query 的查询执行方法。如果这个查询需要四个参数,而妳已经为后面三个参数设置咯默认值,则妳可以只显式传递一个参数便执行查询。

现在妳知道我们在前面的某个例子里为什么不按照数字顺序来写模板查询参数咯。我们让那些不怎么会改变的参数的编号更大,这样我们就不用总是传递这些参数咯。我们可以为它们设置默认值,然后,在默认值有效的情况下,直接使用默认值。当一个模板查询中的某些参数变化得比较少时,这种方法最有效。例如:

query.template_defaults["field1"] = “item”;

query.template_defaults["field2"] = “price”;

StoreQueryResult res1 = query.store(“Hamburger Buns”, “item”);

StoreQueryResult res2 = query.store(1.25, “price”);

上面的代码片段分别将以下两条查询语句的结果储存到res1 res2 中:

select (item, price) from stock where item = “Hamburger Buns”

select (item, price) from stock where price = 1.25

在这个示例中,默认参数是有用的,因为我们有两个查询要执行,其中2号和3号参数保持不变,而0号和1号参数发生变化。

某些人曾采用这种方法来设置一个查询中的所有模板参数:

query.template_defaults["what"] = “Hamburger Buns”;

query.template_defaults["wheref"] = “item”;

query.template_defaults["field1"] = “item”;

query.template_defaults["field2"] = “price”;

StoreQueryResult res1 = query.store();

这样有可能正常运行,但是按照我们的设计,是不应该这样做的。事实上,已知在某种常见的情况下,这种方法会失效。如果妳在邮件列表中报怨说这种方法无效,那么没人会同情妳。如果妳的代码在后续的查询中连一个参数都不显式地重用的话,那么妳就是在滥用MySQL++, 而且它狠有可能会惩罚妳(☯,本座极不喜欢这种威胁式的手册)。

上一章

下一章

3. 教程

首页

5. 特殊SQL 结构

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 

凶残的LibreOffice3.5.3:导入PDF到Writer中编辑

- no title specified


凶残的LibreOffice3.5.3:导入PDF到Writer中编辑

要导入PDF文件进行编辑,首先要安装一个插件:libobasis3.5-extension-pdf-import-3.5.3-2.i586.rpm。

本座记得在以前的版本中,导入PDF的话,会直接导入到Draw中以绘图的方式编辑。今天又试咯一下导入PDF的功能,发现这次LibreOffice打开咯一个选择对话框,选择要用LibreOffice里的什么组件来编辑导入后的内容。本座玩Writer玩得最多,就直接选择用Writer来编辑咯。

在导入的过程中要等待大约1分钟。然后就看到这样的:

显然臭虫还是有的,中间的显示区域没有自动改变大小以适应整个窗口的大小。

这倒没什么,小问题。手动改变一下窗口的大小,显示区域便会根据窗口大小自动调整一下咯。

跟okular的显示效果相比,还是不一样,各个文字块都重叠咯,但是位置都对,应当是因为系统没有安装对应的字体造成的。LibreOffice中默认使用的字体比这个PDF里嵌入的字体要宽一点。如果把对应的字体都安装上的话,显示效果应当是一样的。

鼠标随便在Writer里点几下吧,会发现里面把导入的文字段落都变成咯一个个的文字块。由于有这么多的文字块,所以滚动页面的时候狠卡。

然后把这个文件保存,默认会以ODF格式保存,当然选择ODF格式咯。对比一下文件大小。由于这个文档有98页,而且这98页都是一坨坨的独立文字块,所以保存也费咯点时间,本座大概等咯1分钟,才保存完毕。左边那个是ODF文件,280K,右边的是原PDF文件,371K,ODF压缩得确实厉害啊。刚才顺便试咯一下,这个原PDF文件经过ZIP压缩之后能达到271K,看来PDF格式本身可能没有压缩。

再有一点要说的就是将这个文档再导出成HTML之后的结果咯。要导出成HTML,首先要安装这个模块:libobasis3.5-xsltfilter-3.5.3-2.i586.rpm。然后就可以把文档导出成一体化的HTML文件咯,这里的一体化是指,连图片也会以编码的形式输出到该HTML文件中,这样不会带上其它的任何文件。本座写勃客的时候一直是使用这个功能导出成HTML,再粘贴到勃客的源代码编辑框的,所以本座文章末尾的配图的“文件名超长”,其实那不是文件名,那是图片本体。

好咯,导出一个试试。“文件”》“导出”,选择“XHTML”,“确定”。这次的等待时间更长。生成的文件也非常大。看看最左边那个文件的大小,143986K,换算成M之后就是140M。

本座第一次用火狐打开这个HTML文件的时候,火狐崩溃咯。再次打开,火狐又没崩溃咯。这个页面为火狐增加的内存占用也是狠大的,打开这个页面之前,火狐的内存占用是704.9M,打开页面之后,火狐的内存占用是2.3G。可见这个页面在内存中展开之后也是相当可观的。

写完咯。

 
Tags:
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 

转载:FireBug调试时:Permission denied to access property document错误

- no title specified


转载:FireBug调试时:Permission denied to access property document错误

当妳的网页程序被Firebug报告“Permission denied to access property document”错误时,不一定是妳的错,而可能是Firebug自己的错,禁用Firebug试试。

http://www.ityoudao.com/Web/Html_JS_646_1621.html

亮点:

搜索后得知这似乎只是firefug的的一个bug,3.5版本的火狐就会有这个问题,由于网络延迟的问题,dom就出现了问题。这个老外牛人也提供了解决办法,我拿过来,果真有效。解决方法如下:

 
Tags:
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 

转载:Qt How to make a column in QTableWidget read only

- no title specified


转载:Qt How to make a column in QTableWidget read only

要想让QTableWidget中的特定单元格成为只读的,只需向它设置这样的标志位组合即可:Qt::ItemIsSelectable|Qt::ItemIsEnabled。

http://stackoverflow.com/questions/2574115/qt-how-to-make-a-column-in-qtablewidget-read-only

亮点:

11 down vote accepted

Insert into the QTableWidget following kind of items:

QTableWidgetItem *item = new QTableWidgetItem();

item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);

Works fine!

 
Tags:
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 

Qt4.8文档翻译:QSqlQuery类参考,QSqlQuery Class Reference

- no title specified


Qt4.8文档翻译:QSqlQuery类参考,QSqlQuery Class Reference

成员函数文档

bool QSqlQuery::first ()

如果可以的话,取出结果中的第一条记录,并且将此查询对象放置在那条取出的记录上。注意,在调用此函数之前,对应的结果必须是处于活跃(active)状态,并且isSelect()必须返回真,否则的话,此函数将什么也不做并且返回假.如果成功则会返回.如果失败,则此查询对象的位置将被设置成一个无效,并且返回假.

参考next()previous()last()seek()at()isActive()isValid()

bool QSqlQuery::next ()

如果可以的话,取出结果中的下一条记录,并且将此查询对象放置在那条取出的记录上。注意,在调用此函数之前,对应的结果必须是处于活跃(active)状态,并且isSelect()必须返回真,否则的话,此函数将什么也不做并且返回假.

将按照以下规则来操作:

  • •.如果结果当前是位于第一条记录之前,也就是说此时刚刚执行过一个查询的话,则会尝试取出第一条记录。

  • •.如果结果当前位于最后一条记录之后,则不会做任何事,并且返回假。

  • •.如果结果位于中间的某个位置,则会尝试取出下一条记录。

如果无法取出记录,则结果会被放置于最后一条记录之后,并且返回假。如果成功地取出咯记录,则会返回真。

参考previous()first()last()seek()at()isActive()isValid()

 
Tags:
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 

转载:如何使用QCryptographicHash加密文本

- no title specified


转载:如何使用QCryptographicHash加密文本

可轻松使用QCryptographicHash来将字符串转换成MD5.转换之后的结果默认是以“乱码”的形式表示的,可使用QByteArray::toHex()函数将“乱码”转换成群众喜闻乐见的十六进制表示形式。

http://www.developer.nokia.com/Community/Wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8QCryptographicHash%E5%8A%A0%E5%AF%86%E6%96%87%E6%9C%AC

亮点:

一些相关函数

  • •.添加数据到加密哈希值

QByteArray string=”Nokia”;

hash->addData(string);

  • •.返回最终的哈希值

QByteArray string1=hash->result();

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 

Qt4.8文档翻译:QByteArray类参考,QByteArray Class Reference

- no title specified


Qt4.8文档翻译:QByteArray类参考,QByteArray Class Reference

成员函数文档

QByteArray QByteArray::toHex () const

返回的是将此字节数组以十六进制编码之后的结果。十六进制编码使用数字0-9 和字母a-f。

参考fromHex()

 
Tags:
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 

Libreoffice在插入图片时启用预览

- no title specified


Libreoffice在插入图片时启用预览

Libreoffice在插入图片时,在选择图片文件的对话框里可以预览该图片,方法就是选中对话框最下方的那个“预览”复选框,当对话框最大化时,这个复选框狠不显眼。

 
Tags:
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 

转载:Qt HTTP内部构架

- no title specified


转载:Qt HTTP内部构架

Qt的HTTP模块默认就支持cookies的解析和发送。所以无需特别处理cookies。

http://labs.qt.nokia.com.cn/2012/03/08/inside-the-qt-http-stack/

亮点:

尽管上面这个类图已经显得够复杂了,但还有一些类和领域被省略了:

  • •.Bearer类:用于更加细粒度的调节连接设置等,除了前面提到的QNetworkSession外还有几个类被用到。

  • •.Cookies:显然,Qt HTTP默认支持cookie的解析和发送,请参见QNetworkCookieQNetworkCookieJar

  • •.HTTP缓存:尽管Qt也支持HTTP缓存,但未被默认启用。

  • •.代理服务器:Qt支持在HTTP和SOCKS5代理服务器上进行网络传输。

  • •.上传数据:一些关于上传数据,以及处理HTTP multipart消息的类被省略了。

 
Tags:
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
2 Comments  comments 

转载:Linux安装Subversion并制作Raid1

- no title specified


转载:Linux安装Subversion并制作Raid1

制作软RAID1,只需使用mdadm命令即可。

http://mdadm.org/post/31

亮点:

创建一个raid1

mdadm –C /dev/md0 –l 1 –n 2 /dev/sda2 / dev/sdb2

创建raid后,一定要记得进行格式化,否则挂载会失败

mkfs.ext4 /dev/md0

创建一个mdadm.conf配置文档

里面包含输入mdadm –Ds命令后反馈的内容和drivers=/dev/sda2,/dev/sdb2

 
Tags:
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 
© 漂亮的笨蛋
credit