mysql学习笔记(六):JDBC详解

一、快速入门

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);
		}


ResultSet既然用于封装执行结果的,所以该对象提供的都是用于获取数据的get方法:
获取任意类型的数据
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);
		}
	}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值