JDBC的概念(摘自百度百科)


JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。

将Java语言和JDBC结合起来使程序员不必为不同的平台编写不同的应用程序,只须写一遍程序就可以让它在任何平台上运行,这也是Java语言“编写一次,处处运行”的优势。

JDBC对Java程序员而言是API,对实现与数据库连接的服务提供商而言是接口模型。作为API,JDBC为程序开发提供标准的接口,并为数据库厂商及第三方中间件厂商实现与数据库的连接提供了标准方法。

简单地说,JDBC 可做三件事:与数据库建立连接、发送 操作数据库的语句并处理结果。

JDBC的相关架构


jdbc的作用位置:

jdbcAPI:

jdbc相关URL:

JDBC的构建步骤:


注意:

1)测试数据程序之前,一定要记得打开数据库所在计算机的mySQL服务。不然浪费的时间不可限量。

2)一定记得导入mySQL的jar包。

3)最好将Connection对象设置成单例模式,以防止数据库访问量过大时,造成内存崩溃。

4)使用Class对象的forName()方法,要在静态方法中或者静态块中。

5)记得相关数据库操作后进行释放内存,清理环境。

6)PreparedStatement继承自Statement,所以Statement的相关方法,PreparedStatement可以调用。同时PreparedStatement很强大,推荐多使用它。

7)要将相关释放内存的语句放在try...catch语句中的finally中,以防止try块中的语句执行失败而相关内存没有得到释放。

展示案例


package com.java_JDBC;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; public class JDBC_test { private static String Driver="com.mysql.jdbc.Driver"; //数据库驱动
//连接数据库的URL地址
private static String url="jdbc:mysql://localhost:3306/hellojdbc?useUnicode=true&characterEncoding=UTF-8";
private static String username="root";//数据库连接用户名
private static String password="123456";//数据库连接密码 private static Connection conn=null;//数据库连接对象
private static Statement stat=null;//语句陈述对象
private static ResultSet rs=null;//结果数据集
private static PreparedStatement pst=null;//预编译语句 //使用静态块的方式加载驱动
static {
try {
//调用Class对象的静态forName()方法加载数据库驱动类
Class.forName(Driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} } //使用单例模式返回数据库连接对象
public static Connection getConnection() throws SQLException{
if(conn==null){
conn=DriverManager.getConnection(url, username, password);
return conn;
}
return conn; } //测试数据库连接是否正常
public static void isConnect() throws SQLException{
Connection con=getConnection();
if(con!=null)
System.out.println("数据库连接正常");
else
System.out.println("数据库连接失败");
} //查询全部数据库表中所有信息
public static void QueryToAll(){
try {
stat=conn.createStatement();//由连接获取语句陈述对象
rs=stat.executeQuery("select * from roster");//获取结果集信息
while(rs.next()){
System.out.println("id:"+rs.getInt("id")+",name:"+rs.getString("name")+",age:"+rs.getInt("age"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
clean();
} } //按名字查找数据库中信息
public static void QueryForName(String name){
try {
pst = conn.prepareStatement("select * from roster where name=?");//获取预编译语句
pst.setString(1, name);//设置预编译语句参数
rs=pst.executeQuery();//执行预编译语句,获取结果数据集
while(rs.next()){
System.out.println("id:"+rs.getInt("id")+",name:"+rs.getString("name")+",age:"+rs.getInt("age"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
clean();
} } //增加数据库中数据信息
public static void insert(){
try {
String sql="insert into roster(id,name,age) values ('4','zhangsan','14')";
stat=conn.createStatement();
int count=stat.executeUpdate(sql);//执行语句陈述对象的更新操作
System.out.println("插入操作成功,插入信息条数为"+count);
} catch (SQLException e) {
e.printStackTrace();
}finally{
clean();
} } //修改数据库中数据信息
public static void alter(){
try {
String sql="update roster set age=12 where name='zhangsan'";
stat=conn.createStatement();
int count = stat.executeUpdate(sql);//执行语句陈述对象的更新操作
System.out.println("修改操作成功,修改信息条数为"+count);
} catch (SQLException e) {
e.printStackTrace();
}finally{
clean();
} } //删除数据库中数据信息
public static void delete(){
try {
String sql="delete from roster where name='zhangsan'";
stat=conn.createStatement();
int count=stat.executeUpdate(sql);//执行语句陈述对象的更新操作
System.out.println("删除操作成功,删除信息条数为"+count);
} catch (SQLException e) {
e.printStackTrace();
}finally{
clean();
} } //释放内存,清理环境
public static void clean(){
try {
if(rs!=null)
rs.close();
if(pst!=null)
pst.close();
if(stat!=null)
stat.close(); //不能关闭单例模式下的connection连接对象,否则当一个数据库操作完成后便不能进行其他数据库操作
// if(conn!=null)
// conn.close();
// } catch (SQLException e) {
e.printStackTrace();
} } public static void main(String[] args) throws SQLException {
isConnect();
QueryForName("Bob");
System.out.println("--------------------------------------");
QueryToAll();
System.out.println("--------------------------------------");
insert();
System.out.println("--------------------------------------");
QueryToAll();
System.out.println("--------------------------------------");
alter();
System.out.println("--------------------------------------");
QueryToAll();
System.out.println("--------------------------------------");
delete();
System.out.println("--------------------------------------");
QueryToAll(); } }

执行结果:

 使用JDBC常遇到的问题:


问题一:

编写sql语言的过滤条件太弱,导致一次读出过多的数据记录。

解决方法:修改或增加过滤条件。


问题二:

海量数据读取,可能造成溢出异常。(数据条数过多)

分析原因:读出的数据量超过了JVM的内存限制。

解决方法:使用“游标”。每次只读出来一部分数据记录进行处理,处理完成以后再对下一部分数据记录进行读取处理。

如何使用“游标”?

1)首先需要在数据库的URL中增加一个参数:

相关代码示例:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; public class JDBC_fetch { private static String Driver="com.mysql.jdbc.Driver";
private static String url="jdbc:mysql://localhost:3306/hellojdbc?useCursorFetch=true";
private static String username="root";//数据库连接用户名
private static String password="123456";//数据库连接密码
private static PreparedStatement pst=null;
private static ResultSet rs=null; private static Connection conn=null;
static {
try {
Class.forName(Driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} public static void fetchTest(){
try {
conn=DriverManager.getConnection(url, username, password);
pst=conn.prepareStatement("select * from roster");
pst.setFetchSize(1);//设置游标大小
rs=pst.executeQuery();
while(rs.next()){
System.out.println("id:"+rs.getInt("id")+",name:"+rs.getString("name")+",age:"+rs.getInt("age"));
} } catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public static void main(String[] args) { fetchTest(); }

如上面游标大小设置,JDBC就会一次读取一条记录,处理完再读取下一条记录。

在本案例中输出效果和不设置游标的结果是相同的。


问题三:

读取数据库表大字段,例如博客,图片等等。(单个数据量所占内存过大)

解决方法:

使用流方式。将数据以流的方式,每次读取一段。

相关代码实例:

    while(rs.next()){
//获取对象流
InputStream in=rs.getBinaryStream("blog");
//将对象流写入文件
File f=new File(FILE_URL);
OutputStream out=null;
out=new FileOutStream(f);
int temp=0;
while((temp=in.read())!=-1)
out.write(temp);//边读边写
}
in.close();
out.close();

问题四:

海量数据插入数据库,一条一条地插入————太慢

分析原因:每一条数据的插入都需要客户端到服务器的交互,每一次都存在时间消耗和代价。

解决方法:

批处理。一次提交多条sql语句,节省网络开销。

怎么进行批处理?

相关代码示例:

//批处理
Statement stmt=conn.createStatement();
for(String user:users){
stmt.addBatch("insert into roster(name) values("+user+")");
}
stmt.executeBatch();
stmt.clearBatch();

问题五:

中文乱码的问题。

解决方法:

在数据库URL中加入“characterEncoding=UTF-8”

private static String url="jdbc:mysql://localhost:3306/hellojdbc?useUnicode=true&characterEncoding=UTF-8";

参考博客:

https://www.cnblogs.com/erbing/p/5805727.html

https://www.cnblogs.com/wuziyue/p/4827295.html

使用JDBC连接MySQL数据库的一个基本案例的更多相关文章

  1. java jdbc 连接mysql数据库 实现增删改查

    好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...

  2. Crystal Reports 2008(水晶报表) JDBC连接mysql数据库

    在本blog中,主要介绍的是Crystal Reports 2008使用JDBC连接mysql数据库. 在连接之间,首先要确认你电脑上面都安装了mysql数据库. 其次,就是jdbc连接数据时候所使用 ...

  3. JDBC连接MySQL数据库及演示样例

    JDBC是Sun公司制定的一个能够用Java语言连接数据库的技术. 一.JDBC基础知识         JDBC(Java Data Base Connectivity,java数据库连接)是一种用 ...

  4. JDBC连接MySQL数据库及示例

      JDBC是Sun公司制定的一个可以用Java语言连接数据库的技术. 一.JDBC基础知识         JDBC(Java Data Base Connectivity,java数据库连接)是一 ...

  5. java用JDBC连接MySQL数据库的详细知识点

    想实现java用JDBC连接MySQL数据库.需要有几个准备工作: 1.下载Connector/J的库文件,下载Connector/J的官网地址:http://www.mysql.com/downlo ...

  6. 分页查询信息(使用jdbc连接mysql数据库实现分页查询任务)

             分页查询信息       使用jdbc连接mysql数据库实现分页查询任务 通过mysql数据库提供的分页机制,实现商品信息的分页查询功能,将查询到的信息显示到jsp页面上. 本项目 ...

  7. JDBC——使用JDBC连接MySQL数据库

    在JDBC--什么是JDBC一文中我们已经介绍了JDBC的基本原理. 这篇文章我们聊聊如何使用JDBC连接MySQL数据库. 一.基本操作 首先我们需要一个数据库和一张表: CREATE DATABA ...

  8. ava基础MySQL存储过程 Java基础 JDBC连接MySQL数据库

    1.MySQL存储过程   1.1.什么是存储过程 带有逻辑的sql语句:带有流程控制语句(if  while)等等 的sql语句   1.2.存储过程的特点 1)执行效率非常快,存储过程是数据库的服 ...

  9. JDBC连接MySQL数据库代码

    ******************************************************1********************************************* ...

随机推荐

  1. 从非标准的POST数据流中提取文件

    1 接收数据流转成字符串,注意编码 byte[] recv= Request.BinaryRead(Request.TotalBytes);string sourceByte = Encoding.U ...

  2. 破解第二课 JMP法

    首先,我用录屏大师自制了一个视频,给视频加上密码.任意输入,看到报错信息“密码不对,请重新输入” 第一步 反汇编窗口右键点击“中文搜索引擎”---“智能搜索”,搜索引擎界面再次搜索“不对”,结果如下: ...

  3. 转:centos7搭建jenkins小记

    转自:https://segmentfault.com/a/1190000007086764 安装java环境 1.查看服务器版本 centos7,继续. cat /etc/redhat-releas ...

  4. mesos支持gpu代码分析以及capos支持gpu实现

    这篇文章涉及mesos如何在原生的mesoscontainerizer和docker containerizer上支持gpu的,以及如果自己实现一个mesos之上的framework capos支持g ...

  5. 用js如何获取file是否存在

    其实注意点就可以知道了. 举个例子 firebug看出这代码: <div id="SWFUpload_0_0" class="uploadify-queue-ite ...

  6. Unity UI性能优化技巧

    本文将介绍一些提升Unity UI性能的技巧.更多优化技巧,可以观看Unity工程师Ian Dundore在Unite Europe 2017的演讲<使用Unity性能提升技巧>. 1.划 ...

  7. 使用ES6新数组方法(象C# Lambda表达式一样写查询语句)

    let people = [ {id: 1, name: "a", age: 12}, {id: 2, name: "b", age: 13}, {id: 3, ...

  8. MFC控件编程进度条编写

    MFC控件编程进度条编写 一丶进度条编程需要用到的方法 进度条MFC已经帮我们封装好类了. 叫做 CProgressCtrl  进度条编程也很简单. 封装的方法也就那个那几个. GetPos()  获 ...

  9. Go内置函数cap

    func cap(v Type) int 返回指定类型的容量,根据不同类型,返回意义不同. 数组: 元素个数 (和len(v)一样). 数组指针: *v的元素个数 (和len(v)一样). Slice ...

  10. Zookeeper系列目录

    1.zookeeper安装和参数配置 2.zookeeper的适用场景 3.zookeeper客户端的实现以及使用--watcher机制 session机制 重连恢复机制 异步io