0

0

漫谈jdbc

php中文网

php中文网

发布时间:2016-06-07 16:06:30

|

1336人浏览过

|

来源于php中文网

原创

本文可作为北京尚学堂jdbc课程的学习笔记; 简介 jdbc是什么东西? jdbc全称(Java Database Connectivity java数据库连接) 它是干什么的? 至于它是干什么的,那就应了那句老话了,说来话长.. 很久很久之前,作为用户,我们有c,c++,java...各种语言,另一方面数据库领

本文可作为北京尚学堂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 了。

参考资料

笔启AI论文
笔启AI论文

专业高质量、低查重,免费论文大纲,在线AI生成原创论文,AI辅助生成论文的神器!

下载

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

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

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

286

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

126

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

42

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

19

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

23

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

14

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

421

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

51

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
nginx浅谈
nginx浅谈

共15课时 | 0.9万人学习

10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

【Midjourney】从入门到精通
【Midjourney】从入门到精通

共17课时 | 1.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号