zoukankan      html  css  js  c++  java
  • jdbc中的Statement对象和Preparedstatement对象的区别,以及通过jdbc操作调用存储过程

    一、

    java.sql.*   和  javax.sql.*的包的类结构

                                |- Driver接口: 表示java驱动程序接口。所有的具体的数据库厂商要来实现此接口。

                                         |- connect(url, properties):  连接数据库的方法。

                                                            url: 连接数据库的URL

                                                                     URL语法: jdbc协议:数据库子协议://主机:端口/数据库

                                                                     user: 数据库的用户名

                                                                     password: 数据库用户密码

                                |- DriverManager类: 驱动管理器类,用于管理所有注册的驱动程序

                                         |-registerDriver(driver)  : 注册驱动类对象

                                         |-Connection getConnection(url,user,password);  获取连接对象

                                |- Connection接口: 表示java程序和数据库的连接对象。

                                                   |- Statement createStatement() : 创建Statement对象

                                                   |- PreparedStatement prepareStatement(String sql)  创建PreparedStatement对象

                                                   |- CallableStatement prepareCall(String sql) 创建CallableStatement对象

                                |- Statement接口: 用于执行静态的sql语句

                                                   |- int executeUpdate(String sql)  : 执行静态的更新sql语句(DDL,DML)

                                                   |- ResultSet executeQuery(String sql)  :执行的静态的查询sql语句(DQL)

                                         |-PreparedStatement接口:用于执行预编译sql语句

                                                            |- int executeUpdate() : 执行预编译的更新sql语句(DDL,DML)

                                                            |-ResultSet executeQuery()  : 执行预编译的查询sql语句(DQL)

                                                   |-CallableStatement接口:用于执行存储过程的sql语句(call xxx)

                                                                     |-ResultSet executeQuery()  : 调用存储过程的方法

                                |- ResultSet接口:用于封装查询出来的数据

                                                   |- boolean next() : 将光标移动到下一行

                                                   |-getXX() : 获取列的值

    Statemetent对象执行的是静态SQL语句,而PreparedStatement对象执行的是预编译SQL语句,如上图,Statement对象执行executeUpdate(String sql)和executeQuery(String sql),而PreparedStatement 对象执行的是无参的executeUpdate()和executeQuery(),从这两个方法可以看出这两个对象的特点,正因为如此,PreparedStatement可以预防SQL语句注入,更安全,当然它的效率也更高一些。

    二、通过jdbc代码调用存储过程

    代码如下

                  

    package com.a_callrablestatement;
    
    import java.sql.CallableStatement;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Types;
    
    import org.junit.Test;
    
    import com.util.DBUtil;
    
    public class Demo1 {
    
    public Connection conn = null;
    public CallableStatement cs = null;
    ResultSet rs = null;
    String driverClass = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
    String url = "jdbc:sqlserver://localhost:1433;DatabaseName=User";
    String username = "sa";
    String password = "******";
    String sql = "exec pro_findById ? ";
    public Demo1() {
    // TODO Auto-generated constructor stub
    }
    @Test
    public void test1()
    {
    
    try{
    //注册驱动
    Class.forName(driverClass);
    //连接
    conn = DriverManager.getConnection(url,username,password);
    //得到prepareCall预编译对象
    cs = conn.prepareCall(sql);
    //设置问号的占位符
    cs.setInt(1,3);
    
    rs = cs.executeQuery();
    //打印结果
    while(rs.next())
    {
    int id = rs.getInt("id");
    String name = rs.getString("username");
    String password = rs.getString("password");
    String gender = rs.getString("gender");
    String interest = rs.getString("interest");
    System.out.println(id+","+name+","+password+","+gender+","+interest);
    }
    }catch(ClassNotFoundException e)
    {
    e.printStackTrace();
    }catch(SQLException e)
    {
    e.printStackTrace();
    }finally
    {
    DBUtil.close(conn,rs,cs);
    }
    }
    
    @Test
    public void test2()
    {
    sql ="exec pro_findNameById ?,?";
    try{
    //注册驱动
    Class.forName(driverClass);
    //连接
    conn = DriverManager.getConnection(url,username,password);
    //得到prepareCall预编译对象
    cs = conn.prepareCall(sql);
    //设置问号的占位符的参数值
    cs.setInt(1,3);
    /**
    * 1.参数一,表示要设置的参数位置
    * 2.参数二,表示要返回的参数值类型 varchar(20)
    */
    cs.registerOutParameter(2, Types.VARCHAR);
    //执行操作,但不返回结果集,返回值在参数中,这里只能用execute(),不能用executeQuery(),这是在SQL Server2008中
    cs.execute();
    
    /**
    * 预编译sql中参数的位置
    */
    String name = cs.getString(2);
    //打印结果
    System.out.println(name);
    
    
    }catch(ClassNotFoundException e)
    {
    e.printStackTrace();
    }catch(SQLException e)
    {
    e.printStackTrace();
    }finally
    {
    DBUtil.close(conn,rs,cs);
    }
    }
    
    }
    
    工具类
    
    package com.util;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class DBUtil {
    
    public DBUtil() {
    // TODO Auto-generated constructor stub
    }
    public static void close(Connection conn,ResultSet rs,PreparedStatement ps )
    {
    try{
    if(conn!=null)
    {
    conn.close();
    }
    if(rs!=null)
    {
    rs.close();
    }
    if(ps!=null)
    {
    ps.close();
    }
    }catch(SQLException e)
    {
    e.printStackTrace();
    throw new RuntimeException(e);
    }
    }
    }

    1.test1()方法是调用没有返回值的存储过程

    2,test2()方法是调用有返回值的存储过程

    在调用有返回值的存储过程时,不能使用executeQuery(),否则会报没有返回结果集的错误

    而改为execute()方法后就可以得到正常的结果

    test1()中的存储过程代码

    use [User]
    go
    
    create procedure pro_findById(@id int)
    as 
    select * from [tb_user] where id=@id
    go

    test2()中的存储过程

    use [User]
    go
    create procedure findNameById @id int,@name varchar(20)
    as 
    select @name=username from tb_user where id=@id
    go

    注:SQL server 2008和jdk 1.7 加eclipse ee 4.5

    一个愿意分享技术和生活的码农
  • 相关阅读:
    Java——enum与int的转换——转载
    Java——JScrollPane设置透明——转载
    Java——JFrame与JButton添加背景
    Java——模态对话框
    u-boot_2010.6 nandflash驱动彻底分析
    linux 常用命令整理----权限管理
    linux 常用命令整理----链接文件
    linux 常用命令整理----文件操作
    linux 常用命令整理----目录操作
    linux 进程运行状态
  • 原文地址:https://www.cnblogs.com/zhuixun/p/6059797.html
Copyright © 2011-2022 走看看