使用糖中的准备陈述7.9

什么是准备好的陈述?

准备的陈述,也称为参数化 语句是数据库功能,允许以更高效率和更高的安全性执行相同或相似的查询。它也是一段时间的常见糖平台功能请求。

准备好的声明看起来像这样:

SELECT * FROM table WHERE id = ?

如您所见,准备好的声明基本上是一个SQL模板,允许您识别稍后可以绑定的参数。数据库引擎可以解析,优化和缓存此语句而不执行它。

这减少了与解析复杂查询相关的开销,这些复杂查询通常由糖等应用程序使用。例如,您可以想象列表视图查询将受益于准备好语句,因为它们通常在每次显示列表,搜索,过滤或分页时都经常复杂和执行。使用准备好语句,每次重复其中一个操作时,数据库都将少工作。

准备好陈述的另一个关键实力是它有助于预防 SQL注入 漏洞。预计参数将是常量值(字符串,整数等)而不是SQL。因此,如果攻击者将RAW SQL绑定为准备的语句,则不会被解释为SQL。攻击失败了!

数据库管理员(DBA)也如准备好的语句,因为它倾向于让它们更多地控制这些查询如何由后端数据库引擎缓存。在良好的DBA手中,准备好的语句允许应用程序更好地调整 high performance.

糖的变化7.9.0

糖7.9.0将在此写作时的未来几周内提供。在Sugar 7.9.0中,大多数糖执行的查询现在 参数化。一些新的 已添加查询API以支持准备的语句。

最重要的变化是我们已经采用了部分 教义's数据库抽象层,特别是 QueryBuilder. 班级,为了与之合作 prepared statements.

DBManager.

DBManager.类将使用Doctrine QueryBuilder进行构建插入和更新查询。

糖曲线

糖曲线类将使用Doctrine QueryBuilder构建选择查询。

糖类课将继续使用 DBManager类保存 all fields.

在糖中出去的东西7.9.0

有一些糖开发人员需要知道他们准备他们的东西 Sugar 7.9.0的代码自定义。

DBManager.和SugarQuery API更改

如上所述 糖7.7.1发行说明,许多dbmanager apis和一些 糖曲线 APIs 被贬值作为我们计划为糖添加准备的声明支持的计划的一部分。这些已弃用的API已被淘汰7.9.0。如果你没有't already, you 必须 在Sugar 7.9.0升级之前迁移使用这些API的自定义代码。

在这种糖释放中已删除以下弃用的PHP类和方法。

糖曲线_Builder_Delete

糖曲线_Builder_Insert

糖曲线_Builder_Update

糖曲线_Builder_Literal

糖曲线_Compiler

糖曲线::joinRaw()

糖曲线 :: compilesql()

DBManager.::delete()

DBManager.::retrieve()

DBManager.::insertSQL()

DBManager.::updateSQL()

DBManager.::deleteSQL()

DBManager.::retrieveSQL()

DBManager.::preparedQuery()

DBManager.::pQuery()

DBManager.::prepareQuery()

DBManager.::prepareTypeData()

DBManager.::prepareStatement()

$执行 参数 DBManager. :: InstractParams() and dbmanager :: reductparams() 也被删除了。

糖曲线 :: compilesql()

糖曲线 :: compilesql() 通常用于调试使用SugarQuery API构建的原始SQL。 糖曲线 :: compilesql() 被弃在糖7.7.x并是 不再支持糖7.9.0。因为 糖曲线 现在使用准备好语句,它不再编译一个 完整的SQL语句本身。请记住,参数化查询组装并在DB引擎内执行。因此,您需要单独获取参数化的SQL和参数。从这些信息,您可以 determine 如何执行查询。

例如,

$compiled = $query->compile(); // create compiled prepared statement

$编译 - >getSQL(); // fetches parameterized SQL

$编译 - >getParameters(); // fetches parameters

$编译 - >getSQL() 将返回SQL与占位符而不是参数:

SELECT * FROM users WHERE id=?

$编译 - >getParameters() 将返回一个参数数组:

['ec2f4abb-b6b9-3d49-0382-5730e67c116c']

如何在糖中使用准备的陈述7.9.0

如果你已经使用了 糖曲线 或者 然后祝贺!您的代码自定义将自动从准备好的语句中受益。 我们对这两个界面进行了更改,以确保他们使用 准备好陈述。潜在的行为 is 自定义代码透明。

但是,如果你 需要更多的技巧与您的查询,然后我们将探索如何使用新的DBManager和Doctrine使用准备的语句 QueryBuilder. APIs.

选择查询

对于简单的静态选择查询,更改非常直。前:

$query = 'SELECT * FROM table WHERE id = ' . $this->db->quoted($id);

$db->query($query);

后:

$query = 'SELECT * FROM table WHERE id = ?';

$conn = $db->getConnection();

$stmt = $conn->executeQuery($query, array($id));

在查询逻辑变量或有条件构建的情况下,直接使用Doctrine QueryBuilder有意义。前:

$query = 'SELECT * FROM table';

if ($status !== null) {

   $query .= ' WHERE status = ' . $this->db->quoted($status);

}

$db->query($query);

后:

$builder = $db->getConnection()->createQueryBuilder();

$builder->select('*')->from('table');

if ($status !== null) {

   $builder->where(

       'status = ' . $builder->createPositionalParameter($status))

   );

}

$builder->execute();

插入查询

插入查询 可以使用DBManager类轻松执行。前:

$query = 'INSERT INTO table (foo, bar) VALUES ("foo", "bar")';

$db->query($query);

后:

$fieldDefs = $GLOBALS['dictionary']['table']['fields'];

$db->insertParams('table', $fieldDefs, array(

   'foo' => 'foo',

   'bar' => 'bar',

));

更新查询

在使用已知ID的记录或具有简单过滤条件的一组记录时,可以使用DBManager:前:

$query = 'UPDATE table SET foo = "bar" WHERE id = ' . $db->quoted($id);

$db->query($query);

后:

$fieldDefs = $GLOBALS['dictionary']['table']['fields'];

$db->updateParams('table', $fieldDefs, array(

'foo' => 'bar',

), array(

'id' => $id,

), );

更复杂的标准 或者列值包含对表中其他字段的表达式或引用,可以使用Doctrine QueryBuilder。前:

$query = 'UPDATE table SET foo = "bar" WHERE foo = "foo" OR foo IS NULL';

$db->execute($query);

后:

$query = 'UPDATE table SET foo = ? WHERE foo = ? OR foo IS NULL';

$conn = $db->getConnection();

$stmt = $conn->executeQuery($query, array('bar', 'foo'));

匿名的
父母
没有数据
评论
  • $ core_v2_ui.getresizedimagehtml($ compual.user.avatarurl,44,44,44,“%{border ='0px',alt = $ compougin.user.displayname,resizemethod ='zoomandcrop'}”)
    $ core_v2_ui.userpresence($ comminy.user.id) $ compount.user.displayname. 超过2020年前
    此评论正在审核。
孩子们
没有数据