认识 JDBC

JDBC (Java DataBase Connectivity) 是 Java 数据库连接技术的简称,用于连接常用数据库。

Sun 公司提供了 JDBC API ,供程序员调用接口和类,集成在 java.sqljavax.sql 包中。

Sun 公司还提供了 DriverManager 类用来管理各种不同的JDBC驱动。

不同数据库厂商提供各自的JDBC驱动,所以我们想要连接数据库除了要了解 JDBC API 还需要下载各数据库厂商的驱动 jar 包。

JDBC API

JDBC API主要用于与数据库建立连接、执行SQL语句、处理结果,其中核心类和接口如下:

  • DriverManager:依据数据库的不同,管理JDBC驱动
  • Connection:负责连接数据库并担任传送数据的任务
  • Statement:由 Connection 产生、负责执行SQL语句
  • ResultSet:负责保存 Statement 执行后所产生的查询结果

JDBC 编码模板

1、与数据库建立连接并获取连接

Connection connection=DriverManager.getConnection(URL,数据库用户名,密码);

2、发送SQL语句,得到执行结果

Statement stmt=connection.createStatement();
ResultSet rs=stmt.executeQuery(SQL语句);

3、处理返回结果

while(rs.next()){
int a=rs.getInt("a");
String b=rs.getString("b");
Date d=rs.getDate("d");
……
}

4、释放资源

rs.close();
stmt.close();
connection.close();

使用 JDBC 连接到 MySQL 数据库

本例适合已经会使用 MySQL 数据库的同学,首先我们下载 JDBC 的驱动 jar 包。这个网址提供了 MySQL 各种语言连接数据库的驱动 https://www.mysql.com/products/connector/,MySQL Connector / J 8.0与从MySQL 5.5开始的所有MySQL版本兼容。

8.0下载地址

下载完成后解压,后将jar添加依赖到项目中。

连接到MySQL数据库

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException; public class DemoConnectMySQL {
public static void main(String[] args) {
//连接MySQL的URL
String url="jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
//MySQL数据库用户名
String user="root";
//MySQL数据库的密码
String password="1234";
Connection connection=null;
try {
connection=DriverManager.getConnection(url, user, password);
System.out.println("连接成功");
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
connection.close();
System.out.println("连接关闭");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

url指定数据库的连接字符串,格式为:

jdbc:数据库://ip或域名:端口号?参数&参数……

这里的参数 useUnicode=true 使用Unicode字符,characterEncoding=utf8 设置编码防止中文乱码,serverTimezone=UTC 设置时区,useSSL=false 不使用SSL

jdbc4.0不需要加载驱动

PreparedStatement 增删改

PreparedStatement 继承了 Statement 接口,表示预编译的 SQL 语句对象,SQL 语句被预编译并存储在 PreparedStatement 对象中,可以使用此对象多次高效地执行该语句。(还避免了 SQL 注入的隐患)

先准备好数据库 books

表 book

字段 类型 属性
id 整数 主键,自增
bName 字符串 非空
price 小数 非空

脚本也准备好了

#创建数据库
CREATE DATABASE books;
USE books;
#创建表
CREATE TABLE book (
id INT primary key auto_increment,
bName VARCHAR ( 255 ) NOT NULL,
price FLOAT NOT NULL
);

PreparedStatement添加数据

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException; public class TestInsert { public static void main(String[] args) {
Connection connection=null;
PreparedStatement pstmt=null;
String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
String user="root";
String password="1234";
try {
connection=DriverManager.getConnection(url,user,password);
//sql语句
String sql="insert into book(bName,price) values (?,?)";
pstmt=connection.prepareStatement(sql);
//传入参数
pstmt.setString(1, "《java入门到改行》");
pstmt.setFloat(2, 11.11f);
int result=pstmt.executeUpdate();
System.out.println("受影响行数:"+result);
} catch (SQLException e) {
e.printStackTrace();
}finally {
if (pstmt!=null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}

说明:

1、连接字符串要修改数据库名字为 books

String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";

2、插入数据库的数据不能拼接而是要用 ? 代替

String sql="insert into book(bName,price) values (?,?)";

3、? 代替的参数要通过 set类型(位置,值) 传入

pstmt.setString(1, "《java入门到改行》");
pstmt.setFloat(2, 11.11f);

pstmt.setXxx()的位置从 1 开始!

4、增删改的SQL语句都使用这个方法,返回受影响行数

int result=pstmt.executeUpdate();

删除数据

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException; public class TestDelete { public static void main(String[] args) {
Connection connection=null;
PreparedStatement pstmt=null;
String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
String user="root";
String password="1234";
try {
connection=DriverManager.getConnection(url,user,password);
//sql语句
String sql="delete from book where id=?";
pstmt=connection.prepareStatement(sql);
//传入参数 要删除id
pstmt.setInt(1, 1);
int result=pstmt.executeUpdate();
System.out.println("受影响行数:"+result);
} catch (SQLException e) {
e.printStackTrace();
}finally {
if (pstmt!=null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}

修改数据

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException; public class TestUpdate { public static void main(String[] args) {
Connection connection=null;
PreparedStatement pstmt=null;
String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
String user="root";
String password="1234";
try {
connection=DriverManager.getConnection(url,user,password);
//sql语句
String sql="update book set bName=?,price=? where id=?";
pstmt=connection.prepareStatement(sql);
//传入参数 要删除id
pstmt.setString(1, "《MySQL从删库到跑路》");
pstmt.setFloat(2, 16.66f);
pstmt.setInt(3, 2);
int result=pstmt.executeUpdate();
System.out.println("受影响行数:"+result);
} catch (SQLException e) {
e.printStackTrace();
}finally {
if (pstmt!=null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}

增、删、改操作的写法都一样,都调用 executeUpdate() 方法返回一个受影响行数,唯一不同的 SQL语句。

PreparedStatement 查询数据

查询数据需要用到 ResultSet 类保存返回的结果集,我们获取数据要操作 ResultSet 获取。

ResultSet 常用方法

方法名 说明
boolean next() 将游标从当前位置向下移动一行
void close() 关闭 ResultSet 对象
int getInt(int colIndex) 以int形式获取结果集当前行指定列号值
int getInt(String colLabel) 以int形式获取结果集当前行指定列名值
float getFloat(String colLabel) 以float形式获取结果集当前行指定列名值
String getString(String colLabel) 以 String 形式获取结果集当前行指定列名值
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; public class TestSelect { public static void main(String[] args) {
Connection connection=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
String user="root";
String password="1234";
try {
connection=DriverManager.getConnection(url,user,password);
//sql语句
String sql="select bName,price,id from book where id=?";
pstmt=connection.prepareStatement(sql);
//传入查询条件
pstmt.setInt(1, 2);
rs=pstmt.executeQuery();
while(rs.next()) {
//通过列名获取列的值
int id=rs.getInt("id");
//通过位置获取列的值
String bName=rs.getString(1);
float price=rs.getFloat("price");
System.out.println(id+" "+bName+" "+price);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (pstmt!=null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}

关闭对象时注意关闭的顺序,后使用的先关闭:rs.close()->pstmt.close()->connection.close()

ResultSet 对象存在一个光标,光标所指行为当前行。想要获取列的数据需要先指向一行,所以要先指定 next() 方法用于指向一行,如果没有数据next()方法返回false,有数据返回true。

使用 getXxx() 方法获取列的数据时建议写列名,这样好识别

Java入门系列-26-JDBC的更多相关文章

  1. java io系列26之 RandomAccessFile

    本文主要介绍 RandomAccessFile. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_26.html 更多内容请参考:java io系列0 ...

  2. Java入门系列-19-泛型集合

    集合 如何存储每天的新闻信息?每天的新闻总数是不固定的,太少浪费空间,太多空间不足. 如果并不知道程序运行时会需要多少对象,或者需要更复杂方式存储对象,可以使用Java集合框架. Java 集合框架提 ...

  3. Java入门系列:实例讲解ArrayList用法

    本文通过实例讲解Java中如何使用ArrayList类. Java.util.ArrayList类是一个动态数组类型,也就是说,ArrayList对象既有数组的特征,也有链表的特征.可以随时从链表中添 ...

  4. Java Web系列:JDBC 基础

    ADO.NET在Java中的对应技术是JDBC,企业库DataAccessApplicationBlock模块在Java中的对应是spring-jdbc模块,EntityFramework在Java中 ...

  5. Java入门系列之hashCode和equals(十二)

    前言 前面两节内容我们详细讲解了Hashtable算法和源码分析,针对散列函数始终逃脱不掉hashCode的计算,本节我们将详细分析hashCode和equals,同时您将会看到本节内容是从<E ...

  6. Java入门系列之字符串创建方式、判断相等(一)

    前言 陆续从0开始学习Java出于多掌握一门语言以后的路也会更宽,.NET和Java兼顾,虽然路还很艰难,但事在人为.由于Java和C#语法相似,所以关于一些很基础的内容不会再重头讲,Java系列中所 ...

  7. Java入门系列之重写

    前言 关于所有Java系列文章面向有一定基础的童鞋,所写每一篇希望有一定含金量,有些内容可能会从Java整个语法全局考虑穿插后续要讲解的内容以成系统,若不理解,请看完后再学习.上一节我们讲解完了fin ...

  8. Java入门系列 泛型

    前言 <Java编程思想>第四版足足用了75页来讲泛型——厚厚的一沓内容,很容易让人头大——但其实根本不用这么多,只需要一句话:我是一个泛型队列,狗可以站进来,猫也可以站进来,但最好不要既 ...

  9. Java入门系列 Java 中的四种引用

    Why java内存管理分为内存分配和内存回收,都不需要程序员负责,垃圾回收的机制主要是看对象是否有引用指向该对象. java对象的引用包括强引用,软引用,弱引用,虚引用 Java中提供这四种引用类型 ...

随机推荐

  1. [转载].NET Web开发技术(补充)

    大家在工作应该养成善于总结的习惯,总结你所学习.使用的技术,总结你所工作事项的比较好的地方,善于总结不断的沉淀优化自己.适时停下来总结下过去走过的路,才能让我们的未来走的更坚定.文章转自JamesLi ...

  2. 关于人脸识别引擎FaceRecognitionDotNet的实例

    根据我上篇文章的分享,我提到了FaceRecognitionDotNet,它是python语言开发的一个项目face_recognition移植.结果真是有喜有忧,喜的是很多去关注了,进行了下载,我看 ...

  3. 解除SVN的控制

    win10操作就是把文件夹隐藏的对勾勾上 然后就可以看见一个.SVN的文件夹 把他直接删除即可 然后刷新 自己亲测的 win10 家庭版

  4. c# 类的反射实例 (GetType().Invoke().GetMethod().CreateInstance())

    原文:http://www.cnblogs.com/chenwei19/archive/2009/02/04/1384034.html Class1和Form 窗体在同一个命名空间 using Sys ...

  5. NVIDIA GTC照片

    这次的NVIDIA GPU Technology Conference 2014在美国San Jose(就是俗称的硅谷了)举办. 去美国的飞机上10个小时反正是睡不着,电影还是挺好看的. 美联航的早餐 ...

  6. QTP如何准确识别Dialog中的对象

    QTP脚本中有一个点击网页弹出框确定按钮的操作,实际运行时发现存在问题:调试过程,可正常识别并点击:但批量运行时不能识别并点击的概率接近100%. 修改WinButton的其中一个对象属性后,该问题解 ...

  7. 逃生(反向topo)

    逃生 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status De ...

  8. 8,Phaser__并发且多阶段任务

    使用场景 考选武状元 10 个 武生 参加考试 ,第一个关 靠耐力, 坚持最久的5个人进入第二关, 第二关考 力气,力气最大的 3个人进入第二关,第三关考兵法,兵法最好的当选武状元

  9. shell的算术运算

    变量的数值计算方法大致有双括号 (()), expr,  bc, $[ ] 例子1 注意:2**3表示2的3次方,a++表示先输出a自身的值,然后进行++的运算: --a表示先进行--的运算,然后再输 ...

  10. python3入门之print,import,input介绍

    本节主要介绍print,import和input,t函数,包括他们在python2.7和python3 的区别以及用法.下面附有之前的文章: ​ python3的print函数的变化 python3之 ...