如何将SQL查询转换为原生查询?附具体SQL示例语句
嘿,我来帮你搞定这个SQL转原生查询的事儿~其实你贴出来的这段SQL本身已经是原生SQL了——它直接遵循了MySQL的语法规范(比如用反引号包裹表名、标准的JOIN关联逻辑)。不过我猜你大概率是想问怎么在常见的开发框架里执行这段原生查询,或者是想优化它作为原生查询的写法?下面我分几个实用场景给你说明:
一、直接在数据库客户端执行(最基础的原生用法)
这是最直接的原生查询使用方式,你可以把这段SQL复制到MySQL客户端(比如Navicat、MySQL Workbench、命令行mysql工具)里直接执行。不过我给你优化了一下写法,让它更清晰且符合最佳实践:
SELECT fp.id, fp.name, fp.slug, fp.status, fc.name AS category_name, -- 给分类名称加别名,避免和商品名混淆 fc.slug AS category_slug, fp.approved, ff.filepath, fdp.product_id, fdp.type, fdp.sku, fdp.regular_price, fdp.sale_price, fp.created_at, fp.updated_at FROM `foduu_products` fp JOIN `foduu_details_product` fdp ON fp.id = fdp.product_id JOIN `foduu_category_product` fcp ON fp.id = fcp.product_id JOIN `foduu_filemanager` ff ON fp.filemanager_id = ff.id JOIN `foduu_categories` fc ON fcp.category_id = fc.id WHERE fc.slug = 'microsoftheadphonesadaptersmotherboardswebcam' -- MySQL里建议用单引号包裹字符串 AND fp.approved = 1 AND fp.status = 1
执行前记得确认:你连接的是正确的数据库,且所有表名、字段名和你的数据库实际结构完全匹配。
二、在主流后端框架中执行原生查询
如果你是在开发框架里需要调用这段查询,下面是几个常用框架的实现方式,都做了安全的参数绑定(防止SQL注入,一定要这么做!):
1. Laravel(PHP)
用DB::select()方法直接执行原生查询:
$categorySlug = 'microsoftheadphonesadaptersmotherboardswebcam'; $approvedStatus = 1; $productStatus = 1; $results = DB::select("SELECT fp.id, fp.name, fp.slug, fp.status, fc.name AS category_name, fc.slug AS category_slug, fp.approved, ff.filepath, fdp.product_id, fdp.type, fdp.sku, fdp.regular_price, fdp.sale_price, fp.created_at, fp.updated_at FROM `foduu_products` fp JOIN `foduu_details_product` fdp ON fp.id = fdp.product_id JOIN `foduu_category_product` fcp ON fp.id = fcp.product_id JOIN `foduu_filemanager` ff ON fp.filemanager_id = ff.id JOIN `foduu_categories` fc ON fcp.category_id = fc.id WHERE fc.slug = ? AND fp.approved = ? AND fp.status = ?", [ $categorySlug, $approvedStatus, $productStatus ]);
2. Django(Python)
使用Django的connection.cursor()执行原生查询:
from django.db import connection def get_filtered_products(): category_slug = 'microsoftheadphonesadaptersmotherboardswebcam' approved = 1 status = 1 with connection.cursor() as cursor: cursor.execute(""" SELECT fp.id, fp.name, fp.slug, fp.status, fc.name AS category_name, fc.slug AS category_slug, fp.approved, ff.filepath, fdp.product_id, fdp.type, fdp.sku, fdp.regular_price, fdp.sale_price, fp.created_at, fp.updated_at FROM `foduu_products` fp JOIN `foduu_details_product` fdp ON fp.id = fdp.product_id JOIN `foduu_category_product` fcp ON fp.id = fcp.product_id JOIN `foduu_filemanager` ff ON fp.filemanager_id = ff.id JOIN `foduu_categories` fc ON fcp.category_id = fc.id WHERE fc.slug = %s AND fp.approved = %s AND fp.status = %s """, [category_slug, approved, status]) # 把结果转成字典格式,方便后续处理 columns = [col[0] for col in cursor.description] results = [dict(zip(columns, row)) for row in cursor.fetchall()] return results
3. Spring Boot(Java)
用JdbcTemplate来执行原生查询,同时映射到DTO对象:
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; // 先定义一个DTO类来接收查询结果 class ProductDTO { private Long id; private String name; private String slug; private String categoryName; private String categorySlug; // 其他字段的getter和setter方法自行补充 } public List<ProductDTO> getProducts(JdbcTemplate jdbcTemplate) { String sql = """ SELECT fp.id, fp.name, fp.slug, fp.status, fc.name AS category_name, fc.slug AS category_slug, fp.approved, ff.filepath, fdp.product_id, fdp.type, fdp.sku, fdp.regular_price, fdp.sale_price, fp.created_at, fp.updated_at FROM `foduu_products` fp JOIN `foduu_details_product` fdp ON fp.id = fdp.product_id JOIN `foduu_category_product` fcp ON fp.id = fcp.product_id JOIN `foduu_filemanager` ff ON fp.filemanager_id = ff.id JOIN `foduu_categories` fc ON fcp.category_id = fc.id WHERE fc.slug = ? AND fp.approved = ? AND fp.status = ? """; return jdbcTemplate.query(sql, new Object[]{ "microsoftheadphonesadaptersmotherboardswebcam", 1, 1 }, new RowMapper<ProductDTO>() { @Override public ProductDTO mapRow(ResultSet rs, int rowNum) throws SQLException { ProductDTO product = new ProductDTO(); product.setId(rs.getLong("id")); product.setName(rs.getString("name")); product.setSlug(rs.getString("slug")); product.setCategoryName(rs.getString("category_name")); product.setCategorySlug(rs.getString("category_slug")); // 其他字段的映射逻辑自行补充 return product; } }); }
三、原生查询转换/使用的核心注意事项
- 适配数据库语法:不同数据库的原生语法有细微差异,比如MySQL用反引号`包裹标识符,PostgreSQL用双引号",SQL Server用方括号[],要根据你的数据库调整。
- 参数绑定必用:永远不要直接把用户输入拼接进SQL字符串,用参数绑定可以彻底避免SQL注入风险。
- 字段别名要清晰:像原查询里的
fc.name没有别名,返回结果里会和fp.name重名,处理起来很麻烦,一定要加别名区分。
内容的提问来源于stack exchange,提问作者user3201500
相关产品推荐
相关产品推荐

