java项目往数据库插入数据时报错:Too many parameters: expected 0, was given 3 Query,占位符输入中文错误

String sql = "INSERT INTO t_user(username,passward,email) VALUES(?,?,?)";
        return updateData(sql,user.getUsername(),user.getPassward(),user.getEmali());

报错:

java.sql.SQLException: Too many parameters: expected 0, was given 3 Query: INSERT INTO t_user(username,passward,email) VALUES(,,) Parameters: [tom, tom, tom.163.com]

分析:

  1. 确定代码逻辑没有问题

  2. sql语法没没有问题

结果——是占位符?输入成了中文的,无法识别所以报错

<think>我们正在使用ApacheCommons DbUtils库进行数据库操作。出现错误:"Wrong numberof parameters: expected0, wasgiven1",意味着我们的SQL语句中并没有任何参数占位符(即没有?),但是我们在执行查询却传递了一个参数(这里是一个参数值为3的数组)。这通常发生在使用`QueryRunner`的查询方法错误信息: Query: SELECT* FROMmilepostParameters:[3] 这表明我们的SQL语句是`SELECT* FROMmilepost`,它没有参数占位符,但是我们却传递了一个参数([3])。因此,我们需要检查调用查询方法的方式。 在DbUtils中,执行查询的方法有多个重载版本。如果我们使用`query(String sql, ResultSetHandler<T> rsh,Object...params)`,那么即使SQL中没有参数占位符,我们也不应该传递参数(除非有?需要替换)。如果SQL中没有问号,我们应该使用另一个重载版本:`query(String sql, ResultSetHandler<T>rsh)`。因此,问题在于:我们在执行一个不需要参数的查询,却传递了参数。解决方案:1.如果我们要根据条件查询(例如按id查询),那么SQL中应该包含参数占位符,例如:`SELECT *FROM milepost WHEREid =?`,然后传递参数。2.如果我们不需要条件,那么就不要传递参数。 假设我们想要根据id查询一个里程碑,那么正确的做法应该是:```javapublicMilepostfindMilepostById(int mid) throwsSQLException {QueryRunner qr =new QueryRunner(JDBCUtils.getDataSource());Stringsql ="SELECT* FROMmilepostWHERE id= ?";//使用BeanHandler将结果集的第一行映射为Milepost对象BeanHandler<Milepost> handler= newBeanHandler<>(Milepost.class);//执行查询,传递参数midreturnqr.query(sql,handler,mid);} ```但是,如果我们想查询所有里程碑,那么就不需要参数: ```javapublic List<Milepost> findAllMileposts()throws SQLException {QueryRunner qr =new QueryRunner(JDBCUtils.getDataSource());Stringsql ="SELECT* FROMmilepost";//使用BeanListHandler将结果集映射为Milepost对象的列表BeanListHandler<Milepost> handler= newBeanListHandler<>(Milepost.class);return qr.query(sql,handler);} ```所以,错误的原因是我们执行了一个没有参数占位符的SQL,却传递了参数。请检查你的SQL字符串和参数传递。具体到错误信息中的SQL是`SELECT* FROMmilepost`,没有问号,所以不应该传递参数。但是我们在调用传递了一个参数[3]。因此,我们需要检查调用该查询的代码,确保在没有参数不要传递参数。例如,如果我们有类似这样的代码:```java//错误示例:即使SQL没有问号,也传递了参数qr.query("SELECT* FROMmilepost", newBeanListHandler<>(Milepost.class),3);```应该改为: ```java//正确:没有参数就不传qr.query("SELECT *FROM milepost",new BeanListHandler<>(Milepost.class));``` 或者,如果我们想按id查询,那么SQL应该改为带问号,并传递参数:```javaqr.query("SELECT *FROM milepost WHEREid =?",new BeanHandler<>(Milepost.class), mid); ```总结:-检查SQL语句中是否有参数占位符(?) -根据占位符的数量传递相应数量的参数-如果没有占位符,就不要传递参数现在,我们可以为MilepostService添加查询方法:1.按id查询单个里程碑(返回单个对象)2.查询所有里程碑(返回列表)具体实现如下:</think>### 解决 DbUtils 参数数量不匹配问题 您遇到的错误 `Wrong number of parameters: expected 0, was given 1` 是由于 SQL 语句中的参数占位符(`?`)数量与实际传递的参数数量不一致导致的。以下是详细分析和解决方案: --- ### 问题分析 1. **错误信息含义**: - `expected 0`:SQL 语句中没有参数占位符 `?` - `was given 1`:调用传递了 1 个参数 - 示例:`Query: SELECT * FROM milepost Parameters: [3]` 2. **根本原因**: - SQL 语句中没有使用 `?` 占位符,但代码尝试传递参数 - 参数传递方式错误(如直接传递值而非数组) - 参数数量与占位符数量不匹配 --- ### 解决方案 #### 1. 正确使用参数占位符 确保 SQL 语句中的 `?` 数量与参数数量一致: ```java // 错误:无占位符却传递参数 String sql = "SELECT * FROM milepost"; // 无? qr.query(sql, handler, mid); // 传递了参数mid → 错误 // 正确:添加占位符 String sql = "SELECT * FROM milepost WHERE id = ?"; // 1个? qr.query(sql, handler, mid); // 正确 ``` #### 2. 查询单个里程碑(按 ID) ```java public Milepost getMilepostById(int mid) throws SQLException { QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource()); String sql = "SELECT * FROM milepost WHERE id = ?"; // 使用 BeanHandler 映射单条记录 BeanHandler<Milepost> handler = new BeanHandler<>(Milepost.class); return qr.query(sql, handler, mid); } ``` #### 3. 查询所有里程碑 ```java public List<Milepost> getAllMileposts() throws SQLException { QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource()); String sql = "SELECT * FROM milepost"; // 使用 BeanListHandler 映射多条记录 BeanListHandler<Milepost> handler = new BeanListHandler<>(Milepost.class); return qr.query(sql, handler); // 无参数不传递 } ``` #### 4. 带条件查询(多个参数) ```java public List<Milepost> getMilepostsByStatus(int state) throws SQLException { QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource()); String sql = "SELECT * FROM milepost WHERE state = ?"; BeanListHandler<Milepost> handler = new BeanListHandler<>(Milepost.class); return qr.query(sql, handler, state); } ``` --- ### 关键修复点 1. **占位符与参数匹配**: ```java // 正确示例:2占位符对应2个参数 String sql = "UPDATE milepost SET name=?, state=? WHERE id=?"; Object[] params = {newName, newState, mid}; // 3个参数 → 错误! // 修正:参数数量必须等于占位符数量 Object[] params = {newName, newState, mid}; // 3个参数对应3个? ``` 2. **参数传递规范**: ```java // 错误:直接传递基本类型 qr.update(sql, mid); // 正确:使用Object数组包装 qr.update(sql, new Object[]{mid}); // 单个参数也要用数组 ``` 3. **空参数处理**: ```java // 无参数不要传递null qr.query(sql, handler); // 正确 qr.query(sql, handler, null); // 错误!会触发参数数量检查 ``` --- ### 修改功能优化建议 在您的 `updateMilepost` 方法中,添加参数验证确保安全: ```java public void updateMilepost(Milepost milepost) throws Exception { // 验证必要字段 if (milepost.getId() == null) { throw new IllegalArgumentException("里程碑ID不能为空"); } QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource()); String sql = "UPDATE milepost SET name=?, launchtime=?, depict=?, state=? WHERE id=?"; Object[] params = { milepost.getName(), milepost.getLaunchtime(), milepost.getDepict(), milepost.getState(), milepost.getId() // 确保WHERE条件参数在最后 }; int count = qr.update(sql, params); // ... 处理结果 } ``` --- ### 预防此类错误的技巧 1. **使用命名参数**(推荐使用其他库如 Spring JDBCTemplate): ```java // 示例:Spring 风格命名参数 MapSqlParameterSource params = new MapSqlParameterSource(); params.addValue("id", mid); jdbcTemplate.query("SELECT * FROM milepost WHERE id = :id", params, rowMapper); ``` 2. **SQL 日志监控**: ```java // 添加日志输出实际执行的SQL和参数 System.out.println("Executing: " + sql + " | Params: " + Arrays.toString(params)); ``` 3. **使用预编译语句**: ```java try (Connection conn = dataSource.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, name); // 显式设置参数位置 stmt.setInt(2, state); // ... 执行查询 } ``` 通过以上修正,您的参数传递问题将得到解决,同增强了代码的健壮性和可维护性[^1]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值