JDBC基础教程

本文实例讲述了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程序设计有所帮助。

(0)

相关推荐

  • 一个jdbc 测试程序代码

    复制代码 代码如下: import java.sql.Date; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSetMetaData; import java.sql.Statement; import java.sql.ResultSet; import java.sql.DriverManager; import java.sql.SQLException; publ

  • JDBC示例代码

    本教程提供了如何创建一个简单的JDBC应用程序的示例.演示如何打开一个数据库连接,执行SQL查询,并显示结果. 所有在此模板的例子中提到的步骤,将在本教程的后续章节说明. 创建JDBC应用程序: 有下列涉及构建JDBC应用程序的六个步骤: 导入数据包 . 需要包括含有需要进行数据库编程的JDBC类的包.大多数情况下,使用 import java.sql.*  就可以了. 注册JDBC驱动程序. 需要初始化驱动程序,可以与数据库打开一个通信通道. 打开连接. 需要使用DriverManager.g

  • 基于Java回顾之JDBC的使用详解

    尽管在实际开发过程中,我们一般使用ORM框架来代替传统的JDBC,例如Hibernate或者iBatis,但JDBC是Java用来实现数据访问的基础,掌握它对于我们理解Java的数据操作流程很有帮助. JDBC的全称是Java Database Connectivity. JDBC对数据库进行操作的流程:•连接数据库•发送数据请求,即传统的CRUD指令•返回操作结果集JDBC中常用的对象包括:•ConnectionManager•Connection•Statement•CallableStat

  • 深入解析Java中的JDBC事务

    事务 事务是一步或多步组成操作序列组成的逻辑执行单元,这个序列要么全部执行,要么则全部放弃执行.事务的四个特性:原子性(Atomicity).一致性(Consistency).隔离性(IsoIation)和持续性(Durability)原子性(Atomicity):事务应用最小的执行单元,不可再分.是事务中不可再分的最小逻辑执行体. 一致性(Consistency):事务的执行结果,必须使数据库的从一个一致性的状态变到另一个一致性的状态. 隔离线(IsoIation):各个事务的执行互不干扰,任

  • JDBC简介_动力节点Java学院整理

    前言:什么是JDBC 维基百科的简介: Java 数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法.JDBC也是Sun Microsystems的商标.它JDBC是面向关系型数据库的. 简单地说,就是用于执行SQL语句的一类Java API,通过JDBC使得我们可以直接使用Java编程来对关系数据库进行操作.通过封装,可以使开发人员使用纯Java API完成S

  • JDBC环境设置(中文详解)

    安装Java: 安装J2SE开发工具包5.0(JDK 5.0)下载:Java官方网站. 请确保以下环境变量设置,如下所述: JAVA_HOME: 此环境变量应该指向安装JDK的目录,例如:C:\Program Files\Java\jdk1.5.0CLASSPATH: 此环境变量应已适当的路径设置,如: C:\Program Files\Java\jdk1.5.0_20\jre\libPATH: 此环境变量应指向适当的JRE bin,如: C:\Program Files\Java\jre1.5

  • JDBC基础教程

    本文实例讲述了JDBC基础知识与技巧.分享给大家供大家参考.具体分析如下: 1.什么是JDBC? 通俗来讲JDBC技术就是通过java程序来发送SQL语句到数据库,数据库收到SQL语句后执行,把结果返回给java程序管理. 2.使用JDBC要有什么条件呢? A)目标数据库主机的地址 B)数据库软件在该主机上所占用的端口号 C)登陆数据库用的用户名 D)该用户名的密码 E)连接数据库 3.JDBC技术的原理 我们知道,数据库是有各种类型的,不同的厂商生产的数据库标格和规范是不同的,这时候,如果我们

  • Java Mybatis框架入门基础教程

    一.Mybatis介绍 MyBatis是一款一流的支持自定义SQL.存储过程和高级映射的持久化框架.MyBatis几乎消除了所有的JDBC代码,也基本不需要手工去 设置参数和获取检索结果.MyBatis能够使用简单的XML格式或者注解进行来配置,能够映射基本数据元素.Map接口和POJOs(普通java对象)到数据库中的记录. 二.MyBatis工作流程 (1)加载配置并初始化 触发条件:加载配置文件 配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个个

  • Mybatis_plus基础教程(总结篇)

    一.简介 官网网址:http://mp.baomidou.com/ 参考教程:http://mp.baomidou.com/guide/ 二.特性 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 强大的 CRUD 操作:内置通用 Mapper.通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 支持 Lambda 形式调用:通过 Lambda

  • Javascript常用运算符(Operators)-javascript基础教程

    javascript基础教程算术运算符 运算符 运算符说明 示例 示例说明 + 加法 x+y 如果x为整数2,y为整数5, x+y等于7 如果x为字符串"text1", y为字符串"fun", x+y则等于"text1fun" - 减法 x-y * 乘法 x*y / 除法 x/y % 两者相除求余数 x%y 如果x等于10, y等于3, x%y结果等于1 ++ 递增 x++ 如果x等于10, x++等于11 -- 递减 y-- 如果y等于10,

  • 微信小程序开发入门基础教程

    微信小程序开发入门基础教程 本文档将带你一步步创建完成一个微信小程序,并可以在手机上体验该小程序的实际效果. 开发准备工作获取微信小程序的 AppID 登录 https://mp.weixin.qq.com ,就可以在网站的"设置"-"开发者设置"中,查看到微信小程序的 AppID 了,注意不可直接使用服务号或订阅号的 AppID . 下载开发工具 下载地址:https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/dow

  • AngularJs 60分钟入门基础教程

    AngularJs是一个不错的用于开发SPA应用(单页Web应用)的框架.单页Web应用(single page web application,SPA),就是只有一张Web页面的应用.浏览器一开始会加载必需的HTML.CSS和JavaScript,所有的操作都在这张页面上完成,由JavaScript来控制不同view在这个页面上的呈现.本文源于Youtube上一个不错的AngularJs的入门教程视频:AngularJS Fundamentals In 60-ish Minutes,主要讲解了

  • JS基础教程——正则表达式示例(推荐)

    正则表达式的() [] {}有不同的意思. () 是为了提取匹配的字符串.表达式中有几个()就有几个相应的匹配字符串. (\s*)表示连续空格的字符串. []是定义匹配的字符范围.比如 [a-zA-Z0-9] 表示相应位置的字符要匹配英文字符和数字.[\s*]表示空格或者*号. {}一般用来表示匹配的长度,比如 \s{3} 表示匹配三个空格,\s[1,3]表示匹配一到三个空格. (0-9) 匹配 '0-9′ 本身. [0-9]* 匹配数字(注意后面有 *,可以为空)[0-9]+ 匹配数字(注意后

  • Kotlin 基础教程之反射

    Kotlin 基础教程之反射 概述 反射是语言与库中的一组功能, 可以在运行时刻获取程序本身的信息.在Kotlin中,不仅可以通过发射获取类的信息,同时可以获取函数和属性的信息.也就是说,在在运行时刻得到一个函数或属性的名称和数据类型) 可以通过简单的函数式, 或交互式的编程方式实现. 在Java平台上, 使用反射功能所需要的运行时组件是作为一个单独的JAR文件发布的( kotlinreflect.jar). 这是为了对那些不使用反射功能的应用程序, 减少其运行库的大小. 如果你需要使用反射,

  • Kotlin 基础教程之异常

    Kotlin 基础教程之异常 概述 在Kotlin-null的处理里提到的NPE,它就是一个异常.而,异常是程序运行过程中出现的错误.在Kotlin中,所有的异常都继承于Throwable.对于每一个异常而言,它不仅仅包括异常的信息,还可以选择性包括异常的原因,而其原因也是一个异常的实例. 抛出异常 使用 throw表达式抛出异常: throw MyException("Hi There!") 捕获异常 如果在函数内部抛出了异常(或者在函数内部调用的其他函数抛出了异常),这个函数将在抛

  • Kotlin 基础教程之数组容器

    Kotlin 基础教程之数组容器 Arrays Kotlin 标准库提供了arrayOf()创建数组, **ArrayOf创建特定类型数组 val array = arrayOf(1, 2, 3) val countries = arrayOf("UK", "Germany", "Italy") val numbers = intArrayOf(10, 20, 30) val array1 = Array(10, { k -> k * k

随机推荐