龙空技术网

JDBC的开发

爱音乐的程序员小新人 565

前言:

眼前大家对“jdbc创建数据库mysql”可能比较关切,咱们都想要知道一些“jdbc创建数据库mysql”的相关资讯。那么小编在网上搜集了一些关于“jdbc创建数据库mysql””的相关资讯,希望看官们能喜欢,朋友们一起来了解一下吧!

1. 简介与基本代码实现

1. 简介:JDBC即java数据库连接,是sun公司用于统一数据库操作代码而制定的一套规范(提供了一套接口由数据库厂商实现,开发者只需加载相应的数据库驱动并调用这些接口即可操作数据库),简称为JDBC。

2. 基本代码实现:

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;//这个就是mysql实现的Driver接口实现类/** * @ClassName:JDBCDemo1 * @Description:JDBC基础开发过程 * 首先需要引入需要连接的对应数据库的jar包,比如mysql为mysql-connector-java */public class JDBCDemo1 {	public static void main(String[] args) {		try {						//1. 注册mysql数据库连接的驱动类			DriverManager.registerDriver(new Driver());			// 2. 获取到数据库的连接对象,指定数据库的url,用户名和密码			Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/studytest", "root", "123456");			//3. 编写SQL语句			String sql="select * from employee";			// 4. 执行SQL语句,创建能执行SQL语句的Statement对象,然后通过这个对象执行			Statement statement=con.createStatement();			// 5. 获取执行SQL语句的结果			ResultSet rs=statement.executeQuery(sql);			// 6. 遍历rs中的结果			while(rs.next()){				// 获取某个字段的数据,可以通过字段名,也可以通过查询的所有字段中目标字段在第几个位置的下标				System.out.println(rs.getInt("id"));//可以通过字段名				System.out.println(rs.getString(2));;//也就是获取第二个字段username下的数据				System.out.println(rs.getFloat("salary"));				System.out.println();				//注意获取的字段值的类型必须要对应get+数据类型()的方法			}			// 7. 释放资源			rs.close();			statement.close();			con.close();		} catch (SQLException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}	}}

3. 上面所写的基本JDBC实现代码的缺点:

java.sql.DriverManager类过于依赖某一个数据库驱动类的Driver对象在创建mysql数据库驱动类的Driver对象时,com.mysql.jdbc.Driver类内部实际上已经进行了一次数据库驱动注册,而在使用DriverManager时又进行了一次注册,所以实际上总共进行了两次数据库连接驱动注册行为。

所以,可以使用Class.forName()来改善上面两个缺点。改善代码如下

import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class JDBCDemo2 {	public static void main(String[] args) {		try {			//加载com.mysql.jdbc.Driver类,直接进行数据库驱动注册			Class.forName("com.mysql.jdbc.Driver");			// 2. 获取到数据库的连接对象,指定数据库的url,用户名和密码			Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/studytest", "root", "123456");			//3. 编写SQL语句			String sql="select * from employee";			// 4. 执行SQL语句,创建能执行SQL语句的Statement对象,然后通过这个对象执行			Statement statement=con.createStatement();			// 5. 获取执行SQL语句的结果			ResultSet rs=statement.executeQuery(sql);			// 6. 遍历rs中的结果			while(rs.next()){				// 获取某个字段的数据,可以通过字段名,也可以通过查询的所有字段中目标字段在第几个位置的下标				System.out.println(rs.getInt("id"));//可以通过字段名				System.out.println(rs.getString(2));;//也就是获取第二个字段username下的数据				System.out.println(rs.getFloat("salary"));				System.out.println();				//注意获取的字段值的类型必须要对应get+数据类型()的方法			}			// 7. 释放资源			rs.close();			statement.close();			con.close();					} catch (ClassNotFoundException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (SQLException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}	}}

4. Connection对象:代表一个与数据库之间的连接对象。其作用有

创建执行SQL语句的对象:createStatement():创建向数据库发送SQL语句的Statement对象prepareStatement(String sql):创建向数据库发送预编译SQL语句的PreparedStatement对象,预编译SQL可以防止SQL注入漏洞prepareCall(String sql):创建执行存储过程的CallableStatement 对象管理事务:void setAutoCommit(boolean autoCommit):设置事务是否自动提交void commit():在当前连接上提交事务void rollback():在当前连接上回滚事务

5. Statement对象:用于向数据库发送要执行的SQL语句,常用执行方法

ResultSet executeQuery(String sql):专门用于执行查询SQL语句,执行后会返回查询结果集ResultSet 对象int executeUpdate(String sql):专门用于执行数据更新语句,比如insert、update、delete等,执行完毕后会返回改变了几行数据boolean execute(String sql):执行任何SQL语句,如果执行的是查询语句且有查询结果则返回true,否则为falsevoid addBatch( String sql ):该方法用于将一个SQL语句添加至一批等待执行的SQL语句中,比如增删改数据的语句int[] executeBatch():批处理执行SQL语句,将一批SQL语句全部执行,返回每个SQL语句执行所改变的数据行数所组成的数组void clearBatch():清除当前这一批SQL语句

使用批处理执行大量SQL语句肯定要比单条SQL语句执行更快。

6. ResultSet 对象:用于保存查询语句返回的结果集,只有查询语句的执行才会返回该对象。其封装数据采用类似与表格的数据结构,其内部维护了一个指向表格数据行的游标,游标初始时会指向第一行数据,当执行ResultSet 对象的 next()方法时,游标便会下移一行,可以通过get+指定数据类型()的方法来获取指定字段下的当前行数据。比如

String getString(String columnLabel):获取某一个字段下的某一行数据,并且转为String类型返回int getInt(String columnLabel):获取某一个字段下的某一行数据,并且转为int类型返回Object getObject(String columnLabel):获取某一个字段下的某一行数据,并且转为Object类型返回

还有其余获取数据方法,其方法名形式都为get+指定数据类型;每个方法都有两个版本,一个版本的参数为字段名字符串,另一个则是字段在查询得到的字段集中按照书写顺序的下标。通常都使用字段名字符串来取值。

7. 资源对象的释放:ResultSet对象、Statement对象和Connection对象在使用结束后都必须立即释放,尤其是Connection对象,而资源的释放代码一般都放在finally块里,保证资源释放代码一定会执行。

import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class JDBCDemo2 {	public static void main(String[] args) {		Connection con=null;		Statement statement=null;		ResultSet rs=null;		try {			//加载com.mysql.jdbc.Driver类,直接进行数据库驱动注册			Class.forName("com.mysql.jdbc.Driver");			// 2. 获取到数据库的连接对象,指定数据库的url,用户名和密码			con=DriverManager.getConnection("jdbc:mysql://localhost:3306/studytest", "root", "123456");			//3. 编写SQL语句			String sql="select * from employee";			// 4. 执行SQL语句,创建能执行SQL语句的Statement对象,然后通过这个对象执行			statement=con.createStatement();			// 5. 获取执行SQL语句的结果			rs=statement.executeQuery(sql);			// 6. 遍历rs中的结果			while(rs.next()){				// 获取某个字段的数据,可以通过字段名,也可以通过查询的所有字段中目标字段在第几个位置的下标				System.out.println(rs.getInt("id"));//可以通过字段名				System.out.println(rs.getString(2));;//也就是获取第二个字段username下的数据				System.out.println(rs.getFloat("salary"));				System.out.println();				//注意获取的字段值的类型必须要对应get+数据类型()的方法			}					} catch (ClassNotFoundException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (SQLException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}finally {			// 7. 释放资源			try {				if(rs!=null){					rs.close();				}				rs=null;			} catch (SQLException e) {				e.printStackTrace();			}			try {				if(statement!=null){					statement.close();				}				statement=null;			} catch (SQLException e) {				e.printStackTrace();			}			try {				if(con!=null){					con.close();						}				con=null;			} catch (SQLException e) {				e.printStackTrace();			}		}	}}

8. 修改连接数据库的几个必需字符串,改为通过配置文件的方式来获取:先添加一个db.properties文件,并填写对应数据

import java.io.IOException;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 JDBCDemo3 {	public static void main(String[] args) {		Connection con=null;		Statement statement=null;		ResultSet rs=null;		try {			Properties pro=new Properties();			pro.load(JDBCDemo3.class.getClassLoader().getResourceAsStream("jdbc/db.properties"));			String driver=pro.getProperty("driver");			String user=pro.getProperty("user");			String url=pro.getProperty("url");			String password=pro.getProperty("password");						Class.forName(driver);			con=DriverManager.getConnection(url, user, password);			String sql="select * from employee";			statement=con.createStatement();			rs=statement.executeQuery(sql);			while(rs.next()){				System.out.println(rs.getInt("id"));				System.out.println(rs.getString(2));				System.out.println(rs.getFloat("salary"));				System.out.println();			}		} catch (ClassNotFoundException e) {			e.printStackTrace();		} catch (SQLException e) {			e.printStackTrace();		} catch (IOException e) {			e.printStackTrace();		}finally {			try {				if(rs!=null){					rs.close();				}			} catch (SQLException e) {				e.printStackTrace();			}			rs=null;			try {				if(statement!=null){					statement.close();				}			} catch (SQLException e) {				e.printStackTrace();			}			statement=null;			try {				if(con!=null){					con.close();						}			} catch (SQLException e) {				e.printStackTrace();			}			con=null;		}	}}

2. SQL注入漏洞

1. SQL语句是字符串类型,而且其通常都由多个字符串拼接而成,以用户登录为例

String username;String password;String sql="select * from user where username=" +username "and password=" +password;

username和password的值通常都是由用户输入,由前端传入后台进行验证,如果username输入为" 'sdfds' or 1=1",而password的值任意那么SQL语句就变成:

select * from user where username='sdfds' or 1=1 and password='任意值';

如果username正确,那么 username='sdfds' 得到true,而密码是错误的,而且and的优先级更高,所以 1=1 and password='任意值' 先进行逻辑运算 得到false,然后 true or false 得到true,所以会判断密码正确,进而就造成了不安全的SQL注入漏洞。

2. 解决方法:SQL语句的执行对象使用PreparedStatement对象,因为该对象会预编译SQL,可以防止SQL注入漏洞;该对象所执行的SQL语句,不需要通过字符串拼接来指定SQL语句中需要手动填入的字符串符合,而是替换为 ? 占位符的形式,然后将该SQL语句的格式进行预编译,当编译完成后SQL语句的格式就会被固定,通过PreparedStatement对象向 ? 处的数据需要填充的参数,填充在占位符的数据全部都会成为指定的数据类型形式,而不会出现上面拼接字符串中出现的情况(也就是说会把or、=等关键字当做普通字符串处理),所以就避免了SQL注入漏洞。

PreparedStatement对象通过

import java.io.IOException;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.Properties;public class JDBCDemo4 {	public static void main(String[] args) {		Connection con=null;		PreparedStatement statement=null;		ResultSet rs=null;		try {			Properties pro=new Properties();			pro.load(JDBCDemo3.class.getClassLoader().getResourceAsStream("jdbc/db.properties"));			String driver=pro.getProperty("driver");			String user=pro.getProperty("user");			String url=pro.getProperty("url");			String password=pro.getProperty("password");						Class.forName(driver);			con=DriverManager.getConnection(url, user, password);			String id="1";			//String sql="select * from employee where id="+id;			String sql="select * from employee where id=?";//将拼接字符串改为占位符形式			statement=con.prepareStatement(sql);//进行预编译,固定SQL语句格式			//设置占位符处参数的值,填充数据的参数类型为int型,设置在第一个 ? 占位符处,填充数据为2			//对于or、=等数据库关键字是不被识别的,也是会报错的,无法在这里设置字符串类型的数据,只能是int值			statement.setInt(1,2); //执行时不需要传入sql语句作为参数,因为在预编译时就已经传入,只需直接执行即可			rs=statement.executeQuery();			while(rs.next()){				System.out.println(rs.getInt("id"));				System.out.println(rs.getString(2));				System.out.println(rs.getFloat("salary"));				System.out.println();			}		} catch (ClassNotFoundException e) {			e.printStackTrace();		} catch (SQLException e) {			e.printStackTrace();		} catch (IOException e) {			e.printStackTrace();		}finally {			try {				if(rs!=null){					rs.close();				}			} catch (SQLException e) {				e.printStackTrace();			}			rs=null;			try {				if(statement!=null){					statement.close();				}			} catch (SQLException e) {				e.printStackTrace();			}			statement=null;			try {				if(con!=null){					con.close();						}			} catch (SQLException e) {				e.printStackTrace();			}			con=null;		}	}}

3. 事务

1. 简介:事务表示一组逻辑上的操作,要么全部成功要么全部失败。其有四个特性,原子性、一致性、隔离性和持续性。通常用于一组数据更新操作。

2. MySQL中事务相关的命令:

start transaction; 使用该命令来开启一个mysql事务。commit; 使用该命令提交事务rollback; 使用该命令事务回滚set autocommit=off或0; 设置其后执行的SQL语句执行后不自动提交,执行该行命令后,表示在此命令之后执行的所有SQL语句都必须输入 commit 命令来提交SQL语句的执行结果,永久存储到数据库中,也就相当于每条SQL语句都会开启一个事务,执行完毕后需要输入提交或回滚命令。show variables like '%commit%'; 通过该语句查看当前数据库是否是自动提交事务的

3. 开启事务的两种方法:在事务中执行的SQL语句,操作的是临时表,更改的数据也是临时表的数据,提交之后才会更改数据库表中的数据

通过 使用该命令开启事务后,就可以执行多条SQL语句,当执行完毕后,如果过确认无误则输入命令进行事务提交,此时SQL语句执行的结果就会真正存储到数据库中,如果SQL语句执行有误,则输入事务回滚命令,就会初始化此次事务所执行的所有SQL语句的结果,也就是使数据库中的数据返回到本次事务中所有的SQL语句未执行前的状态。比如

start transaction;//开启事务//执行多个SQL语句sql1;sql2;...commit;//提交SQL语句执行结果或rollback;//回滚SQL语句执行结果
MySQL中的SQL语句执行完毕后,是默认会自动提交的,通过 set autocommit=off或0; 命令设置其后执行的SQL语句执行后不自动提交,执行该行命令后,表示在此命令之后执行的所有SQL语句都必须输入 commit 命令来提交SQL语句的执行结果,永久存储到数据库中,也就是相当于每条SQL语句都会开启一个事务,执行完毕后需要输入提交或回滚命令。比如
show variables like '%commit%';//查看当前数据库是否自动提交SQL执行结果的,如果是set autocommit = off或0;sql1;sql2;...commit;//提交或rollback;//回滚

4. JDBC代码中使用事务:通过java.sql.Connection对象来操作事务

开启事务:调用 void setAutoCommit(boolean autoCommit)方法,将参数值设置为false,即设置数据库取消自动提交事务。提交事务:调用 void commit()事务回滚:调用 void rollback()

import java.io.IOException;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.Properties;/** * @ClassName:JDBCDemo5 * @Description:JDBC代码中使用事务 */public class JDBCDemo5 {	public static void main(String[] args) {		Connection con=null;		PreparedStatement statement=null;		ResultSet rs=null;		try {			Properties pro=new Properties();			pro.load(JDBCDemo3.class.getClassLoader().getResourceAsStream("jdbc/db.properties"));			String driver=pro.getProperty("driver");			String user=pro.getProperty("user");			String url=pro.getProperty("url");			String password=pro.getProperty("password");						Class.forName(driver);			con=DriverManager.getConnection(url, user, password);			//开启事务			con.setAutoCommit(false);			String sql="insert into employee values(null,'vn',20234,1)";			PreparedStatement ps=con.prepareStatement(sql);			ps.executeUpdate(sql);//执行SQL语句			//提交事务			con.commit();		} catch (ClassNotFoundException e) {			//若发生异常,则事务回滚			try {				con.rollback();			} catch (SQLException e1) {				// TODO Auto-generated catch block				e1.printStackTrace();			}			e.printStackTrace();		} catch (SQLException e) {			//若发生异常,则事务回滚			try {				con.rollback();			} catch (SQLException e1) {				// TODO Auto-generated catch block				e1.printStackTrace();			}			e.printStackTrace();		} catch (IOException e) {			//若发生异常,则事务回滚			try {				con.rollback();			} catch (SQLException e1) {				// TODO Auto-generated catch block				e1.printStackTrace();			}			e.printStackTrace();		}finally {			try {				if(rs!=null){					rs.close();				}			} catch (SQLException e) {				e.printStackTrace();			}			rs=null;			try {				if(statement!=null){					statement.close();				}			} catch (SQLException e) {				e.printStackTrace();			}			statement=null;			try {				if(con!=null){					con.close();						}			} catch (SQLException e) {				e.printStackTrace();			}			con=null;		}	}	}

5. 事务的4大特性:原子性、一致性、隔离性和持续性

原子性:指事务是一个不可分割的工作单位,其中的操作要么全部发生,要么全不发生。一致性:事务前后的数据完整性必须保持一致,比如A表的某个字段依赖B表的主键,那么如果要删除B表中的主键数据时,必须先把A表中外键对应B表的数据先行删除。隔离性:指多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间的数据要互相隔离。在并发访问时,如果不考虑隔离性,则会产生以下问题数据脏读:指一个事务读取了另一个未提交的事务的数据。不可重复读:在A事务中,多次重新执行一个查询,在B事务中进行数据修改并先行提交,当A事务返回查询的数据结果后,会发现获取的数据会被另一个事务修改过。正常来说,同一个事务内部,多次虚读:在A事务中,多次重新执行一个查询,在B事务中进行数据插入并先行提交,当A事务返回查询的数据结果后,会发现获取的数据会被另一个事务修改过。持续性:是指一个事务一旦被提交,就会对数据库中的数据进行的改变是永久性的。

6. 数据库事务隔离设置:有四个隔离级别,分别是

serializable:可避免脏读、不可重复读、以及虚读情况,相当于将所有的事务进行串行化执行,效率最低,安全性最高repeatable read:避免不可重复读、脏读情况,但不能避免虚读。效率大于上一个,安全性小于上一个read committed:可以避免脏读情况(读已提交),效率大于上一个,安全性小于上一个read uncommitted:最低级别,以上情况均不能保证(未提交读),效率最高,安全性最低

MySQL数据库中可通过以下命令语句设置事务隔离级别(默认级别为repeatable read)

set session transaction isolation level xx; (xx代表隔离级别)设置事务隔离级别select @@tx_isolation; 查询当前事务的隔离级别

7. JDBC代码中设置事务隔离级别:四个级别分别对应Connection对象中的四个静态变量

static int TRANSACTION_READ_UNCOMMITTED = 1;static int TRANSACTION_READ_COMMITTED = 2;static int TRANSACTION_REPEATABLE_READ = 4;static int TRANSACTION_SERIALIZABLE = 8;void setTransactionIsolation(int level):Connection对象中通过该方法设置隔离级别,参数就是以上四个int变量

import java.io.IOException;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.Properties;public class JDBCDemo4 {	public static void main(String[] args) {		Connection con=null;		PreparedStatement statement=null;		ResultSet rs=null;		try {			Properties pro=new Properties();			pro.load(JDBCDemo3.class.getClassLoader().getResourceAsStream("jdbc/db.properties"));			String driver=pro.getProperty("driver");			String user=pro.getProperty("user");			String url=pro.getProperty("url");			String password=pro.getProperty("password");						Class.forName(driver);			con=DriverManager.getConnection(url, user, password);			String id="1";			//String sql="select * from employee where id="+id;			String sql="select * from employee where id=?";//将拼接字符串改为占位符形式			statement=con.prepareStatement(sql);//进行预编译,固定SQL语句格式			//设置占位符处参数的值,填充数据的参数类型为int型,设置在第一个 ? 占位符处,填充数据为2			//对于or、=等数据库关键字是不被识别的,也是会报错的,无法在这里设置字符串类型的数据,只能是int值			statement.setInt(1,2);			rs=statement.executeQuery();			while(rs.next()){				System.out.println(rs.getInt("id"));				System.out.println(rs.getString(2));				System.out.println(rs.getFloat("salary"));				System.out.println();			}		} catch (ClassNotFoundException e) {			e.printStackTrace();		} catch (SQLException e) {			e.printStackTrace();		} catch (IOException e) {			e.printStackTrace();		}finally {			try {				if(rs!=null){					rs.close();				}			} catch (SQLException e) {				e.printStackTrace();			}			rs=null;			try {				if(statement!=null){					statement.close();				}			} catch (SQLException e) {				e.printStackTrace();			}			statement=null;			try {				if(con!=null){					con.close();						}			} catch (SQLException e) {				e.printStackTrace();			}			con=null;		}	}}

4. 数据库连接池技术

1. 在上面的jdbc代码,都是简单的实现代码,在代码中每开启一个Connection连接对象,都需要关闭释放,而获取和销毁连接操作都会消耗一些时间,而当有大量的开启关闭Connection动作时,就会使性能降低,效率低下,而且可能会造成内存溢出,而使用连接池技术就可以很好的避免这个问题。

2. 连接池技术:连接池技术类似于线程池,提前创建多个连接对象并放在连接池(也就是内存中,从内存取肯定比创建快)中,并且使用完后也不需要关闭销毁,当需要使用时就从连接池中获取,使用完后归还即可。

3. 连接池配置参数:

有默认值,但一般需要根据需求和条件来配置性能最高的参数

初始连接个数大小:连接池中的初始连接数最小空闲连接数:当空闲连接数小于该值时,就会创建新连接放入连接池增量:当需要创建新连接时,一次性创建的最小连接数最大空闲连接数:当空闲的连接数超出这个数值时,就会把多余的连接销毁,仅剩下数量等于这个数值的连接最大连接数:所能创建的最大连接数最大等待时间:当最大连接数目的连接全都处于占用时,其他新的连接请求的最大等待连接时间,单位为毫秒。

无默认值,必须配置的参数:

DriverClassName:要连接的数据库的驱动类的全限定名Url:数据库的地址Username:登录数据库的用户名Password:登录数据库的用户密码

4. 数据库连接池中利用装饰者模式增强的Connection对象:从数据库连接池中获取到的Connection对象并不是普通的由数据库厂商实现的Connection实现类的对象,而是将由数据库厂商实现的Connection实现类增强,将Connection对象方法中的close方法修改为不销毁连接,而是返还给数据库连接池。演示简单原理如下

//首先是sun公司提供的java.sql.Connection接口//然后是数据库厂商实现sun公司提供的java.sql.Connection接口的实现类,以MySQL为例是com.mysql.jdbc.Connection//然后是数据库连接池中利用装饰者模式实现的com.mysql.jdbc.Connection类的增强类/** * @ClassName:JDBCDemo7 * @Description:自定义数据库连接池 */public class MyDataSource implements Connection{	public Connection conn;//该Connection对象指向的是一个由数据库厂商实现的Connection类	public List<Connection> list;//该集合表示数据库连接池中维护的Connection对象集合	//该构造方法会由数据库连接池来执行,当执行getConnection()方法时就会执行该方法并返回这个增强的Connection对象,	//并传入对应参数,Connection conn参数就是数据库连接池中创建的com.mysql.jdbc.Connection对象	public MyDataSource(Connection conn,List<Connection> list){		this.conn=conn;		this.list=list;	}	// 增强该方法,或者说修改该方法,不销毁连接对象,而是改为归还连接对象	public void close() throws SQLException {		list.add(conn);	}//还有其他许多要实现的方法,但都可以使用conn的相对应的方法,主要是close方法}

所以,对于那些数据连接池的开源项目,其中获取的Connection对象的close方法都是返还连接,而不是销毁连接,所以只需使用该方法即可。

5. 常用的几个数据库开源项目:dbcp连接池、c3p0连接池、druid连接池(阿里提供,性能最好的),使用方式为

dbcp连接池:需要导入名为commons-dbcp的jar包,使用时通过org.apache.commons.dbcp.BasicDataSource类来使用连接池的功能

import java.io.IOException;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;import org.apache.commons.dbcp.BasicDataSource;/** * @ClassName:JDBCDemo7 * @Description:使用DBCP连接池,建立一个工厂类获取Connection对象 */public class JDBCDemo7 {	private static BasicDataSource bds;	private static String driver;	private static String user;	private static String url;	private static String password;	private static String initsize;	private static String maxsize;	static{ //通过配置文件来读取数据库连接池的相应配置		Properties p=new Properties();		try {			p.load(test1.class.getClassLoader().getResourceAsStream("jdbc/db.properties"));			driver=p.getProperty("driver");			user=p.getProperty("user");			url=p.getProperty("url");			password=p.getProperty("password");			initsize=p.getProperty("initsize");			maxsize=p.getProperty("maxsize");			bds=new BasicDataSource();			bds.setDriverClassName(driver);			bds.setUrl(url);			bds.setPassword(password);			bds.setUsername(user);			bds.setInitialSize(Integer.parseInt(initsize));			bds.setMaxActive(Integer.parseInt(maxsize));					} catch (IOException e) {			// TODO Auto-generated catch block			e.printStackTrace();			throw new RuntimeException("配置文件读取失败",e);		}	}	public Connection getConnection() throws SQLException{		return bds.getConnection();		}	public void close(Connection con){		if(con!=null)			try {				con.close();			} catch (SQLException e) {				// TODO Auto-generated catch block				e.printStackTrace();				throw new RuntimeException("连接关闭异常",e);			}	}	public static void main(String[] args) {		JDBCDemo7 t=new JDBCDemo7();		Connection con=null;		try {			con=t.getConnection();			System.out.println(con.toString());		} catch (SQLException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}finally {			try {				con.close();			} catch (SQLException e) {				// TODO Auto-generated catch block				e.printStackTrace();			}		}	}}
c3p0连接池:需要导入名为c3p0的jar包,使用时通过com.mchange.v2.c3p0.ComboPooledDataSource类来使用连接池的功能,具体实现遇上面dbcp连接池的使用方式基本类似druid连接池:需要导入名为druid的jar包,使用时通过com.alibaba.druid.pool.DruidDataSource类来使用连接池的功能

5. JDBC查询数据分页

1. 简介:在开发中,常常会将从数据库中查询到的数据,分为多个部分,在客户端使用多个页面来向用户展示,比如百度搜索出来的结果。分页分为物理分页和逻辑分页,

物理分页:指利用MySQL等数据库中的SQL语句中的分页关键字来实现分页查询,比如MySQL数据库中的分页关键字为limit,使用形式比如 select * from mytable limit m,n; 表示检索第m+1条到第m+n条数据,m<n。逻辑分页:表示先用SQL语句查询到需要的数据结果,然后将这个数据结果通过逻辑代码进行按页分割,将分割后指定部分的数据返回。主要应用于没有分页关键字的数据库,比如Oracle数据库。

标签: #jdbc创建数据库mysql