【澳门金沙vip】jdbc中的Statement对象和Preparedstatement对象的分别,以及通过jdbc操作调用存储进度,preparedstatement

一、先来讲说,什么是java中的Statement:Statement是java实行数据库操作的三个要害措施,用于在曾经创设数据库连接的底蕴上,向数据库发送要试行的SQL语句。具体步骤:

一、概述

  本文首要介绍Java接连数据库的焦点格局和步子,并对内部的几个主旨举行简单表明。

jdbc中的Statement对象和Preparedstatement对象的界别,以及因而jdbc操作调用存储进程,preparedstatement

一、

java.sql.*   和  javax.sql.*的包的类协会

 

                            |- Driver接口:
表示java驱动程序接口。全体的求实的数据库商家要来完毕此接口。

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

                                                        url:
连接数据库的U陆风X8L

                                                                
UENCOREL语法: 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 = “qwer1234”;
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(),不然会报未有再次回到结果集的不当澳门金沙vip 1

而改为execute()方法后就能够获得平常的结果

test1()中的存款和储蓄进程代码

use [User]
go

create procedure pro_findById(@id int)
as
select * from [tb_user] where
[email protected]
go

 

test2()中的存款和储蓄进度

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

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

一、 java.sql.* 和 javax.sql.*的包的类组织 |- Dri…

  1.率起首入java.sql.*;这个包。

二、数据库访谈步骤

  在Java中一连数据库实行的拜谒首要有以下几个步骤:

  1. 加载数据库驱动
  2. 挂号数据库驱动
  3. 创立到数据库的连年
  4. 访谈数据库

  首先,要调用Class.ForName()加载并注册mysql驱动程序类,加载驱动程序驱动类后,必要登记驱动程序类的四个实例,DriverManager类担负管理驱动程序,这几个类提供了registerDriver()方法来注册驱动程序类的实例,並且大家无需亲自调用这么些方法,因为Drive接口的驱动程序类都含有了静态代码块,在这一个代码块中会调用registerDriver()方法来注册本身的三个实例。

  然后调用DriverManager类的getConnection方法创建到数据库的连天。在成立连接后,须求对数据库进行拜望。在java.sql包中定义了八个接口:Statement、PrepareStatement和CallableStatement,分别对应分裂的调用形式。当中:  

  Statement:用于奉行静态的sql语句。

  PrepareStatement:从Statement接口承继而来,它的靶子表示一条预编写翻译过的sql语句,通过调用Connection对象的prepareStatement()方法获得。

  CallableStatement:用于实践sql存款和储蓄进度,该接口从PrepareStatement接口承袭而来,通过调用Connection对象的prepareCall()方法得到CallableStatement对象。

  完整的探访数据库代码如下:

package com.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class CreateDB
{
    public static void main(String[] args)
    {
        String url="jdbc:mysql://localhost:3306";
        String user="root";
        String password="281889";
        String driverclass="com.mysql.jdbc.Driver";//JDBC类名
        try
        {
            //加载JDBC驱动,当这个类被加载时,类加载器会执行该类的静态代码块从而注册驱动程序的一个实例
            Class.forName(driverclass);  

            //建立数据库的连接
            Connection conn=DriverManager.getConnection(url,user,password);

            //访问数据库
            Statement stmt=conn.createStatement();
            stmt.execute("use information_schema");
            int i=0;
            ResultSet rs1=stmt.executeQuery("SELECT * FROM information_schema.SCHEMATA where SCHEMA_NAME='student'");
            while(rs1.next())  //判断是否含有student数据库
                i++;
            if(i==0)
                stmt.executeUpdate("create database student");

            stmt.executeUpdate("use student");

            int j=0;
            ResultSet rs2=stmt.executeQuery("select * from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='student' and TABLE_NAME='stuinfo' ");
            while(rs2.next()) //判断数据库中是否含有stuinfo表
                j++;
            if(j==0)
                stmt.executeUpdate("create table stuinfo(sno INT not null primary key,name VARCHAR(50) not null,age int,sex VARCHAR(50))");

            stmt.addBatch("insert into stuinfo values(0420,'阿斌',25,'男')");
            stmt.executeBatch();
            stmt.close();
            stmt=null;
            conn.close();
            conn=null;
        } 
        catch (ClassNotFoundException e)
        {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } 
        catch (SQLException e)
        {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }
}

  2.然后加载驱动,制造连接,得到Connection接口的的兑现指标,比如对象名称为做conn。

 三、要点表达

  3.然后再用conn对象去创设Statement的实例,方法是:Statement
stmt = conn.creatStatement(“SQL语句字符串”);

  1、execute(String sql)、executeUpdate(String sql)和executeQuery(String sql)的区别:

  execute:试行回来三个结果集的sql语句。

  Returns:true if the first
result is a ResultSet object

       false if it is an update count or there are no
results

  executeUpdate:实施类似insert、update大概delete的sql语句。

  Returns:(1) the row count for SQL
Data Manipulation Language (DML) statements

        (2) 0 for SQL statements that return nothing     

   executeQuery:实施钦定的sql语句,再次回到贰个ResultSet对象,用于查看试行的结果。

   Returns:a ResultSet object that
contains the data produced by the given query;“

  ps:executeQuery重临的ResultSet长久都不会为null

  Statement 对象用于将 SQL
语句发送到数据库中。实际上有三种 Statement
对象,它们都看成在加以连接上进行SQL语句的包容器:Statement、PreparedStatement(它从 Statement
承继而来)和CallableStatement(它从 PreparedStatement
传承而来)。它们都专项使用于发送特定项指标 SQL 语句:Statement
对象用于实行不带参数的简短 SQL 语句;PreparedStatement
对象用于施行带或不带参数的预编写翻译 SQL 语句;CallableStatement
对象用于执行对数据库已囤积过程的调用。

  2、ResultSet对象

  ResultSet对象以逻辑表格的方式封装了施行数据库操作的结果集,其目的保证了二个针对性当前数据行的游标,开端状态下游标在首先行在此之前,能够通过next()方法移动游标到下一行。

  综上所述,计算如下:Statement每一次推行sql语句,数据库都要实践sql语句的编写翻译,最佳用于仅实践一回查询并回到结果的场合,效能当先PreparedStatement.但存在sql注入危机。PreparedStatement是预编译推行的。在推行可变参数的一条SQL时,PreparedStatement要比Statement的频率高,因为DBMS预编译一条SQL当然会比多次编写翻译一条SQL的功效高。安全性越来越好,有效制止SQL注入的难点。对于数十回重复实施的言辞,使用Prepared

  3、Statement 与 PreparedStatement的区别(摘录自):

1.语法不相同

Statement只帮衬静态编写翻译,SQL语句是写死的。

PreparedStatement帮助预编写翻译,用?号来占位。

2.作用分裂

Statement每便都要发送一条SQL语句,不帮忙缓存,试行成效低。

PreparedStatement协助预编写翻译,缓存在数据库,只需发送参数,试行功能快。

3.安全性分歧

Statement轻易被注入。

流入:狡猾的成员得以编写特殊的SQL语句来入侵数据库。

诸如:要询问有个别客户的消息

诚如情状:SELECT * FROM user_list where username=xxx and
password=xxx;(这里的xxx本应该为客商填写自个儿的客商名和密码)

流入意况:SELECT * FROM user_list where username=’abc’ or 1=1 —
password=xxx;

如此1=1恒等,并且在password前拉长了“–”号,前边的剧情成为了批注不被实施。也正是说,那样就可以不要密码地查询全部的客商音信。

PreparedStatement,因为规定了SQL语句中的参数,所以可以免止流入。