本文可作为北京尚学堂jdbc课程的学习笔记;

简介

jdbc是什么东西?

jdbc全称(Java Database Connectivity java数据库连接)

它是干什么的?

至于它是干什么的,那就应了那句老话了,说来话长..

很久很久之前,作为用户,我们有c,c++,java...各种语言,另一方面数据库领域Oracle,Mysql,DB2,SQLServer也是种类繁多。

为了方便我们用户的使用各大数据库厂商就就建立了自己的API,如下图



看上去还不错哦。

后来,我们还是觉得麻烦,虽然各个厂商有自己的API,但我Oracle和Myaql毕竟不一样呀!作为客户的我们,并不想学习那么多的API,怎么办?

再加一层呗!



至于odbc是微软出的一套东西,干的事情和jdbc一样,就是屏蔽各个数据库的不同!

看上面的图大家就应该明白,各个数据库厂商会开发自己的jdbc jar包。

至此,我们就不需要管各个数据库的差异问题了。(当然,各个数据库的sql语法还有些微的不同,再后来Hibernate出现了,这里我们先不谈)

我们只用了解一个统一的接口,就能方便的使用各个数据库。

编程步骤

LoadDriver

    Class.forName("com.mysql.jdbc.Driver");
    Class.forName("com.mysql.jdbc.Driver").newInstance();
    new com.mysql.jdbc.Driver();

三种方式都可以,不过我们经常采用第一种方式,三者有什么区别?

我们看这个例子

package load;

public class LoadTest {
    public static void main(String[] args) {
        try {
            Class.forName("load.Loaded");
            System.out.println("*******");
            Class.forName("load.Loaded").newInstance();
            System.out.println("*****");
            new Loaded();
        } catch (ClassNotFoundException |IllegalAccessException|InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

package load;

public class Loaded {
    static{
        System.out.println("i am static");
    }
    public Loaded(){
        System.out.println("i am constructed");
    }
}

运行结果:

i am static

*******

i am constructed

*****

i am constructed

大家应该明白了

Class.forName("***"); 会加载一个类,返回的结果是Class类型的,在加载过程中,会执行类中的静态语句块;

Class.forName("***").newInstance(); 它其实和new ***()是一样的,当然类只用加载一次,所以上面调用这行代码的时候没有显示i am static

new ***() 这个和上面那个的区别在于,这个方法可以传递参数,构造不同的类,但是上面的newInstance只能构造无参的对象;

在说的通俗一点,jvm要生成一个类

需要两步,加载与实例化!

第一个方式是加载,后面两个既加载,又实例化(当然,如果前面已经加载了,就不用再加载了)



另外,关于这部分源码基本的分析如com.mysql.jdbc.Driver中到底干了什么,我们后面再说,这里就不多讨论了。

获得Connection

DriverManager.getConnection(url,username,password);

三个参数的意思我就不多说了,这里需要我们注意的其实也就一个url,不过大家也不用死记硬背,知道有这么个东西就ok;

获得Statemment;

Statement st=con.creatStatemnent();

获得结果集;

首先我们得说明,这里的结果集是用ResultSet来组织的。

    ResutSet rs=st.executeQuery("select * from admininfo");

遍历结果集:

while (rs.next()) {

        System.out.println(rs.getString("Filedname"));

    }

这里我得说明一点,即使你想取得数据集中的第一条数据,rs.next()这行也必须有。我们可以理解为,初始情况下resultset内部的"游标"在第一条数据前面,我们得next一下能找到下一条数据!

close

一个原则,后建立的对象先关闭。

最基本的jdbc

下面的代码,写的比较全,只有一个要求,背下来!不要说,先看看,以后再说,这是基础!应该全文默写!!

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBC_Test2 {

    public static void main(String[] args) {

        Connection conn=null;
        Statement st=null;
        ResultSet rs=null;
        String url="jdbc:mysql://localhost:3306/webexample?useUnicode=true&characterEncoding=UTF-8";
        String userName="root";
        String passWord="";
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn=DriverManager.getConnection(url,userName,passWord);
            st=conn.createStatement();
            rs=st.executeQuery("select * from admininfo");
            while (rs.next()) {
                System.out.println(rs.getString("Aname"));
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();           //log4j 具体记录
        }catch (SQLException e) {
            e.printStackTrace();
        }
        finally{
            try {
                if (rs!=null) {
                    rs.close();
                    rs=null;
                }
                if (st!=null) {
                    st.close();
                    st=null;
                }
                if (conn!=null) {
                    conn.close();
                    conn=null;
                }

            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

几个知识点

PreparedStatement

其实Statement本身已经够用了,不过有点不方便,哪里不方便?

看下面的例子:

我想将一条数据插入到数据库中如下

      

            String name="董磊峰";
            int id=16;
            String sql="insert into admininfo (Aname,Aid) values('"+name+"',"+id+") ";
            st.executeUpdate(sql);

大家不觉得生成那个sql语句很麻烦吗?你少写一个'都有可能出错。

所以有了PreparedStatement,它也是一个接口,继承自Statement。

其用法为

       

            String name="董磊峰2";
            int id=18;
            String sql="insert into admininfo (Aname,Aid) values(?,?)";
            PreparedStatement st=conn.prepareStatement(sql);
            st.setString(1, name);         //给第一个栏位注入String型的数值name  这个不是从0开始
            st.setInt(2, id);
            st.execute();

用若干个?代替要插入的字符,比上面的sql清楚多了,不是吗?

批处理问题

如果我想执行多条sql语句怎么办?

使用Statement

            String name="董磊峰2";
            int id=154;
            int id2=487;
            String sql="insert into admininfo (Aname,Aid) values('"+name+"',"+id+") ";
            String sql2="insert into admininfo (Aname,Aid) values('"+name+"',"+id2+") ";
            System.out.println(sql);
            st=conn.createStatement();
            st.executeUpdate(sql);
            st.executeUpdate(sql2);

使用PretaredStatement

            String name="董磊峰2";
            int id=48;

            String sql="insert into admininfo (Aname,Aid) values(?,?)";
            System.out.println(sql);
            st=conn.prepareStatement(sql);
            st.setString(1, name);
            st.setInt(2, id);
            st.execute();

            st=conn.prepareStatement(sql);
            st.setString(1, name);
            st.setInt(2, id+1);
            st.execute();

似乎都不是太方便

看新的方法

使用Statement

            st=conn.createStatement();
            st.addBatch("insert into admininfo (Aname,Aid) values('"+name+"',"+id+") ");
            st.addBatch("insert into admininfo (Aname,Aid) values('"+name2+"',"+id2+") ");
            st.executeBatch();

使用PretaredStatement

            String sql="insert into admininfo (Aname,Aid) values(?,?)";
            System.out.println(sql);
            st=conn.prepareStatement(sql);
            st.setString(1, name);
            st.setInt(2, id);
            st.addBatch();

            st.setString(1, name+"ss");
            st.setInt(2, id+15);
            st.addBatch();

            st.executeBatch();

会用即可,这里不必深究。

Transaction

Transaction我们一般翻译成会话,就是一个不可分割的多条(或一条)sql语句,在一个Transaction中,这些sql语句要么全部执行成功,要么一个也不执行。

它有什么用?还用解释么?想想银行。

在jdbc中,默认一个sql语句就是一个transaction。

看看代码

      

            try{
                        conn.setAutoCommit(false);
            st=conn.createStatement();
            st.addBatch("insert into admininfo (Aname,Aid) values('"+name+"',"+id+") ");
            st.addBatch("insert into admininfo (Aname,Aid) values('"+name2+"',"+id2+") ");
            st.executeBatch();
            conn.commit();
            conn.setAutoCommit(true);    //用完了得改回去
            }catch(Exception e){
                if(conn!=null){
                conn.rollBack();          //sql代码撤销
                conn.setAutoCommit(true);  //还得改回去
                }
            }

可滚动的结果集

            String sql="select * from admininfo order by Aid";

            st=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
            rs=st.executeQuery(sql);

        /*    admininfo 表内容
         *  Aid  Aname
            15  dlf
            16  董磊峰
            18  董磊峰2
            48  董磊峰2
            49  董磊峰2
            55  董磊峰2
            154  董磊峰2
            155  董磊峰2
            487  董磊峰2
            1599  董磊峰2ss
            2000  董磊峰2
            2015  董磊峰2ss
            3000  董磊峰2666
            8000  董磊峰2hhhh
            10001  wyf
            10002  zrk
            */
            rs.absolute(4);
            System.out.println("第4   "+ rs.getInt("Aid"));
            System.out.println("第几条   "+ rs.getRow());
            rs.first();
            System.out.println("第一个   "+ rs.getInt("Aid"));
            rs.last();
            System.out.println("最后一个   "+ rs.getInt("Aid"));
            System.out.println("总数   "+ rs.getRow());
            System.out.println("是否最后一个   "+ rs.isLast());
            System.out.println("最后结尾   "+ rs.isAfterLast());
            rs.next();
            System.out.println("最后结尾   "+ rs.isAfterLast());

结果

第4   48

第几条   4

第一个   15

最后一个   10002

总数   16

是否最后一个   true

最后结尾   false

最后结尾   true

看看这些方法的名字还有结果,大家应该能知道方法的作用,不过isAfterLast方法大家估计有点迷惑。

最后一个的后面?

这个方法是判断当前指针是否已经到文件尾,注意:文件尾和最后一条记录是不同的。

比如我们开始读取 ResultSet 时,指针位于文件头,首先需要 rs.next() 执行这个方法,指针移到第一条记录后才可以进行读取。到文件尾也是一样的,读到最后一条记录后,再继续读就到文件尾了,没有记录了,执行 isAfterLast() 方法就返回 true 了。

参考资料

http://blog.163.com/yutao_inx_319/blog/static/207234007201311177482930/    java,ResultSet 类中的isAfterLast()方法

http://www.cnblogs.com/shosky/archive/2011/07/22/2114290.html  三种类加载方式的区别

漫谈jdbc的更多相关文章

  1. 漫谈可视化Prefuse(三)---Prefuse API数据结构阅读有感

    前篇回顾:上篇<漫谈可视化Prefuse(二)---一分钟学会Prefuse>主要通过一个Prefuse的具体实例了解了构建一个Prefuse application的具体步骤.一个Pre ...

  2. JDBC 数据库连接池

    http://www.cnblogs.com/lihuiyy/archive/2012/02/14/2351768.html JDBC 数据库连接池 小结   当对数据库的访问不是很频繁时,可以在每次 ...

  3. Java数据库连接技术——JDBC

    大家好,今天我们学习了Java如何连接数据库.之前学过.net语言的数据库操作,感觉就是一通百通,大同小异. JDBC是Java数据库连接技术的简称,提供连接各种常用数据库的能力. JDBC API ...

  4. 玩转spring boot——结合AngularJs和JDBC

    参考官方例子:http://spring.io/guides/gs/relational-data-access/ 一.项目准备 在建立mysql数据库后新建表“t_order” ; -- ----- ...

  5. [原创]java使用JDBC向MySQL数据库批次插入10W条数据测试效率

    使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(100000),如何提高效率呢?在JDBC编程接口中Statement 有两个方法特别值得注意:通过使用addBatch( ...

  6. JDBC MySQL 多表关联查询查询

    public static void main(String[] args) throws Exception{ Class.forName("com.mysql.jdbc.Driver&q ...

  7. JDBC增加删除修改

    一.配置程序--让我们程序能找到数据库的驱动jar包 1.把.jar文件复制到项目中去,整合的时候方便. 2.在eclipse项目右击"构建路径"--"配置构建路径&qu ...

  8. JDBC简介

    jdbc连接数据库的四个对象 DriverManager  驱动类   DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用 ...

  9. JDBC Tutorials: Commit or Rollback transaction in finally block

    http://skeletoncoder.blogspot.com/2006/10/jdbc-tutorials-commit-or-rollback.html JDBC Tutorials: Com ...

随机推荐

  1. Android动态换肤(三、安装主题apk方式)

    相比之前免安装的方式,这种方法需要用户下载并安装皮肤apk,程序写起来比免安装的要简单很多,像很多系统主题就是通过这种方式实现的. 这种方式的思路是,从所有已安装的应用程序中遍历出皮肤程序(根据特定包 ...

  2. JDBC编程-优化程序(六)

    首先完成DTO类的编写 DTO类是data tranfer object也就是数据传输类,DTO主要用于数据的传输操作,其中包含属性值,以及构造方法和getter ,setter方法等,不会包含业务逻 ...

  3. Android高级控件(六)——自定义ListView高仿一个QQ可拖拽列表的实现

    Android高级控件(六)--自定义ListView高仿一个QQ可拖拽列表的实现 我们做一些好友列表或者商品列表的时候,居多的需求可能就是需要列表拖拽了,而我们选择了ListView,也是因为使用L ...

  4. Servlet概述-servlet学习之旅(一)

    Servlet概述 servlet是server+applet的缩写.applet是运行于客户端浏览器的java小程序,java诞生的时候,因为applet而闻名于世,但是现在已经没有多少热使用了,而 ...

  5. hive编程指南——读书笔记(无知拾遗)

    set hive.metastore.warehouse.dir=/user/myname/hive/warehouse; 用户设定自己的数据仓库目录.不影响其他用户.也在$HOME/.hiverc中 ...

  6. Cocos2D iOS之旅:如何写一个敲地鼠游戏(十一):完善游戏逻辑

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  7. python使用h5py读取mat文件数据,并保存图像

    1 安装h5py sudo apt-get install libhdf5-dev sudo pip install h5py 假设你已经安装好python和numpy模块 2 读取mat文件数据 i ...

  8. 套接字工厂——ServerSocketFactory

    接收器Acceptor在接收连接的过程中,根据不同的使用场合可能需要不同的安全级别,例如在支付相关的交易就必须对信息加密后再发送,这其中还涉及到密钥协商的过程,而在另外一些普通场合则无需对报文加密.反 ...

  9. 统计git代码提交量

    以下是我写的一个脚本,可以统计在某个项目中,自己修改代码的行数,包括增加多少行,删除多少行. 可以统计当天,24小时内或全部时间内.使用时需要把代码中的author对应的值换成自己的名字. 代码如下: ...

  10. 【Unity技巧】自定义消息框(弹出框)

    写在前面 这一篇我个人认为还是很常用的,一开始也是实习的时候学到的,所以我觉得实习真的是一个快速学习工程技巧的途径. 提醒:这篇教程比较复杂,如果你不熟悉NGUI.iTween.C#的回调函数机制,那 ...