JDBC中PreparedStatement常用操作实践

本文介绍JDBC中PreparedStatement接口的使用方法,包括executeQuery、executeUpdate和execute三种执行SQL语句的方法,并详细讲解了批处理功能的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【1】PreparedStatement

PreparedStatement接口提供了三种执行 SQL 语句的方法:executeQueryexecuteUpdateexecute

使用哪一个方法由 SQL 语句所产生的内容决定。一般的使用习惯Select语句使用executeQuery()方法执行,DeleteUpdateInsert语句使用executeUpdate()方法执行,而CreateDrop语句使用execute()方法执行,当然也可以使用executeUpdate()方法。

① executeQuery

用于产生单个结果集的语句,例如 SELECT 语句。 被使用最多的执行 SQL 语句的方法是 executeQuery。这个方法被用来执行 SELECT 语句,它几乎是使用最多的 SQL 语句。

② executeUpdate

用于执行 INSERTUPDATEDELETE 语句以及 SQL DDL(数据定义语言)语句,例如 CREATE TABLEDROP TABLE

INSERTUPDATEDELETE 语句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的返回值是一个整数,指示受影响的行数(即更新计数)。

对于 CREATE TABLEDROP TABLE 等不操作行的句,executeUpdate 的返回值总为零。

使用executeUpdate方法是因为在 createTable 中的 SQL 语句是 DDL (数据定义语言)语句。创建表,改变表,删除表都是 DDL 语句的例子,要用 executeUpdate 方法来执行。你也可以从它的名字里看出,方法 executeUpdate 也被用于执行更新表 SQL 语句。实际上,相对于创建表来说,executeUpdate 用于更新表的时间更多,因为表只需要创建一次,但经常被更新。

③ 方法execute

用于执行返回多个结果集、多个更新计数或二者组合的语句。也可用于执行 INSERT、UPDATE 或 DELETE 语句。

④ 用法举例

① 增加、修改、删除都用execute(),也可用executeUpdate(),针对于INSERT、UPDATE 或 DELETE 语句

 public int addAirEnvironmentPresent(M_AirEnviromentPresentDTO airDTO){
  int index = 1;
  String sql = "insert into airPresent(airForecastPlace,ForecastTime,TSPvalue,remark) values(?,?,?,?)";
  try {
   ps = conn.prepareStatement(sql);
   ps.setString(index++, airDTO.getAirForecastPlace());
   ps.setString(index++, airDTO.getForecastTime());
   ps.setString(index++, airDTO.getTSPvalue());
   ps.setString(index++, airDTO.getRemark());
   ps.execute();   
  } catch (SQLException e) {
   e.printStackTrace();
  }
  return 1;
 }

② 查询调用executeQuery(),针对于SELECT语句

public ArrayList getAirEnvironmentPresentAll(){
  ArrayList list = new ArrayList();
  String sql = "select * from airPresent";
  try {
   ps = conn.prepareStatement(sql);
   rs = ps.executeQuery();
   while(rs.next()){
    dto = new M_AirEnviromentPresentDTO();
    dto.setId(rs.getInt("id"));
       dto.setAirForecastPlace(rs.getString("airForecastPlace"));
    dto.setForecastTime(rs.getString("forecastTime"));
    dto.setTSPvalue(rs.getString("tspvalue"));
    dto.setRemark(rs.getString("remark"));
    list.add(dto);
   }
  } catch (SQLException e) {
   e.printStackTrace();
  }
  return list;
 }

【2】批处理

JDBC使用Statement和PreparedStatement实现批处理功能。

① PreparedStatement

步骤如下:

  • 根据connection和SQL得到PreparedStatement;
  • 设置参数并 addBatch();
  • 重复第二步直到所有需要执行的SQL参数设置完;
  • executeBatch()将一批SQL提交给数据库来执行。

② Statement
步骤如下:

  • 根据connection得到Statement;
  • addBatch(String sql)在批处理缓存中加入一条sql语句;
  • 重复第二步直到所有需要执行的SQL添加完;
  • executeBatch()将一批SQL提交给数据库来执行。

注意:PreparedStatement中使用批量更新时,要先设置好参数后再使用addBatch()方法加入缓存。批量更新中只能使用更改、删除或插入语句,不能有select语句。

① 批量插入

① 使用Statement

实例如下:


/* 
 *1,首先把Auto commit设置为false,不让它自动提交 
 *2,进行手动提交(commit) 
 *3,提交完成后回复现场将Auto commit,还原为true, 
 *4,当异常发生执行catch中SQLException时,记得要rollback(回滚); 
 **/
public static void main(String args[]) {  
        Connection con = null;  
        Statement stm = null;  
        try {  
            con = JDBTools.getConnection();  
            stm = con.createStatement();  
            con.setAutoCommit(false);  
            // 若不出现异常,则继续执行到try语句完,否则跳转到catch语句中  
            stm.addBatch("insert into student values(1,'jane','高数',100)");  
            stm.addBatch("insert into student values(2,'lily','c#',98)");  
            stm.addBatch("insert into student values(3,'lucy','java',90)");  
            stm.addBatch("insert into student values(4,'tom','英语',89)");  
            stm.addBatch("insert into student values(5,'jack','java',63)");  
            /* 
             * int[] executeBatch() throws 
             * SQLException将一批命令提交给数据库来执行,如果全部命令执行成功,
             * 则返回更新计数组成的数组。 
             */  
            stm.executeBatch();  
            System.out.println("插入成功!");  
            // commit:若成功执行完所有的插入操作,则正常结束  
            con.commit();  
            System.out.println("提交成功!");  
            con.setAutoCommit(true);  

        } catch (SQLException e) {  
            e.printStackTrace();  
            try {  
    //rollback: 若出现异常,对数据库中所有已完成的操作全部撤销,则回滚到事务开始状态  
                if (!con.isClosed()) {  
                    con.rollback();  
                    System.out.println("提交失败,回滚!");  
                    con.setAutoCommit(true);  
                }  
            } catch (SQLException e1) {  
                e1.printStackTrace();  
            } finally {  
                JDBTools.closeStatement(stm);  
                JDBTools.closeConnection(con);  
            }  
        }  
    }  


② 使用PreparedStatement

实例如下:

public static void main(String args[]) {  
    Connection con = null;  
    PreparedStatement pstm = null;  
    try {  
        // 1. 建立与数据库的连接  
        con = JDBTools.getConnection();  
        // 2. 准备并添加批量处理sql语句  
        // 1)创建PreparedStatement语句(发送slq请求):  
        pstm = con.prepareStatement("insert into student values(?,?,?,?)");  
        //首先把Auto commit设置为false,不让它自动提交  
        con.setAutoCommit(false);
        // 2) 设置sql语句1参数  
        pstm.setInt(1, 33);  
        pstm.setString(2,"wangqin");  
        pstm.setString(3, "c++");  
        pstm.setDouble(4, 78.5);  
        // 3) 添加到此 PreparedStatement 对象的批处理命令中。  
        pstm.addBatch();  
        
        //设置sql语句2  
        pstm.setInt(1, 34);  
        pstm.setString(2,"wuytun");  
        pstm.setString(3, "c");  
        pstm.setDouble(4, 77);  
        // 添加到此 PreparedStatement 对象的批处理命令中。  
        pstm.addBatch();  
        
        //  设置sql语句3  
        pstm.setInt(1, 31);  
        pstm.setString(2,"tetet");  
        pstm.setString(3, "c++");  
        pstm.setDouble(4, 90);  
        //添加到此 PreparedStatement 对象的批处理命令中。  
        pstm.addBatch();  
      
        // 将一批sql提交给数据库来执行,如果全部命令执行成功,
        //则返回更新计数组成的数组。  
        pstm.executeBatch();  
        
        System.out.println("插入成功!");  
        // 若成功执行完所有的插入操作,则正常结束  
        //进行手动提交(commit)  
        con.commit();
        System.out.println("提交成功!");  
        //提交完成后回复现场将Auto commit,还原为true, 
        con.setAutoCommit(true); 
    } catch (SQLException e) {  
        e.printStackTrace();  
        try {  
            // 若出现异常,对数据库中所有已完成的操作全部撤销,则回滚到事务开始状态  
            if(!con.isClosed()){  
                con.rollback();
                System.out.println("插入失败,回滚!");  
                con.setAutoCommit(true);  
            }  
        } catch (SQLException e1) { 
e1.printStackTrace();  
        }  
    }finally{  
        JDBTools.closePreparedStatement(pstm);  
        JDBTools.closeConnection(con);  
    }  
}  


② 批量删除

使用PreparedStatement实例

public void deleteBat(Integer[] catNo){  
try {  
    Connection con=JDBTools.getConnection();  
    String sql="delete from cat where catno=?";  
    con.setAutoCommit(false);  
    PreparedStatement ps=con.prepareStatement(sql);  
    for (Integer in : catNo) {  
        ps.setInt(1, in);  
        ps.addBatch();  
    }  
    int[] result=ps.executeBatch();  
    con.commit();  
    for (int i : result) {  
        System.out.println(i);  
    }  
} catch (ClassNotFoundException e) {  
    e.printStackTrace();  
} catch (SQLException e) {  
    e.printStackTrace();  
}

其实无论插入,删除和更新,核心思想都一样,都是博文片头的步骤。

<think>好的,我现在要处理用户关于Android 12中RKNN开发配置和使用教程的问题。首先,我需要回顾用户提供的引用内容,看看是否有相关的信息。 用户提供了三个引用。引用1提到了RKNN Model Zoo和RKNN Toolkit2的环境配置,包括安装Miniconda3。引用2是关于系统镜像下载,特别是Ubuntu 22.04版本和导出ONNX模型。引用3讨论了RV1808/1126使用RKNN作为MediaPipe推理后端的步骤,包括配置参数如use_rga、use_mmap和data_type的设置,以及反量化的处理。 用户的问题集中在Android 12上,所以需要将引用中的信息与Android系统关联起来。引用3提到了MediaPipe和RKNN的集成,这可能适用于Android开发,但需要确认是否支持Android 12。此外,RKNN Toolkit2的环境配置可能在不同平台上有所不同,用户可能需要针对Android进行调整。 接下来,我需要考虑Android开发中RKNN的一般步骤,比如环境准备、模型转换、集成到Android应用、配置参数和性能优化。结合引用中的信息,模型转换部分可以参考引用2提到的导出ONNX模型,然后使用RKNN Toolkit转换为RKNN格式。引用3中的配置参数(如use_rga、use_mmap、data_type)可能在Android中同样适用,但需要查阅相关文档确认。 可能还需要指导用户如何将RKNN库集成到Android项目中,比如添加依赖项或NDK配置。此外,性能优化方面,引用3提到的反量化处理可能需要特别注意,尤其是在Android设备上的实现。 最后,确保回答结构清晰,分步骤说明,并引用提供的资料。需要验证引用中的信息是否适用于Android 12,例如系统镜像是否支持,或者是否有特定版本的要求。如果某些步骤在引用中没有明确说明,可能需要提示用户参考官方文档或社区资源。</think>### Android 12 RKNN 开发配置与使用教程 #### 1. **环境准备** - **系统镜像与工具链**: 根据引用[2],建议使用Ubuntu 22.04作为开发环境,并下载Orange Pi 5 Pro等支持RKNN的硬件镜像。对于Android 12开发,需确保RKNN Toolkit2适配Android NDK版本(推荐NDK 21+)[^2]。 - **安装RKNN Toolkit2**: 参考引用[1],通过Miniconda3配置Python环境(建议Python 3.8),并安装RKNN Toolkit2以支持模型转换与推理。命令示例: ```bash pip install rknn_toolkit2 ``` #### 2. **模型转换(ONNX转RKNN)** - **导出ONNX模型**: 使用PyTorch或TensorFlow等框架导出模型为ONNX格式(引用[2])。 - **转换为RKNN格式**: 编写RKNN配置文件(`config.yml`),指定输入尺寸、量化方式等参数。示例代码: ```python from rknn.api import RKNN rknn = RKNN() rknn.config(target_platform='rk3568', mean_values=[[127.5]], std_values=[[127.5]]) rknn.load_onnx(model="model.onnx") rknn.build(do_quantization=True, dataset="dataset.txt") rknn.export_rknn("model.rknn") ``` #### 3. **Android项目集成** - **添加RKNN库依赖**: 将编译好的RKNN动态库(`librknnrt.so`)和模型文件(`model.rknn`)放入Android项目的`jniLibs`目录。 - **JNI接口开发**: 通过JNI调用RKNN的C/C++ API实现推理。关键配置参考引用[3]: ```cpp #include <rknn/rknn_runtime.h> rknn_context ctx; int ret = rknn_init(&ctx, model_path, 0, 0, nullptr); ret = rknn_inputs_set(ctx, input_num, input_attrs); ret = rknn_run(ctx, nullptr); ret = rknn_outputs_get(ctx, output_num, output_attrs, nullptr); ``` #### 4. **关键配置参数** - **use_rga与use_mmap**: 根据引用[3],若Android设备不支持硬件加速(如RGA),需将`use_rga`和`use_mmap`设为`false`。 - **数据量化类型**: `data_type`可选`uint8`或`fp32`。若选`uint8`,需手动实现反量化;若选`fp32`,RKNN会自动处理[^3]。 #### 5. **性能优化** - **多线程推理**: 利用Android的`ThreadPoolExecutor`并行处理输入数据。 - **内存优化**: 启用`use_mmap`(若支持)减少内存拷贝开销,或通过零拷贝技术直接操作物理内存。 #### 6. **调试与验证** - **日志输出**: 启用RKNN的调试模式(`RKNN_LOG_LEVEL=DEBUG`)查看详细运行信息。 - **性能分析**: 使用`rknn.query(RKNN_QUERY_PERF_DETAIL)`获取各层耗时,针对性优化模型结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流烟默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值