PreparedStatement接口的补充问题——占位符

PreparedStatement接口继承于Statement接口,所以它拥有Statement接口中的方法,详情见
在实际开发中我们在编写SQL语句的时候可能会用到占位符?,它可以代替SQL语句的参数,然后通过setXXX()方法对SQL语句的参数进行赋值。例如

public List<Employee> selectEmp(int firstResult, int pageSize) {
        Connection con = null;
        List<Employee> list = new ArrayList<Employee>();
        try {
            con = DBCon.getCon();
            String sql = "select  * from tb_employee order by id limit ?,?";
            PreparedStatement pstmt = con.prepareStatement(sql);
            pstmt.setInt(1, firstResult);//调用PreparedStatement接口中的setInt方法
            pstmt.setInt(2, pageSize);
            ResultSet rs = pstmt.executeQuery();
            while (rs.next()) {
                Employee emp = new Employee();
                emp.setEmpId(rs.getInt("id"));
                emp.setEmpName(rs.getString("name"));
                emp.setEmpSex(rs.getString("sex"));
                emp.setEmpAge(rs.getInt("age"));
                emp.setTelephoneNo(rs.getString("telephoneNo"));
                emp.setAddress(rs.getString("address"));
                list.add(emp);
            }
            rs.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return list;
    }
<think>我们在讨论JDBC中的PreparedStatement接口,用户询问使用哪种占位符替代SQL参数。根据提供的引用资料,特别是引用[1][2][3]都明确提到了使用问号(?)作为占位符。引用[1]中:"我们使用了PreparedStatement来构建SQL语句,并通过setString()和setInt()方法来设置占位符的值",这里占位符指的就是问号(?)引用[2]中多次提到:"使用PreparedStatement和?来实现?SQL语句中放置的占位符"、"基于PreparedStatement的替代方法使用?占位符"引用[3]中代码示例也使用了问号(?):Stringsql="SELECT*FROMuser_loginWHEREuser_password=?AND(user_name=?ORuser_telNumber=?)"引用[4]中提到MyBatis中#{}会替换为?,也是指向PreparedStatement占位符机制引用[5]直接说明了PreparedStatement使用?作为占位符:"将SQL语句发送给mysql服务进行检查,编译",这里SQL语句中就是使用?作为占位符因此,答案非常明确:PreparedStatement使用问号(?)作为占位符来替代SQL参数。同时需要解释基本使用方法:创建PreparedStatement时SQL语句中用?代替具体参数值,然后使用setXxx方法按索引设置值。由于用户只问占位符类型,所以回答重点放在占位符符号上即可。</think> 在 JDBC 编程中,`PreparedStatement` 接口**统一使用问号(`?`)作为参数占位符**来替代 SQL 语句中的动态参数。具体规则如下: 1. **占位符格式**: - **单一符号 `?`**:每个需要动态赋值的参数位置必须使用一个独立的问号(`?`)。 - **示例 SQL**: ```sql SELECT * FROM users WHERE username = ? AND password = ? -- 两个占位符 INSERT INTO orders (product_id, quantity) VALUES (?, ?) -- 两个占位符 ``` 2. **参数绑定规则**: - **索引从 1 开始**:通过 `setXxx(int index, Xxx value)` 方法按占位符的**从左到右顺序**依次赋值,索引起始值为 `1`。 - **示例代码**: ```java String sql = "UPDATE products SET price = ? WHERE id = ?"; PreparedStatement pstmt = connection.prepareStatement(sql); pstmt.setDouble(1, 99.9); // 第一个?绑定为Double类型值 pstmt.setInt(2, 1001); // 第二个?绑定为Int类型值 pstmt.executeUpdate(); ``` 3. **技术优势**: - **防 SQL 注入**:占位符机制会对输入值自动转义(如引号转义为`\'`),避免恶意拼接[^5]。 - **预编译提升性能**:SQL 模板在首次执行时编译,后续仅传递参数值,减少数据库解析开销[^5]。 - **类型安全**:强制通过 `setInt()`、`setString()` 等方法进行类型校验。 4. **注意事项**: - **禁止拼接字符串**:若手动拼接参数(如 `"WHERE id=" + id`),会失去安全性和性能优势。 - **避免 `$ {}`(MyBatis 场景)**:MyBatis 中 `#{}` 对应 `PreparedStatement` 的 `?`,而 `${}` 是直接字符串替换,有注入风险[^4]。 5. **语法错误示例**: ```java // ❌ 错误:带参数的executeQuery()会导致语法异常[^3] ResultSet rs = pstmt.executeQuery(sql); // ✅ 正确:应使用无参方法 ResultSet rs = pstmt.executeQuery(); ``` ### 相关问题 1. **如何解决 `PreparedStatement` 中超过 1000 个占位符的限制(如 Oracle 的 ORA-01795 错误)?**[^2] 2. **`PreparedStatement` 的预编译机制在数据库层面如何工作?**(需开启 `useServerPrepStmts=true` 配置)[^5] 3. **MyBatis 中 `#{}` 和 `${}` 占位符的本质区别是什么?在何种场景下必须使用 `${}`?**[^4]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值