一、快速入门
1.概念
数据库驱动:
数据库厂商为了方便开发人员从程序中操作数据库而提供的一套jar包,通过导入这个jar包就可以调用其中的方法操作数据库,这样的jar包就叫做数据库驱动
JDBC驱动:
sun定义的一套标准,本质上是一大堆的操作数据库的接口,所有数据库厂商为java设计的数据库驱动都实现过这套接口,这样一来同一了不同数据库驱动的方法,开发人员只需要学习JDBC就会使用任意数据库驱动了
如下图:
2.创建数据库数据和导入数据库驱动jar包
创建数据库
create table user(
id int primary key auto_increment,
name varchar(40),
password varchar(40),
email varchar(60),
birthday date
)character set utf8 collate utf8_general_ci;
insert into user(name,password,email,birthday) values('zs','123456','zs@sina.com','1980-12-04');
insert into user(name,password,email,birthday) values('lisi','123456','lisi@sina.com','1981-12-04');
insert into user(name,password,email,birthday) values('wangwu','123456','wangwu@sina.com','1979-12-04');
这时候就可以看到创建的数据了
导入数据库驱动
JDBC驱动不用导入,因为java自带的,但是只有JDBC驱动是不行的,还需要导入导入数据库驱动jar包
先建立一个文件lib,然后将数据库驱动复制到文件内
复制到lib文件中
3.快速入门
案例:要遍历上面数据库的名字
JDBCDemo1.java
package com.java.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.mysql.jdbc.Driver;
public class JDBCDemo1 {
public static void main(String[] agrs) throws SQLException{
//1.注册数据库驱动
DriverManager.registerDriver(new Driver());
//2.获取数据库连接
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/day10", "root", "");
//3.获取数据库传输器对象
Statement stat=conn.createStatement();
//4.利用传输器传输sql语句到数据库中执行
ResultSet rs=stat.executeQuery("select * from user");
//5.遍历结果集获取查询结果
while(rs.next()){
String name = rs.getString("name");
System.out.println(name);
}
//6.关闭资源
rs.close();
stat.close();
conn.close();
}
}
运行可以输出:
zs
lisi
wangwu
二、JDBC细节
我们一一分析上面的代码:
//1.注册数据库驱动
DriverManager.registerDriver(new Driver());
上面有两个问题:
(1)由于mysql在Driver类的实现中自己注册了一次,而我们又注册了一次,于是会导致MySql驱动被注册两次
(2)创建MySql的Driver对象时,导致了程序和具体的Mysql驱动绑死在了一起,在切换数据库时需要改动java代码
第一个问题看Driver类的原代码得出来的,我们先导入Driver类的源码
而第二个问题,则在这里出现的状况?
如何解决?
可以用Class.forName("com.mysql.jdbc.Driver");方式解决
Class.forName()就是如果路径的文件已经加载了,那么就不会重复的加载
改动后变成如下的了:
package com.java.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.mysql.jdbc.Driver;
public class JDBCDemo1 {
public static void main(String[] agrs) throws SQLException, ClassNotFoundException{
//1.注册数据库驱动
//DriverManager.registerDriver(new Driver());
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/day10", "root", "");
//3.获取数据库传输器对象
Statement stat=conn.createStatement();
//4.利用传输器传输sql语句到数据库中执行
ResultSet rs=stat.executeQuery("select * from user");
//5.遍历结果集获取查询结果
while(rs.next()){
String name = rs.getString("name");
System.out.println(name);
}
//6.关闭资源
rs.close();
stat.close();
conn.close();
}
}
第二个代码:
//2.获取数据库连接
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/day10", "root", "");
可参看如下:
这跟http协议有点类似
那么上面的参数和参数值可以是哪些?这也是mysql已经定义好的了,我们可以打开mysql文档看一下
所以上面的用户名和密码也可以用参数的形式改变:
"jdbc:mysql:/3306//day10?user=root&password=root"
另外Connection类也是很重要的类,它常见的方法有下面的几点:
createStatement():创建向数据库发送sql的statement对象。
prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。
prepareCall(sql):创建执行存储过程的callableStatement对象。
setAutoCommit(boolean autoCommit):设置事务是否自动提交。
commit() :在链接上提交事务。
rollback() :在此链接上回滚事务。
第三个代码:
//3.获取数据库传输器对象
Statement stat=conn.createStatement();
它除了有executeQuery(String sql) :用于向数据发送查询语句。
还有:
executeUpdate(String sql):用于向数据库发送insert、update或delete语句
这是用于增删改
那么除了,这个还有两者的结合:
execute(String sql):用于向数据库发送任意sql语句
这跟上面的有什么不一样?
我们先看executeQuery和executeUpdate的不一样
返回的类型不一样:
executeQuery返回 Resultset(结果集)
executeUpdate则返回改动数据的个数,如果没有就返回0
execute里面的sql语句如果是查询的话,则返回true,如果不是查询或者没有结果就返回false
另外它还有方法
addBatch(String sql) :把多条sql语句放到一个批处理中。
executeBatch():向数据库发送一批sql语句执行。
//4.利用传输器传输sql语句到数据库中执行
ResultSet rs=stat.executeQuery("select * from user");
//5.遍历结果集获取查询结果
while(rs.next()){
String name = rs.getString("name");
System.out.println(name);
}
获取任意类型的数据
getObject(int index)
getObject(string columnName)
获取指定类型的数据,例如:
getString(int index)
getString(String columnName)
提问:数据库中列的类型是varchar,获取该列的数据调用什么方法?Int类型呢?bigInt类型呢?Boolean类型?
上面的提问是有相应的类型的
ResultSet还有下面的方法:
next():移动到下一行
Previous():移动到前一行
absolute(int row):移动到指定行
beforeFirst():移动resultSet的最前面。
afterLast() :移动到resultSet的最后面。
比如下面的案例:
表user是这样的:
package com.java.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.mysql.jdbc.Driver;
public class JDBCDemo1 {
public static void main(String[] agrs) throws SQLException, ClassNotFoundException{
//1.注册数据库驱动
//DriverManager.registerDriver(new Driver());
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接
Connection conn=DriverManager.getConnection(<span style="font-family: Arial, Helvetica, sans-serif;">"jdbc:mysql://localhost:3306/day10", "root", ""</span>
);
//3.获取数据库传输器对象
Statement stat=conn.createStatement();
//4.利用传输器传输sql语句到数据库中执行
ResultSet rs=stat.executeQuery("select * from user");
//5.遍历结果集获取查询结果
// while(rs.next()){
// String name = rs.getString("name");
// System.out.println(name);
// }
rs.next();
rs.next();
String name = rs.getString("name");
System.out.println(name);
//6.关闭资源
rs.close();
stat.close();
conn.close();
}
}
上面执行的结果是:
lisi
第六个代码:
//6.关闭资源
rs.close();
stat.close();
conn.close();
上面的代码是不严谨的,因为当rs出异常的时候,程序停止,那么stat 和conn就无法正常关闭了,所以要用finally
下面是改造后的代码:
package com.java.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCDemo1 {
public static void main(String[] args){
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try{
//1.注册数据库驱动
//--由于mysql在Driver类的实现中自己注册了一次,而我们又注册了一次,于是会导致MySql驱动被注册两次
//--创建MySql的Driver对象时,导致了程序和具体的Mysql驱动绑死在了一起,在切换数据库时需要改动java代码
//DriverManager.registerDriver(new Driver());
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day10", "root", "");
//3.获取传输器对象
stat = conn.createStatement();
//4.利用传输器传输sql语句到数据库中执行,获取结果集对象
rs = stat.executeQuery("select * from user");
//5.遍历结果集获取查询结果
while(rs.next()){
String name = rs.getString("name");
System.out.println(name);
}
}catch (Exception e) {
e.printStackTrace();
}finally{
//6.关闭资源
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs = null;
}
}
if(stat!=null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
stat = null;
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn = null;
}
}
}
}
}
三、JDBC增删改查
上面已经初步的了解了相关的知识点,下面就在实现它的增删改查
增加的功能:
</pre><p><pre name="code" class="java">public void add(){
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
//1.注册数据库驱动
try {
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day10", "root", "");
//3.获取传输器对象
stat = conn.createStatement();
//4.利用传输器传输sql语句到数据库中执行,添加对象
int count = stat.executeUpdate("insert into user values (null,'zhaoliu','123456','zhaoliu@qq.com','1999-09-09')");
// 5.处理结果
if (count > 0) {
System.out.println("执行成功!影响到的行数为" + count);
} else {
System.out.println("执行失败!!");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//6.关闭资源
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs = null;
}
}
if(stat!=null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
stat = null;
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn = null;
}
}
}
}
执行成功!影响到的行数为1
修改的功能:
我们发现修改的功能和增加的功能代码有很多一样的,所以我们可以将一些功能变为工具类:
将获得数据库连接和异常处理变为工具类
先建立工具类:
package com.itheima.util;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JDBCUtils {
private static Properties prop = null;
private JDBCUtils() {
}
static{
try{
prop = new Properties();
prop.load(new FileReader(JDBCUtils.class.getClassLoader().getResource("config.properties").getPath()));
}catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 获取连接
* @throws ClassNotFoundException
* @throws SQLException
*/
public static Connection getConn() throws ClassNotFoundException, SQLException{
// 1.注册数据库驱动
Class.forName(prop.getProperty("driver"));
// 2.获取连接
return DriverManager.getConnection(prop.getProperty("url"), prop.getProperty("user"), prop.getProperty("password"));
}
/**
* 关闭连接
*/
public static void close(ResultSet rs, Statement stat,Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs = null;
}
}
if(stat!=null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
stat = null;
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn = null;
}
}
}
}
上面的是有用到了配置文件:
配置文件的内容是这样的:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day10
user=root
password=
这时候修改功能的java就是这样:
@Test
public void update() {
Connection conn = null;
Statement stat = null;
try{
conn = JDBCUtils.getConn();
stat = conn.createStatement();
stat.executeUpdate("update user set password=999 where name='zhaoliu'");
}catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.close(null, stat, conn);
}
}
查询的功能:
@Test
public void find(){
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try{
conn = JDBCUtils.getConn();
stat = conn.createStatement();
rs = stat.executeQuery("select * from user where name='zhaoliu'");
while(rs.next()){
String name = rs.getString("name");
String password = rs.getString("password");
System.out.println(name+":"+password);
}
}catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.close(rs, stat, conn);
}
}
删除的功能:
public void delete(){
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try{
conn = JDBCUtils.getConn();
stat = conn.createStatement();
stat.executeUpdate("delete from user where name='zhaoliu'");
}catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.close(rs, stat, conn);
}
}