JDBC个人学习总结

JDBC个人学习总结

  • JDBC是什么
  • JDBC API
  • JDBC访问数据库的步骤
  • 各数据库对JDBC提供的接口
  • 实例
    • 加载具体的驱动类
    • 建立连接
    • 关闭连接
    • Statement对象
    • PreparedStatement对象
    • Statement和PreparedStatement
    • CallableStatement对象
    • 处理结果集
    • 总结
    • 整合
  • 扩展例子
    • 处理稍大型的数据
      • JDBC存储及下载大文本数据(CLOB)
        • 存储小说到数据库
        • 从数据库取小说
      • JDBC存储及下载二进制文件(BLOB)
        • 存储图片到数据库
        • 从数据库取图片
      • JDBC存储文件路径
        • 向数据库中存储地址
        • 从数据库中取文件地址
    • JDBC执行SQL语句
      • JDBC创建数据库
      • JDBC删除数据库
    • 创建数据库表
    • 删除数据库表

JDBC是什么

JDBC:JAVA Database Connectivity,是用于在Java编程语言和广泛的数据库之间独立于数据库的连接的标准Java API,是JAVA用来与各种数据库连接的。

JDBC库包含用于下面提到的每个任务的API,这些API通常与数据库使用相关联:

  • 与数据库建立连接。
  • 创建SQL语句。
  • 在数据库中执行SQL操作。
  • 查看和修改结果记录。

总的来说,JDBC可以为多种关系型数据库DMS提供统一的访问方式,即用JAVA来操作数据库,为Java程序员操作数据提供了方法。
JDBC API使用驱动程序管理器和特定于数据库的驱动程序来提供与不同的数据库之间的透明连接。如图:
JDBC个人学习总结_第1张图片
其中java.sql和javax.sql是JDBC 4.0的主要软件包,一般我们在开发过程中主要用的java.sql,大家如果想避免导错包的话,可以直接在自己的Java代码上先直接加上import java.sql.*(后面会提到)。

JDBC API

JDBC API支持用于数据库访问的两层和三层处理模型,但是通常,JDBC体系结构由两层组成:

  • JDBC API:这提供了应用程序到JDBC管理器的连接。
  • JDBC Driver API:它支持JDBC管理器到驱动程序的连接。

JDBC驱动程序管理器确保使用正确的驱动程序来访问每个数据源。驱动程序管理器能够支持连接到多个异构数据库的多个并发驱动程序。

总结:
JDBC个人学习总结_第2张图片

  1. JDBC API 的主要功能是提供工作操作访问接口:Connection、Statement(PreparedStatement)、CallableStatement、ResultSet。
  2. JDBC DriverManager:管理不同的数据库驱动
  3. 各种数据库驱动:相应的数据库厂商提供的(第三方公司提供的JAR包),连接或直接操作数据库
  4. 具体通过以下的类/接口实现:
    • DriverManager:管理JDBC驱动
    • Connection:与数据库建立连接(连接字符串加用户名加密码)
    • Statement(子接口PreparedStatement):实现增删改查
    • CallableStatement:调用数据库中的存储过程/存储函数
    • Result:返回的结果集

JDBC访问数据库的步骤

  1. 导入驱动包,加载具体的驱动类
  2. 与数据库建立连接
  3. 发送sql语句,执行
  4. 处理结果集(对于增删改来说,返回的是多少行被修改(int),对于查来说,无疑是返回查询结果(ResultSet))

各数据库对JDBC提供的接口

下面表中的端口号都是默认端口号:

数据库 驱动的jar包名 驱动类 连接字符串
Oracle ojdbc-x.jar oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@主机名:1521:数据库名称
MySQL8.0以前版本 mysql-connector-java-x.jar com.mysql.jdbc.Driver jdbc:mysql://主机名:3306/数据库名称
MySQL8.0以后版本 mysql-connector-java-x.jar com.mysql.cj.jdbc.Driver jdbc:mysql://localhost:3306/数据库名称?serverTimezone=格林威治时间
sqlserver sqljdbc.-x.jar com.microsoft.sqlserver.jdbc.SQLServerDriver jdbc:microsoft:sqlserver:localhost:1433;databasename=数据库名称

小技巧:大多数的jar包可以在百度搜索,在百度搜索mysql-connector-java.jar mvn(在maven库中查找),之后选择图中的第一个https://mvnrepository.com/artifact/mysql/mysql-connector-java,可以直接下载,也可以在自己下载的数据库的安装目录找:
JDBC个人学习总结_第3张图片

实例

加载具体的驱动类

try {
	//对应的数据库使用对应的驱动类,如Oracle:
   Class.forName("oracle.jdbc.driver.OracleDriver");
} catch(ClassNotFoundException e) {
   . . .
}

建立连接

//URL为连接字符串:jdbc:oracle:thin:@主机名:1521:数据库名称
String URL = "jdbc:oracle:thin:@主机名:1521:数据库名称";
String USER = "username";
String PASS = "password"
//记得3个参数:连接字符串,用户名,密码
Connection conn = DriverManager.getConnection(URL, USER, PASS);

关闭连接

在JDBC程序的末尾,显式地需要关闭与数据库的所有连接以结束每个数据库会话。但是,如果忘记了,Java的垃圾收集器在清理陈旧对象时将关闭连接。

依靠垃圾回收,尤其是在数据库编程中,是非常糟糕的编程实践,所以我们应该养成始终使用与连接对象关联的close()方法关闭连接的习惯。

为了确保关闭连接,我们可以在代码中提供一个“finally”块。

try{
	if(conn!=null)conn.close();
} catch (SQLException e) {
	e.printStackTrace();
}

Statement对象

Statement stmt = null;
try {
   stmt = conn.createStatement();
   . . .
} catch (SQLException e) {
   . . .
} finally {
	//和connection一样,我们需要将statement关闭
	try{
		if(stmt!=null)stmt.close();
	} catch (SQLException e) {
		e.printStackTrace();
	} 
}

一旦创建了Statement对象,就可以使用其三个执行方法之一来执行SQL语句。

  • boolean execute(String SQL):如果可以检索到ResultSet对象,则返回布尔值true。否则,它返回false。当需要使用真正的动态SQL时,请使用此方法执行SQL DDL语句。
  • int executeUpdate(String SQL):返回受SQL语句执行影响的行数。使用此方法可以执行您希望受影响的行数的SQL语句,例如,INSERT,UPDATE或DELETE语句。
  • ResultSet executeQuery(String SQL):返回ResultSet对象。当您希望获得结果集时,请使用此方法,就像使用SELECT语句一样。

PreparedStatement对象

PreparedStatement的接口扩展了Statement接口,可以动态提供参数:

PreparedStatement pstm = null;
try {
   String SQL = "Update 数据库表 SET age = ? WHERE id = ?";
   pstm = conn.prepareStatement(SQL);
   . . .
} catch (SQLException e) {
   . . .
} finally {
	//父类statement都要关闭,何况子类
   try{
		if(pstm!=null)pstm.close();
	} catch (SQLException e) {
		e.printStackTrace();
	}	
}
  1. JDBC中的参数都由?占位符表示,称为参数标记。在执行SQL语句之前,必须为每个参数提供值。

  2. setXXX()方法绑定值的参数,其中XXX代表要绑定到输入参数的值的Java数据类型,分别由setInt()、setString()、setDate()组成。如果忘记提供值,则将收到一个SQLException。

  3. 每个参数标记都由其顺序位置引用。第一个标记代表位置1,第二个代表位置2,依此类推,如setInt(1,20);或setString(2,“20”);。此方法不同于Java数组从0开始的索引。

  4. 与数据库交互的所有Statement对象的方法(a)execute(),(b)executeQuery()和(c)executeUpdate(),PreparedStatement对象也可以使用。但是,方法被修改为使用可以输入参数的SQL语句。

Statement和PreparedStatement

Statement和PreparedStatement有以下一些差别:

  1. PreparedStatement执行的SQL语句,处理的数据可以用占位符?替换,而Statement不可以;
  2. PreparedStatement调用setInt()、setString()、setDate()方法替换占位符;
  3. PreparedStatement对执行的SQL语句进行预编译处理,之后再交给数据库执行SQL操作,而Statement没有这一过程。

推荐使用PreparedStatement,原因如下:

  • 占位符的使用使得编码更加简便,同时避免了字符串的拼接:
    对于日常功能的开发,我们会出现如下的情况:
String name="zs";
int age=23;
Connection conn=……
//Statement stmt
Statement stmt=conn.createStatement();
String SQL="insert into emp(name,age) values('"+name+"',"+age+")";
stmt.executeUpdat(SQL);
//PreparedStatement pstm
String SQL="insert into emp(name,age) values(?,?)";
PreparedStatement pstm=conn.prepareStatement(SQL);//预编译SQL
pstm.setString(1, name);
pstm.setInt(2, age);
  • 提高性能(由上面的例子可知,因为有预编译操作,预编译只需要执行一次)
    如需要重复增加1000条数据:
Connection conn=……
//Statement stmt
Statement stmt=conn.createStatement();
String SQL = "insert into student(name,age) values ('"+name+"',"+age+")";
for(1000)
	stmt.executeUpdate(SQL);
//PreparedStatement pstm
String SQL="insert into student(name,age) values (?,?)";
PreparedStatement pstm=conn.prepareStatement(SQL);//预编译
pstm.setString(1,name);
pstm.setInt(2,age);
for(1000)
	pstm.executeUpdate();
  • 安全(可以有效防止SQL注入)
    SQL注入:将客户输入的内容和开发人员的SQL语句混为一体
    stmt:存在被SQL注入的风险
    (例如输入用户名:任意值’ or 1=1 --密码:任意值)
    分析:
    select count() from login where name=‘任意值’ or 1=1 –’ and pwd =‘任意值’;拼接之后,-- 后面的语句被注释了,这个SQL语句就变成select count() from login where name=’*任意值’ or 1=1;如果这是一个登录的SQL语句,返回的结果就是1,用户就登录成功了。
    但是如果使用PreparedStatement,则可以有效的防止SQL注入,因为占位符并不是把内容直接拼接的。

CallableStatement对象

正如Connection对象创建Statement和PreparedStatement对象一样,它也创建CallableStatement对象(Connection.prepareCall(SQL);),该对象将用于执行对数据库存储过程的调用。
参数格式:

  • 存储过程(无返回值return,用out参数代替):{call 存储过程名(参数列表)}
  • 存储函数(有返回值return ):{? = call 存储函数名(参数列表)}
    存在三种类型的参数:IN,OUT和INOUT。PreparedStatement对象仅使用IN参数。CallableStatement对象可以使用所有这三个对象。
    |参数|作用|
    |–|--|
    |IN|创建SQL语句时其值未知的参数。您可以使用setXXX()方法将值绑定到IN参数。|
    OUT|一个参数,其值由返回的SQL语句提供。您可以使用getXXX()方法从OUT参数中检索值。
    INOUT|提供输入和输出值的参数。您可以使用setXXX()方法绑定变量,并使用getXXX()方法检索值。
    我们看一下例子,使用的是Oracle数据库:
--存储过程的Sql语句
create or replace procedure addTwoNum(num1 in number,num2 in number,result out number) --1+2=3
as
begin
result:=num1+num2;
end;
/

--存储函数的Sql语句
create or replace function addTwoNumfunction(num1 in number,num2 in number)  --1+2
return number
as
result number;
begin
result:=num1+num2;
return result;
end;
/
//java代码
import java.sql.*;
public class CallableStatementTest{
	// JDBC 驱动和数据库连接字符串
	static final String JDBC_DRIVER = "oracle.jdbc.OracleDriver";
	static final String DB_URL = "jdbc:oracle:thin:@主机名:1521:EMP";

	// 数据库用户名密码
	static final String USER = "username";
	static final String PASS = "password";

	// Connection、CallableStatement
	static Connection conn = null;
	static CallableStatement cstm = null;
	//存储过程
	public static void storeProcedure(){
		//导入驱动,加载具体的驱动类
		Class.forName(JDBC_DRIVER);
		//与数据库建立连接
		conn=DriverManager.getConnection(DB_URL,USER ,PASS );
		//发送SQL语句
		cstm=conn.prepareCall("{call addTwoNum(?,?,?)}");
		cstm.setInt(1,20);
		cstm.setInt(2,40);
		cstm.registerOutParameter(3,Types.INTEGER);
		cstm.execute();//num1+num2,execute()之前处理输入参数,之后处理输出参数
		//设置输出参数的类型
		int result=cstm.getInt(3);
		System.out.println(result);
	}
	//存储函数
	public static storedFunction(){
		//导入驱动,加载具体的驱动类
		Class.forName(JDBC_DRIVER);
		//与数据库建立连接
		conn=DriverManager.getConnection(DB_URL,USER ,PASS );
		//发送SQL语句
		cstm=conn.prepareCall("{?= call addTwoNumfunction(?,?)}");
		cstm.setInt(2,20);
		cstm.setInt(3,40);
		cstm.registerOutParameter(1,Types.INTEGER);
		cstm.execute();//num1+num2,execute()之前处理输入参数,之后处理输出参数
		//设置输出参数的类型
		int result=cstm.getInt(1);
		System.out.println(result);
	}
}

注意:如果是通过sqlplus访问数据库,只需要开启:OracleServiceSID,通过其他程序访问数据(sqldevelop、navicate、JDBC),需要开启:OracleServiceSID、XxxListener。
JDBC调用存储过程、存储函数的步骤:

  1. 产生调用存储过程的对象:CallableStatement cstm=Connection.prepareCall(SQL);
  2. 通过setXxx()处理输入参数值:cstm.setInt(1,30);
  3. 通过registerOutParameter()处理输出的参数类型:cstm.registerOutParameter(1,Types.INTEGER);
  4. cstm.execute()执行
  5. 接收输出值(返回值)getXxx():int result=cstm.getInt(1);
  6. 在调用时,注意参数的区别,存储过程的SQL:"{call addTwoNum(?,?,?)}",存储函数的SQL:"{?= call addTwoNumfunction(?,?)}",所以,前者的返回值为cstm.registerOutParameter(3,Types.INTEGER);int result=cstm.getInt(3);后者的返回值为cstm.registerOutParameter(1,Types.INTEGER);int result=cstm.getInt(1);具体的开发情况具体分析。

处理结果集

ResultSet rs = null;
try {
   //如果返回的结果集只有一条数据
   if(rs.next()){
   		rs.getXxx(int/String);
   		rs.getXxx(int/String);
  		. . .
  	}
  	//返回多条结果集
  	while(rs.next()){
  		rs.getXxx(int/String);
  		rs.getXxx(int/String);
  		. . .
  	}
} catch (SQLException e) {
   . . .
} finally {//先打开后关闭
	try {
		if(rs != null)rs.close();
	} catch (SQLException e) {
		e.printStackTrace();
	}
}

总结

  1. DriverManager创建Connection连接对象;
  2. Connection创建操作数据库的对象:
    a. Connection创建Statement对象:createStatement();
    b. Connection创建PreparedStatement对象:prepareStatement();
    c.Connection创建CallableStatement对象:prepareCall();
  3. Statement操作数据库:
    a. 增删改executeUpdate(),返回值为int,表示有多少行受到影响;
    b. 查询 executeQuery(),返回值为ResultSet结果集,将查询获取的数据以结果集返回;
  4. ResultSet结果集:
    a. 返回的结果集默认位置指向结果集的前一行
    b. next()方法作用:把结果集的游标下移,同时判断下移之后的元素是否有数据,如果有数据,返回true,没有数据,返回false
    c. 获取结果集的数据:getInt(int/String)返回int值,getString(int/String)返回字符串,getDate(int/String)返回日期,(int/String)内可以传int参数或者字符串,如图:
    JDBC个人学习总结_第4张图片

整合

//Connection类、Statement类、PreparedStatement类、ResultSet类都是在java.sql.*下
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class Test1 {
	// JDBC 驱动和数据库连接字符串
	static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
	static final String DB_URL = "jdbc:mysql://localhost:3306/EMP";

	// 数据库用户名密码
	static final String USER = "username";
	static final String PASS = "password";

	// Connection、Statement、PreparedStatement
	static Connection conn = null;
	static Statement stmt = null;
	static PreparedStatement pstm = null;
	static ResultSet rs = null;

	// 查
	public static void query() {
		try {
			// 注册驱动
			Class.forName(JDBC_DRIVER);
			// 建立连接
			conn = DriverManager.getConnection(DB_URL, USER, PASS);
			/*Statement
			// 执行SQL语句
			String SQL = 
			"select id,name from emp where name like '%zs%'";
			stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(SQL);*/
			//PreparedStatement
			String SQL = "select id,name from emp where name like ?";
			pstm=conn.prepareStatement(SQL);//预编译
			pstm.setString(1, "%zs%");
			rs=pstm.executeQuery();
			while (rs.next()) {
				int id = rs.getInt("id");
				String name = rs.getString("name");
				System.out.println("id: " + id + ", name: " + name);
			}
		}
		// jdbc中,除了Class.forName()抛出ClassNotFoundException外,其他的抛SQLException
		catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {//先打开后关闭
			try {
				if(rs != null)//有结果集,结果集也要关闭
					rs.close();
				if (stmt != null)
					stmt.close();
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	// 增删改
	public static void insert() {
		try {
			//驱动注册
			Class.forName(JDBC_DRIVER);
			//建立连接
			conn=DriverManager.getConnection(DB_URL);
			/*Statement	
			//执行SQL语句
			String SQL="insert into emp values(1,'zs')";//增
//			String SQL="delete from emp where id=1";//删
//			String SQL="update emp set name='ls' where id=1";//改
			stmt=conn.createStatement();
			int result=stmt.executeUpdate(SQL);
			*/
			//PreparedStatement
			//执行SQL语句
			String SQL="insert into emp values(?,?)";//增
//			String SQL="delete from emp where id=?";//删
//			String SQL="update emp set name=? where id=?";//改
			pstm=conn.prepareStatement(SQL);//预编译
			pstm.setInt(1, 1);
			pstm.setString(2, "zs");
			int result=pstm.executeUpdate();
			if(result>0) System.out.println("操作成功!!!");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {//先打开后关闭
			try {
				if (pstm != null)
					pstm.close();
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

扩展例子

处理稍大型的数据

JDBC存储及下载大文本数据(CLOB)

不同数据库中对应CLOB(大文本数据)的类型如下:

  • MySQL中:CLOB对应TEXT
  • DB2/Oracle中:CLOB对应CLOB

存储小说到数据库

  1. 先通过PreparedStatement的?占位符代替小说内容
  2. 再通过PreparedStatement的setCharaterStream(int,Reader,(int/long)File.length())方法将代替小说的占位符替换为数据流,其中第三个参数是小说的文件大小,用int或long数,最好使用long。

以Oracle数据库为例,MySql数据库同理(把CLOB换成TEXT):

create table novel (id number primary key,novle clob);
public static void clob(){
	Connection conn = null;
	PreparedStatement pstm = null;
	try{
		//导入驱动,加载具体的驱动类
		Class.forName("oracle.jdbc.OracleDriver");//加载具体驱动类
		//与数据库建立连接
		conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:EMP","username","password");
		//发送SQL语句
		String SQL = "insert into novel values(?,?)";
		pstm = conn.prepareStatement(SQL);
		pstm.setInt(1,1);
		File file = new File("D:\\novel.txt");//小说文件对象
		InputStream in = new FileInputStream(file);
		Reader reader = new InputStreamReader(in,"UTF-8");//设置编码,最好与数据库编码一致
		//设置CLOB类型:setCharacterStream
		pstm.setCharacterStream(2,reader,file.length());//JDK1.2之后有第三个参数,JDK1.6之后就可以用long数据类型了,1.6之前只能用int
		int count = pstm.executeUpdate();
		//处理结果
		if(count > 0)System.out.println("保存成功!!!")
		reader.close();
		in.close();
	}catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} finally {//先打开后关闭
		try {
			if (pstm != null)
				pstm.close();
			if (conn != null)
				conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

从数据库取小说

  1. 通过Reader reader=rs.getCharacterStream(“novel”);将clob类型的数据保存到Reader对象中
  2. 将Reader通过Writer输出到指定的位置
public static void clob(){
	Connection conn = null;
	PreparedStatement pstm = null;
	ResultSet rs = null;
	try{
		//导入驱动,加载具体的驱动类
		Class.forName("oracle.jdbc.OracleDriver");//加载具体驱动类
		//与数据库建立连接
		conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:EMP","username","password");
		//发送SQL语句
		String SQL = "select novel from novel where id=?";
		pstm = conn.prepareStatement(SQL);
		pstm.setInt(1,1);
		rs = pstm.executeQuery();
		//处理结果
		if(rs.next()){
			Reader reader = rs.getCharacterStream("novel");
			Writer writer = new FileWriter("src/novel.txt");//设置文件存放位置
			char[] chs = new char[100];
			int len = -1;
			while((len = reader.read(chs))!=-1){
				writer.write(chs,0,len);
			}
			writer.close();
			reader.close();
		}
	}catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} finally {//先打开后关闭
		try {
			if (rs != null)
				rs.close();
			if (pstm != null)
				pstm.close();
			if (conn != null)
				conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

JDBC存储及下载二进制文件(BLOB)

数据库也可以存储二进制文件如图片、音乐、文档等等的文件。

存储图片到数据库

操作与上文的大文本数据差不多,区别在于设置BLOB类型的方法为setBinaryStream(),参数大致相同不加赘述,案例如下:
以Oracle数据库为例,MySql数据库同理:

create table picture(id number primary key,picture blob);
public static void blob(){
	Connection conn = null;
	PreparedStatement pstm = null;
	try{
		//导入驱动,加载具体的驱动类
		Class.forName("oracle.jdbc.OracleDriver");//加载具体驱动类
		//与数据库建立连接
		conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:EMP","username","password");
		//发送SQL语句
		String SQL = "insert into picture values(?,?)";
		pstm = conn.prepareStatement(SQL);
		pstm.setInt(1,1);
		File file = new File("D:\\picture.jpg");//图片文件对象
		InputStream in = new FileInputStream(file);
		//设置BLOB类型:setBinaryStream
		pstm.setBinaryStream(2,in,file.length());//JDK1.2之后有第三个参数,JDK1.6之后就可以用long数据类型了,1.6之前只能用int
		int count = pstm.executeUpdate();
		//处理结果
		if(count > 0)System.out.println("保存成功!!!")
		in.close();
	}catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} finally {//先打开后关闭
		try {
			if (pstm != null)
				pstm.close();
			if (conn != null)
				conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

从数据库取图片

操作也和上文大体类似:

public static void blob(){
	Connection conn = null;
	PreparedStatement pstm = null;
	ResultSet rs = null;
	try{
		//导入驱动,加载具体的驱动类
		Class.forName("oracle.jdbc.OracleDriver");//加载具体驱动类
		//与数据库建立连接
		conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:EMP","username","password");
		//发送SQL语句
		String SQL = "select picture from picture where id=?";
		pstm = conn.prepareStatement(SQL);
		pstm.setInt(1,1);
		rs = pstm.executeQuery();
		//处理结果
		if(rs.next()){
			InputStream in = rs.getBinaryStream("picture");
			OutputStream out = new FileOutputStream("src/picture.jpg");//设置文件存放位置
			byte[] byt = new byte[100];
			int len = -1;
			while((len = in.read(byt))!=-1){
				out.write(byt,0,len);
			}
			out.close();
			in.close();
		}
	}catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} finally {//先打开后关闭
		try {
			if (rs != null)
				rs.close();
			if (pstm != null)
				pstm.close();
			if (conn != null)
				conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

JDBC存储文件路径

这个在开发中使用比较多也比较方便,主要是文件太大了存储数据库也不方便,容易卡顿,所以保存文件名在数据库中,需要时再下载无疑是一种好办法:
通过JDBC存储文件路径,然后根据IO操作处理,例如:JDBC将D:\novel.txt文件以字符串的形式"D:\novel.txt"存储在数据库中,获取时只要获取该文件路径然后通过IO的方式处理即可:

向数据库中存储地址

public static void insert(){
	Connection conn = null;
	PreparedStatement pstm = null;
	try{
		//导入驱动,加载具体的驱动类
		Class.forName("oracle.jdbc.OracleDriver");//加载具体驱动类
		//与数据库建立连接
		conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:EMP","username","password");
		//发送SQL语句
		String SQL = "insert into url values(?,?)";
		pstm = conn.prepareStatement(SQL);
		pstm.setInt(1,1);
		pstm.setString(2,"D:\\novel.txt");
		int count = pstm.executeUpdate();
		//处理结果
		if(count > 0)System.out.println("保存成功!!!")
	}catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} finally {//先打开后关闭
		try {
			if (pstm != null)
				pstm.close();
			if (conn != null)
				conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

从数据库中取文件地址

我们把文件保存到D:\download\novel.txt吧:

public static void download(){
	Connection conn = null;
	PreparedStatement pstm = null;
	ResultSet rs = null;
	try{
		//导入驱动,加载具体的驱动类
		Class.forName("oracle.jdbc.OracleDriver");//加载具体驱动类
		//与数据库建立连接
		conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:EMP","username","password");
		//发送SQL语句
		String SQL = "select url from url where id=?";
		pstm = conn.prepareStatement(SQL);
		pstm.setInt(1,1);
		rs = pstm.executeQuery();
		//处理结果
		if(rs.next()){
			String url = rs.getString(url);
			File file = new File(url);//小说文件对象
			InputStream in = new FileInputStream(file);
			OutputStream out = new FileOutputStream("D:\\download\\novel.txt");//设置文件存放位置
			byte[] byt = new byte[100];
			int len = -1;
			while((len = in.read(byt))!=-1){
				out.write(byt,0,len);
			}
			out.close();
			in.close();
		}
	}catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} finally {//先打开后关闭
		try {
			if (rs != null)
				rs.close();
			if (pstm != null)
				pstm.close();
			if (conn != null)
				conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

JDBC执行SQL语句

JDBC创建数据库

import java.sql.*;

public class createDatabase {
   static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  
   static final String DB_URL = "jdbc:mysql//localhost:3306/";
   static final String USER = "username";
   static final String PASS = "password";
   
   public static void main(String[] args) {
	   Connection conn = null;
	   Statement stmt = null;
	   try{
	      //注册驱动
	      Class.forName(JDBC_DRIVER);
	
	      //建立连接
	      conn = DriverManager.getConnection(DB_URL, USER, PASS);
	
	      //执行SQL语句
	      stmt = conn.createStatement();
	      
	      String SQL = "CREATE DATABASE STUDENTS";
	      stmt.executeUpdate(SQL);
	      System.out.println("数据库创建成功");
	   }catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {//先打开后关闭
			try {
				if (stmt != null)
					stmt.close();
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

JDBC删除数据库

import java.sql.*;

public class dropDatabase{
   static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  
   static final String DB_URL = "jdbc:mysql//localhost:3306/";
   static final String USER = "username";
   static final String PASS = "password";
   
   public static void main(String[] args) {
	   Connection conn = null;
	   Statement stmt = null;
	   try{
	      //注册驱动
	      Class.forName(JDBC_DRIVER);
	
	      //建立连接
	      conn = DriverManager.getConnection(DB_URL, USER, PASS);
	
	      //执行SQL语句
	      stmt = conn.createStatement();
	      
	      String SQL = "DROP DATABASE STUDENTS";
	      stmt.executeUpdate(SQL);
	      System.out.println("数据库删除成功");
	   }catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {//先打开后关闭
			try {
				if (stmt != null)
					stmt.close();
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

创建数据库表

import java.sql.*;

public class CreateTable {
   static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  
   static final String DB_URL = "jdbc:mysql//localhost:3306/STUDENTS";
   static final String USER = "username";
   static final String PASS = "password";
   
   public static void main(String[] args) {
	   Connection conn = null;
	   Statement stmt = null;
	   try{
	      //注册驱动
	      Class.forName(JDBC_DRIVER);
	
	      //建立连接
	      conn = DriverManager.getConnection(DB_URL, USER, PASS);
	
	      //执行SQL语句
	      stmt = conn.createStatement();
	      
	      String SQL = "CREATE TABLE REGISTRATION " +
	                   "(id INTEGER not NULL, " +
	                   " name VARCHAR(255), " +
	                   " age INTEGER, " + 
	                   " PRIMARY KEY ( id ))"; 
	
	      stmt.executeUpdate(SQL);
	      System.out.println("成功创建数据库表");
	   }catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {//先打开后关闭
			try {
				if (stmt != null)
					stmt.close();
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

删除数据库表

import java.sql.*;

public class JDBCExample {
   static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  
   static final String DB_URL = "jdbc:mysql//localhost:3306/STUDENTS";
   static final String USER = "username";
   static final String PASS = "password";
   
   public static void main(String[] args) {
	   Connection conn = null;
	   Statement stmt = null;
	   try{
	      //注册驱动
	      Class.forName(JDBC_DRIVER);
	
	      //建立连接
	      conn = DriverManager.getConnection(DB_URL, USER, PASS);
	
	      //执行SQL语句
	      stmt = conn.createStatement();
      
	      String SQL = "DROP TABLE REGISTRATION ";
	 
	      stmt.executeUpdate(SQL);
	      System.out.println("成功删除数据库表");
	    }catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {//先打开后关闭
			try {
				if (stmt != null)
					stmt.close();
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

你可能感兴趣的:(JAVAweb基础,#,JAVA数据库连接)