当前位置: 移动技术网 > IT编程>开发语言>Java > JDBC基础教程

JDBC基础教程

2019年07月22日  | 移动技术网IT编程  | 我要评论
本文实例讲述了jdbc基础知识与技巧。分享给大家供大家参考。具体分析如下: 1.什么是jdbc? 通俗来讲jdbc技术就是通过java程序来发送sql语句到数据库,数据

本文实例讲述了jdbc基础知识与技巧。分享给大家供大家参考。具体分析如下:

1.什么是jdbc?

通俗来讲jdbc技术就是通过java程序来发送sql语句到数据库,数据库收到sql语句后执行,把结果返回给java程序管理。

2.使用jdbc要有什么条件呢?

a)目标数据库主机的地址

b)数据库软件在该主机上所占用的端口号

c)登陆数据库用的用户名

d)该用户名的密码

e)连接数据库

3.jdbc技术的原理

我们知道,数据库是有各种类型的,不同的厂商生产的数据库标格和规范是不同的,这时候,如果我们用java代码来发送sql语句,就要根据不同的数据库来写一套又一套的操作代码,这对程序开发者的开发成本是十分巨大的,所以,sun公司在开发jdbc技术的时候,规定了一套标准接口,数据库产商都必须提供一个驱动来实现这套接口,那么,只要程序开发者在开发时使用了该数据库的驱动,就用一致的方法来开发了,而不需自己写一套有一套的代码去适应不同的数据库。

4.jdbc中的核心api

|- driver : 驱动程序类实现的接口。

  |-connection connect(string url, properties info)  --用于连接数据库,得到连接对象

properties 里需要设置的参数:

    url: 数据库连接的url字符串。协议+数据库子协议+主机+端口+数据库

    user: 数据库用户名

    password: 用户的密码

  |-connection :    与数据库连接的接口

      |- statement createstatement()   --创建statement对象,用于发送sql语句

      |- preparedstatement preparestatement(string sql)  -创建preparedstatement对象,用于发送预编译的sql语句

      |-callablestatement preparecall(string sql)  --创建callablestatement对象,用于调用存储过程。

      |-statement: 用于执行静态sql语句

          |-int executeupdate(string sql)  --执行更新操作(ddl+dml)

          |-resultset executequery(string sql)  --执行查询操作(dql)

      |- preparedstatement: 用于执行预编译的sql语句

          |- int executeupdate() -- 执行更新操作

          |- resultset executequery()    -- 执行查询操作

      |- callablestatement: 用于执行存储过程的sql

          |- resultset executequery()  --调用存储过程

          |- resultset: 结果集。用于封装数据库的查询后的数据

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

              |- object getobject(int columnindex) -- 得到字段上的值

了解完又哪些api,下面我们就来使用jdbc发送sql语句吧~

5.使用statement对象操作数据库

ddl与dml操作

步骤1

导包,因为我使用的是mysql数据库,所以要使用jdbc技术,必须使用由mysql数据库产商提供的数据库驱动,所以,第一步我们要把数据库驱动包导入工程里。

使用的包名:mysql-connector-java-5.1.7-bin.jar

步骤2

创建一个普通的类,在里面添加一个方法,在该方法中按照以下步骤

复制代码 代码如下:
//url
    private string url = "jdbc:mysql://localhost:3306/vmaxtam";
    //user
    private string user = "root";
    //password
    private string password = "root";

public void testddl()throws exception{
        //1.注册驱动
        class.forname("com.mysql.jdbc.driver");
       
        //2.获取连接
        connection conn = drivermanager.getconnection(url, user, password);
       
        //3.创建statement对象
        statement stmt = conn.createstatement();
       
        //4.准备sql语句
        string sql  ="create table student(sid int primary key,sname varchar(20),age int)";
       
        //5.通过statement对象发送sql语句,返回执行结果
        int count = stmt.executeupdate(sql);
       
        //6.打印执行结果
        system.out.println("影响了"+count+"条记录");
}
//7.关闭资源
if(statement!=null)
{
    statement.close();
}

if(conn!=null)
{
    conn.close();
}


如果要进行dql与ddl操作,都可以把sql语句写好,然后调用statement的executlupdate方法来给数据库执行sql语句,这个方法返回一个整数值,表示数据库中有多少行受到了影响。

如果我们不改变上述的程序,想要再向数据库发出sql语句,那么又要写一个程序来再次连接,操作完后又要关闭statement对象 和connection对象,这是十分繁琐的。所以,我们一般把连接过程和释放对象的过程抽取到一个工具类中。工具类中的代码如下:

复制代码 代码如下:
public class sqlutil {
    private static string url = "jdbc:mysql://localhost:3306/vmaxtam";
    private static string user = "root";
    private static string password = "root";

    // 获取连接
    public static connection getconnection() {
        connection conn = null;
        try {
            // 1.注册驱动
            class.forname("com.mysql.jdbc.driver");
            // 2.获取连接
            conn = drivermanager.getconnection(url, user, password);
            // 3.获得statement对象
            statement statement = conn.createstatement();
        } catch (exception e) {
            // todo auto-generated catch block
            e.printstacktrace();
        }
        return conn;
    }

    // 7.关闭资源
    public static void close(statement statement, connection connection) {
        {
            try {
                if (statement != null)
                    statement.close();
                if (connection != null) {
                    connection.close();
                }
            } catch (sqlexception e) {
                // todo auto-generated catch block
                e.printstacktrace();
            }
        }
    }
}

还要考虑的情况就是:

一)一个用户只需要注册一次驱动就行,不用每次连接数据库都注册驱动,所以我们把注册驱动的过程写在静态代码块中。

二)url 和用户名,密码还有驱动类名,在程序里是写死的,为了能够在不改代码的前提下更换数据库 或者更换用户,我们通常把这些信息写到一份配置文件中。

配置文件写在工程的src目录下,名为db.properties

复制代码 代码如下:
url=jdbc:mysql://localhost:3306/vmaxtam
user=root
password=root
driverclass=com.mysql.jdbc.drive

然后再sqlutil中读取该配置文件,最后优化成下面代码
复制代码 代码如下:
public class sqlutil {
    private static string url = null;
    private static string user = null;
    private static string password = null;
    private static string driverclass= null;

    static{
        try {
            //1.获得字节码对象
            class clazz = sqlutil.class;
           
            //2.调用getresourceasstream获取路径
            inputstream inputstream = clazz.getresourceasstream("/db.properties");
            properties pro = new properties();
            pro.load(inputstream);
           
            //3.读取参数
            url=pro.getproperty("url");
            password=pro.getproperty("password");
            user=pro.getproperty("user");
            driverclass=pro.getproperty("driverclass");
           
            class.forname(driverclass);
        } catch (exception e) {
            e.printstacktrace();
            system.out.println("注册失败!" + e.getmessage());
            throw new runtimeexception(e);
        }
    }
   
    // 获取连接
    public static connection getconnection() {
        connection conn = null;
        try {       
            // 获取连接
            conn = drivermanager.getconnection(url, user, password);
            // 获得statement对象
            statement statement = conn.createstatement();
        } catch (exception e) {
            e.printstacktrace();
        }
        return conn;
    }

    // 关闭资源
    public static void close(statement statement, connection connection) {
        {
            try {
                if (statement != null)
                    statement.close();
                if (connection != null) {
                    connection.close();
                }
            } catch (sqlexception e) {
                // todo auto-generated catch block
                e.printstacktrace();
            }
        }
    }
}

dql操作

那么如何用jdbc来查询数据库中的数据呢?

复制代码 代码如下:
@test
    public void testdsl() throws exception {
        //获取连接
        cnn2=sqlutil.getconnection();
        statement statement = cnn2.createstatement();
   
       
        //准备sql语句
        string sql = "select * from subject";
       
        //调用executequery执行查询语句
        resultset res = statement.executequery(sql);
       
        //查询结束后res会指向表头,想要获取数据必须不断地指向查询结果的下一行,当没有下一行数据时,返回0.
        while(res.next())
        {
            //获取查询结果中字段为“sjid”的值,并且要明确类型
            int id = res.getint("sjid");
           
            //获取查询结果中字段为“sjname”的值,并且要明确类型
            string name = res.getstring("sjname");
            system.out.println("id:" + id + "  name:" + name);
        }
        sqlutil.close(statement, cnn2);
}

以上就是使用statement对象来操作数据库了~

6.使用preparedstatement操作数据库

preparedstatement对象其实就是一个特殊的statement对象,它能够预编译sql语句,当你把参数设置好,然后就可以去执行sql语句了~

ddl与dml操作

复制代码 代码如下:
package com.vmaxtam.sqltest;

import java.sql.connection;
import java.sql.preparedstatement;

import org.junit.test;

public class preparedstatementtest {
    connection connection = null;
    @test
    public void ddldmltest() throws exception {
        // 1.获取连接
        connection = sqlutil.getconnection();

        // 2.准备sql语句,预编译语句,参数用?号占位
        string sql = "insert into subject values(?,?)";

        // 3.获得对象
        preparedstatement preparedstatement = connection.preparestatement(sql);

        /*
         * 4.设置sql参数 需要参数是第几个,并且知道它的类型 下面第一句表示:sql语句第一个参数是int类型,参数值设置为3,如此类推
         */
        preparedstatement.setint(1, 3);
        preparedstatement.setstring(2, "英语");

        // 5.交给数据库执行sql
        int num = preparedstatement.executeupdate();

        system.out.println("有" + num + "条记录受到了影响");

              sqlutil.close(preparedstatement , connection );
    }
}

以上就是使用preparedstatement对象来进行插入语句的发送,同理,ddl与dml类的语句都可以根据这样来发送.

preparedstatement预编译的好处:

preparedstatement的预编译可以使你可以通过设置不同的参数来查询不同的目标,在数据库端,只会保存一段预编译语句,但是如果你使用statement来发送语句,每发送一条,数据库中就会存一条,这可能会造成占用大量内存。

dql操作

复制代码 代码如下:
@test
    public void dqltest() throws exception {
        // 1.获取连接
        connection = sqlutil.getconnection();

        // 2.准备sql语句,预编译语句,参数用?号占位
        string sql = "select * from subject where sjid=? or sjname=?";

        // 3.获得对象
        preparedstatement preparedstatement = connection.preparestatement(sql);

        /*
         * 4.设置sql参数 需要参数是第几个,并且知道它的类型 下面第一句表示:sql语句第一个参数是int类型,参数值设置为3,如此类推
         */
        preparedstatement.setint(1, 2);
        preparedstatement.setstring(2, "语文");

        // 5.交给数据库执行sql
        resultset rst = preparedstatement.executequery();
       
        //6.迭代结果集
        while(rst.next())
        {
            int id = rst.getint("sjid");
            string name = rst.getstring("sjname");
            system.out.println("id:" + id + "  name:" + name);
        }
       
        //7.关闭连接
        sqlutil.close(preparedstatement, connection);
}

也是调用executequery();方法即可,得到结果集后迭代输出~

既然statement 与 preparedstatement那么相似,比较它们的优缺点吧~

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语句中的参数,所以可以防止注入。

结论:建议使用preparedstatement,因为它更快更安全

7.使用callablestatement执行存储过程

使用callablestatement只是执行存储过程,创建存储过程我们还是要在数据库内创建的。

步骤1

现在数据库建好一个存储过程:

复制代码 代码如下:
delimiter $
create procedure pro_add(in a int , in b varchar(20),out c int)
begin   
    select * from subject where sjid=a or sjname=b;
    set c=a+a+a+a;
end $

步骤2

利用java代码执行,并得到输出参数

复制代码 代码如下:
@test
public void calast() throws exception {
        //获取连接
        connection= sqlutil.getconnection();
        //准备sql语句
        string sql = "call pro_add(?,?,?)";
       
        //得到callablestatement对象
        callablestatement cbs = connection.preparecall(sql);
       
        //设置输入参数,和preparedstatement一样
        cbs.setint(1, 3);
        cbs.setstring(2, "数学");
       
        /*那么如何设置输出参数呢?
         * 需要注册输出参数!
         */
        cbs.registeroutparameter(3, java.sql.types.integer);//需要使用内置对象来设置参数类型
       
        //执行sql语句
        cbs.executequery();
       
        //利用getxxx方法得到相应位置的输出参数
        integer num= cbs.getint(3);
       
        system.out.println("a*4 is " + num);
       
             //关闭资源
        sqlutil.close(cbs, connection);
}

希望本文所述对大家的java程序设计有所帮助。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网