JDBC第一次学习

 JDBC(Java Data Base Connectivityjava数据库连接),由一些类和接口构成的API,它是J2SE的一部分,由java.sql,javax.sql包组成。

应用程序、JDBC API、数据库驱动及数据库之间的关系:

连接数据的步骤:

  1. 注册驱动 (只做一次)。
  2. 建立连接(Connection)。
  3. 创建执行SQL的语句(Statement)。
  4. 执行语句。
  5. 处理执行结果(ResultSet)。
  6. 释放资源。

快速起步示例:

导包(如果是使用eclipse等IDE工具,无须担心,只是要注意导入的是java.sql,javax.sql的类或接口)

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
static void test() throws SQLException, ClassNotFoundException {
        //1.注册驱动
        //DriverManager.registerDriver(new com.mysql.jdbc.Driver());
        //System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver");
        Class.forName("com.mysql.jdbc.Driver");//将com.mysql.jdbc.Driver加载到虚拟机,推荐方式

        //2.建立连接
        /*
         * jdbc(协议名):子协议(mysql):子名称(无)//主机名:端口号(主机名:端口号可以缺省)/数据库名?属性名=属性值&....
         */
        String url = "jdbc:mysql://localhost:3306/jdbc";
        String user = "root";
        String password = "yezi";
        Connection conn = DriverManager.getConnection(url, user, password);

        //3.创建语句
        Statement st = conn.createStatement();

        //4.执行语句
        ResultSet rs = st.executeQuery("select * from user");

        //5.处理结果
        while(rs.next()) {
            System.out.println(rs.getObject(1)+"\t"+rs.getObject(2)+
                    "\t"+rs.getObject(3)+"\t"+rs.getObject(4));
        }
        //6.释放资源(注意顺序)
        rs.close();
        st.close();
        conn.close();
    }

注册驱动(3种方式):

  1. Class.forName(“com.mysql.jdbc.Driver”);——将驱动类com.mysql.jdbc.Driver加载到虚拟机中。推荐这种方式,不会对具体的驱动类产生依赖。
  2. DriverManager.registerDriver(com.mysql.jdbc.Driver);——会造成DriverManager中产生两个一样的驱动,并会对具体的驱动类产生依赖。
  3. System.setProperty(“jdbc.drivers”, “driver1:driver2”);——虽然不会对具体的驱动类产生依赖,但注册不太方便,所以很少使用。

建立连接:

Connection conn = DriverManager.getConnection(url, user, password);

url格式:

JDBC:子协议:子名称//主机名:端口/数据库名?属性名=属性值&…

user,password可以用“属性名=属性值”方式告诉数据库。

其他参数如:useUnicode=true&characterEncoding=GBK。

释放资源:

释放ResultSet, Statement,Connection。

数据库连接(Connection)是非常稀有的资源,用完后必须马上释放,如果Connection不能及时正确的关闭将导致系统宕机(?)Connection的使用原则是尽量晚创建,尽量早的释放。

以上代码还需要进行优化,优化后的代码如下:

首先建立一个工具类(JdbcUtils),用于注册驱动、建立连接、释放资源:

public final class JdbcUtils {
    private static String url = "jdbc:mysql://localhost:3306/jdbc";
    private static String user = "root";
    private static String password = "yezi";

    private JdbcUtils() {

    }
    /*
     * 静态代码块
     * 随着类的加载而执行,只执行一次,并优先于主函数。用于给类进行初始化。
     */
    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            throw new ExceptionInInitializerError(e);
        }
    }
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, user, password);
    }
    public static void free(ResultSet rs, Statement st, Connection conn) {
        //比较规范的释放方式,比较麻烦
        try {
            if(rs != null)
                rs.close();
        } catch(SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if(st != null)
                    st.close();
            } catch(SQLException e) {
                e.printStackTrace();
            } finally {
                if(conn != null)
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
            }
        }
    }
}
    /*
     * JDBC访问数据库的模板
     */
    static void template() throws ClassNotFoundException, SQLException {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            //2.建立连接
            conn = JdbcUtils.getConnection();
            //单例模式
            //conn = JdbcUtilsSing.getInstance().getConnection();

            //3.创建语句
            st = conn.createStatement();

            //4.执行语句
            rs = st.executeQuery("select * from user");

            //5.处理结果
            while(rs.next()) {
                System.out.println(rs.getObject(1)+"\t"+rs.getObject(2)+
                        "\t"+rs.getObject(3)+"\t"+rs.getObject(4));
            }
        } finally {
            JdbcUtils.free(rs, st, conn);
        }
    }

当然还可以使用单例模式(开发原则:定义单例,建议使用饿汉式)来建立连接。

只要在JdbcUtils类中加入以下三句(懒汉式在此就不赘述):

private static JdbcUtilsSing instance = new JdbcUtilsSing();
private JdbcUtilsSing() {

}
public static JdbcUtilsSing getInstance() {
    return instance;
}

基本的CRUD(创建、读取、更新、删除)模板代码:

增加对应SQL的INSERT,返回增加成功的行(记录)数 。

更新(修改)对应SQL的UPDATE,返回被修改的行(记录)数。

删除对应SQL的DELETE,返回被删除的行(记录)数 。

public class CRUD {

    public static void main(String[] args) throws SQLException {
        //create();
        //read();
        //update();
        delete();
    }

    static void create() throws SQLException {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            //2.建立连接
            conn = JdbcUtils.getConnection();
            //3.创建语句
            st = conn.createStatement();
            //4.执行语句
            String sql = "insert into user (name,birthday,money) values (‘name1‘,‘1987-01-01‘,400)";
            int i = st.executeUpdate(sql);
            System.out.println("i="+i);
        } finally {
            JdbcUtils.free(rs, st, conn);
        }
    }

    static void read() throws SQLException {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            //2.建立连接
            conn = JdbcUtils.getConnection();
            //3.创建语句
            st = conn.createStatement();
            //4.执行语句
            rs = st.executeQuery("select id,name,birthday,money from user");
            //5.处理结果
            while(rs.next()) {
                System.out.println(rs.getObject("id")+"\t"+rs.getObject("name")+
                        "\t"+rs.getObject("birthday")+"\t"+rs.getObject("money"));
            }
        } finally {
            JdbcUtils.free(rs, st, conn);
        }
    }

    static void update() throws SQLException {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            //2.建立连接
            conn = JdbcUtils.getConnection();
            //3.创建语句
            st = conn.createStatement();
            //4.执行语句
            String sql = "update user set money = money + 10";
            int i = st.executeUpdate(sql);
            System.out.println("i="+i);
        } finally {
            JdbcUtils.free(rs, st, conn);
        }
    }

    static void delete() throws SQLException {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            //2.建立连接
            conn = JdbcUtils.getConnection();
            //3.创建语句
            st = conn.createStatement();
            //4.执行语句
            String sql = "delete from user where id > 4";
            int i = st.executeUpdate(sql);
            System.out.println("i="+i);
        } finally {
            JdbcUtils.free(rs, st, conn);
        }
    }

}

CRUD总结:

增、删、改用Statement.executeUpdate来完成,返回整数(匹配的记录数),这类操作相对简单。

查询用Statement.executeQuery来完成,返回的是ResultSet对象,ResultSet中包含了查询的结果;查询相对于增、删、改要复杂一些,因为有查询结果要处理。

SQL注入,PreparedStatement和Statement

在SQL中包含特殊字符或SQL的关键字(如:‘ or 1 or ‘)时Statement将出现不可预料的结果(出现异常或查询的结果不正确),可用PreparedStatement来解决。

PreperedStatement(从Statement扩展而来)相对Statement的优点:

  1. 没有SQL注入的问题。
  2. Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。
  3. 数据库和驱动可以对PreperedStatement进行优化(只有在相关联的数据库连接没有关闭的情况下有效)。

代码如下:

static void read(String name) throws SQLException {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            //2.建立连接(最耗时)
            conn = JdbcUtils.getConnection();
            long start = System.currentTimeMillis();
            //3.创建预处理sql语句,在构造时就给它sql语句
            String sql = "select id,name,birthday,money from user where name = ?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, name);
            //4.执行语句
            //rs = ps.executeQuery(sql);//注意此次调用的是Statement接口里的方法
            rs = ps.executeQuery();
            //5.处理结果
            while(rs.next()) {
                System.out.println(rs.getInt("id")+"\t"+rs.getString("name")+
                        "\t"+rs.getDate("birthday")+"\t"+rs.getFloat("money"));
            }
            long end = System.currentTimeMillis();
            System.out.println("read:"+(end-start));
        } finally {
            JdbcUtils.free(rs, ps, conn);
        }
    }

JDBC读写日期类型

jdbc通常处于数据访问层,主要是和数据库打交道,所用到的一般日期类型都是java.sql.Date,而在业务层我们使用的日期类型一般都是java.util.Date。两者的关系是:java.sql.Date继承java.util.Date。我们在插入的时候传递的是java.util.Date,而ps.setDate()方法要求的是java.sql.Date,所以要进行一下转化。

例(insert):

static void create(String name, Date birthday, float money) throws SQLException {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            //2.建立连接
            conn = JdbcUtils.getConnection();
            //3.创建语句
            String sql = "insert into user (name,birthday,money) values (?,?,?)";
            ps = conn.prepareStatement(sql);
            ps.setString(1, name);
            /*
             * birthday.getTime()返回的是从1970-01-01 00:00:00到birthday的毫秒数
             */
            ps.setDate(2, new java.sql.Date(birthday.getTime()));
            ps.setFloat(3, money);
            //4.执行语句
            int i = ps.executeUpdate();
            System.out.println("i="+i);
        } finally {
            JdbcUtils.free(rs, ps, conn);
        }
    }

例(read):

static Date read(int id) throws SQLException {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        Date birthday = null;
        try {
            //2.建立连接
            conn = JdbcUtils.getConnection();
            //3.创建语句
            st = conn.createStatement();
            //4.执行语句
            rs = st.executeQuery("select birthday from user where id = " + id);
            //5.处理结果
            while(rs.next()) {
                //取值的时候是java.sql.Date赋值给一个父类类型java.util.Date是没有问题的
                //birthday = rs.getDate("birthday");//输出2016-03-23
                /*
                 * 当然也可以像insert的时候那样转换一下
                 * 不过好麻烦,而且输出的没有格式化哟!
                 */
                birthday = new Date(rs.getDate("birthday").getTime());//输出Wed Mar 23 00:00:00 CST 2016
            }
            return birthday;
        } finally {
            JdbcUtils.free(rs, st, conn);
        }
    }

JDBC读写Clob(大文本数据类型)

因为数据库产品不一样,所以表示大文本数据类型的字段也不一样,mysql:text,oracle:Clob。

时间: 2024-11-03 05:34:04

JDBC第一次学习的相关文章

JDBC再学习

JDBC是规范,地球人都知道. 啥是规范呢?反正我说不好,真要让我说的话,就是SUN制订了一大堆接口,然后你要是想实现一些功能就要去实现这些接口,他要是也想要实现这些功能也得去老实儿的实现这些接口. JDBC就是这些接口们,java.sql包下面有好多个接口文件,这些接口文件就是所谓的规范,标准. 无论Oracle,MySql,还是DB2,SqlServer都实现了这些接口.这样一来我们只需要针对着jdk中的接口编程就可以了. 记得上学的时候,最讨厌的就是JDBC,因为就这里需要记一大串东西,第

Linux内核分析第一次学习报告

Linux内核分析第一次学习报告 学生 黎静 学习内容 1.存储程序计算机工作模型 冯诺依曼体系结构:核心思想为存储程序计算机. CPU抽象为for循环,总是执行下一条指令,内存保存指令和数据,CPU来解释和执行这些指令. API:应用程序编程接口(程序员与计算机的接口界面) ABI:二进制接口,指令编码(程序员与CPU的接口界面) 2.X86汇编 1.寄存器 (1)通用寄存器 (2)段寄存器: (3)标志寄存器 2.计算机的汇编指令 (1)movl指令: 寄存器寻址,寄存器模式,以%开头的寄存

《信息安全系统设计基础+Linux 内核分析》第一次学习总结

<信息安全系统设计基础+Linux 内核分析>第一次学习总结 教材学习内容总结 学习了<庖丁解牛>的第一章.知道的概念有: 存储程序计算机 = 冯诺依曼计算机,主要思想是:将程序存放在计算机存储器中,然后按存储器中的程序的首地址来执行程序的第一条指令,接下来就是一步一步按照程序中的编写好的指令来一步一步执行,直至程序结束. 冯诺依曼体系结构的要点如下图.底层是:RAM,ROM,运算器(ALU),控制器,寄存器. 由图可知:寄存器是在CPU中的,而RAM,ROM不是在CPU中的,它们

mysql杂乱无章的第一次学习和使用

作为一个小白,唯一的自学能力很重要.我偏向于linux系统的学习. 第一次学的人也可以看看.截图较多 Mysql 命令 进入mysql   mysql -u root -p 查看当前所有数据库: SHOW DATABASES 进入某一个数据库: use + 数据库名 查看库中数据表 SHOW TABLES+ 表名   如果没在数据库中也需要吧库名 加入 查看数据表内容 DESCRIBE + 表名   简写 DESC +表名 创建新的库 CREATE DATABASES+库名 + MySQL DB

JDBC&amp;nbsp;学习笔记——&amp;nbsp;大数据…

转自:http://even2012.iteye.com/blog/1886950 1.使用JDBC处理大数据 在实际开发中,程序需要把大文本或二进制数据保存到数据库. 基本概念:大数据也称之为LOB(Large Objects),LOB又分为:clob和blob (a)clob用于存储大文本.(mysql 中采用Text) (b)blob用于存储二进制数据,例如图像.声音.二进制文等. 对MySQL而言只有blob,而没有clob,mysql存储大文本采用的是Text,其体系中的Text和bl

JDBC基础学习(四)&mdash;数据库事务

一.事务基本认识 1.事务的概述      为了保证数据库中数据的一致性,数据的操作应当是离散的成组的逻辑单元.当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应当全部视为错误,所有从起始点以后的操作应全部回退到开始状态.      事务的操作: 先定义开始一个事务,然后对数据做修改操作,这时如果提交(commit),这些数据就永久的保存下来,如果回退(rollback),数据库管理系统就放弃所有的修改而回到开始事务的状态.   2.事务的属性 (1)原子性(Atm

JDBC的学习--尚硅谷

1.数据库的连接 [java] view plain copy /** * DriverManager 是驱动的管理类. * 1). 可以通过重载的 getConnection() 方法获取数据库连接. 较为方便 * 2). 可以同时管理多个驱动程序: 若注册了多个数据库连接, 则调用 getConnection() * 方法时传入的参数不同, 即返回不同的数据库连接. * @throws Exception */ @Test public void testGetConnection2() t

JDBC基础学习(一) 第一个JDBC示例代码

创建JDBC应用程序: 我们以<MYSQL权威指南>中mylibray的authors表为例 下面是构建JDBC应用程序的六个步骤: 导入数据包 . 需要包括含有需要进行数据库编程的JDBC类的包.大多数情况下,使用 import java.sql.*  就可以了 注册JDBC驱动程序. 需要初始化驱动程序,可以与数据库打开一个通信通道 打开连接. 需要使用DriverManager.getConnection() 方法创建一个Connection对象,它代表与数据库的物理连接 执行查询 . 

JDBC基础学习

1.概念:java数据库连接技术 2.JDBC:是一个规范,提供接口(面向接口编程) 3.JDBC API:提供程序员调用的接口和类,集成在java.sql 和javax.sql包中.如:DriverManager类(管理不同的JDBC驱动).Connerction接口.Statement接口.ResultSet接口 4.JDBC API主要功能:与数据库建立连接.执行SQL语句.处理结果 5.三大接口: <1>Connerction接口:负责连接数据库并担任传输数据的任务 <2>