JDBC学习笔记.docx
《JDBC学习笔记.docx》由会员分享,可在线阅读,更多相关《JDBC学习笔记.docx(29页珍藏版)》请在冰豆网上搜索。
JDBC学习笔记
JDBC学习笔记
Rick-bao
2015年3月21日
声明:
本笔记来自于佟刚老师源教程。
目录
第一章连接数据库1
第一节准备工作1
第二节小试牛刀(代码实战)2
本章知识总结与扩展4
第二章数据库操作5
第一节更新5
1.1构建共用代码5
第二节查询7
2.1构建查询7
2.2通用查询方法8
第三节优化sql11
3.1使用PreparedStatement接口11
3.2存取blob大对象12
3.3数据库隔离级别13
3.4数据库事务14
3.5批量处理14
第四节数据库连接池15
4.1DBCP连接池15
4.2C3P0连接池16
第五节使用DBUitls工具类18
5.1更新18
5.2查询18
5.3编写通用DAO19
第一章连接数据库
第一节准备工作
1、若要连接数据库,必须先下载好第三方提供的连接jar文件。
本示例主要以MySQL演示为主,连接Oracle也会提及相关知识。
具体如下:
其中,mysql-connector-java-5.*.jar是MySQL驱动类,ojdbc6.jar是Oracle驱动类。
2、确保您的电脑中已经安装好了数据库,并能正常运行。
下图是使用第三方mysqlfront软件,具体可以到http:
//www.mysqlfront.de/官网下载,连接并运行如下图所示:
图1-1MySQL的连接信息
图1-2进入数据库界面
第二节小试牛刀(代码实战)
1、首先,启动myeclipse或eclipse工具,新建项目并添加测试类。
图2-1新建项目
注意:
1、Java普通项目下没有lib这个目录,需要新建一个folder,然后加入准备好的jar文件,如下图
图2-2加入jar文件
2、然后将lib下的jar加入到项目库引用中,具体为选中jar文件—>右键buildpath—>Addtobuildpath,添加成功后如下图所示
图2-3添加成功
2、然后,新建类getConnection,添加如下代码
publicbooleangetConnection(StringDriverType)throwsException{
//数据库常量定义
Stringdriver=null;
StringjdbcUrl=null;
Stringuser=null;
Stringpassword=null;
//读取配置文件
InputStreamin=getClass().getClassLoader().getResourceAsStream("jdbc.properties");
Propertiesproperties=newProperties();
properties.load(in);//配置文件信息载入
driver=properties.getProperty("driver");
jdbcUrl=properties.getProperty("jdbcUrl");
user=properties.getProperty("user");
password=properties.getProperty("password");
try{
if(DriverType==null)
returnfalse;
else{
Class.forName(driver);//装载驱动类
DriverManager.getConnection(jdbcUrl,user,password);
returntrue;
}
}catch(Exceptione){
returnfalse;
}
}
3、接着在src目录下新建一个file文件,命名为jdbc.properties,在文件中加入连库信息,如下图
图2-4配置数据库连接信息
4、最后,添加一个测试类来享受劳动成果了。
添加测试类TestDriverManager
并加入如下代码
JDBCConnectionjdbc=newJDBCConnection();
System.out.println(jdbc.getConnection("mysql"));
选中测试类并运行,最终输出如下结果表明连接成功,如下图
图2-5测试通过
本章知识总结与扩展
本示例中采用DriverManager加载了数据库连接驱动以及连库信息,相比MySQL提供的jar单独连接实用得多。
DriverManager可以加载多个数据库连接信息,只要更改配置文件即可连接到其它数据库,灵活性非常高。
在以上代码try{}中加入如下代码并更改返回值为com.mysql.jdbc.Connection,可以看到连接到MySQL驱动的类。
//3.获得驱动名称
Driverdriver=(Driver)Class.forName(driverClass).newInstance();
Propertiesinfo=newProperties();
info.put("user",user);
info.put("password",password);
//4.获得连接
Connectionconnection=(Connection)driver.connect(jdbcUrl,info);//获取连接
returnconnection;
另外,一些常见数据库URL如下(sid是你的数据库名称)
Oracle:
jdbc:
oracle:
thin:
@localhost:
1521:
sid
SQLServer:
jdbc:
microsoft:
sqlserver//localhost:
1433;DatabaseName=sid
MYSQL:
mysql:
//localhost:
3306/sid
第二章数据库操作
第一节更新
1.1构建共用代码
1.在连库成功后,需要获取操作对象statement。
然而,更新操作全部调用statement的executeUpdate方法,故创建更新通用方法如下
/**
*共同的添加,修改,删除方法
*@paramsql
*@returnresult
*/
publicstaticintupdate(Stringsql){
intresult=0;
Connectionconnection=null;
Statementstatement=null;
try{
try{
connection=getConnection();
}catch(Exceptione){
e.printStackTrace();
}
statement=connection.createStatement();//获取操作对象
statement.executeUpdate(sql);//执行操作
}catch(SQLExceptione){
e.printStackTrace();
}finally{
close(statement,connection);//关闭只要
}
returnresult;
}
2.共用方法构建完成后,添加测试方法TestUpdates(),代码如下
@Test
publicvoidTestUpdates(){
//新增SQL
Stringaddsql="insertintomember(id,name,birth,email)values('tt5565','MM','2014-3-5','card@')";
//修改SQL
Stringupdate="updatemembermsetm.name='李东'wherem.id='1331'";
//删除SQL
Stringdelete="deletefrommemberwhereID='mmd33'";
JDBCUtils.update(addsql);
System.out.println("添加一条记录成功!
");
JDBCUtils.update(update);
System.out.println("修改一条记录成功!
!
");
JDBCUtils.update(delete);
System.out.println("删除成功!
");
}
3.执行测试,显示结果如下
图1-1更新表
第二节查询
2.1构建查询
在查询中,主要使用statement的executeQuery(sql)方法获取查询结果,使用resultSet接收结果集。
主要代码如下
Connectionconnection=null;
Statementstatement=null;
ResultSetresultSet=null;
Mapmap=newHashMap();
//连库
try{
connection=getConnection();
}catch(Exceptione){
e.printStackTrace();
}
//创建操作对象
try{
statement=connection.createStatement();
}catch(SQLExceptione){
e.printStackTrace();
}
//处理结果集
try{
resultSet=statement.executeQuery(sql);
while(resultSet.next()){
//输出结果集
System.out.println(resultSet.getString
(1)+""+resultSet.getString
(2)+""+resultSet.getDate(3)+""+resultSet.getString("EMAIL"));
}
}catch(SQLExceptione){
e.printStackTrace();
}
//关闭资源
close(resultSet,statement,connection);
添加测试方法并运行,结果如下图所示
图2-1查询结果集
2.2通用查询方法
编写高内聚、低耦合的程序代码有助于后期的维护。
提高代码复用可以节省我们大量的时间,以下是优化后的通用查询方法代码
代码片段1:
publicListgetAll(Classclazz,Stringsql,
Object...args){
//创建连接
Connectionconnection=null;
//创建操作对象
PreparedStatementpreparedStatement=null;
//创建结果集
ResultSetresultSet=null;
//存放结果集
Listresults=newArrayList();
try{
connection=JDBCUtils.getConnection();
preparedStatement=connection.prepareStatement(sql);
//设置sql参数
for(inti=0;ipreparedStatement.setObject(i+1,args[i]);
resultSet=preparedStatement.executeQuery();
List
results=handleEntity(clazz,values);//独立的entity反射方法
}catch(Exceptione){
e.printStackTrace();
}finally{
JDBCUtils.close(resultSet,preparedStatement,connection);
}
returnresults;
}
代码片段2:
privateList
throwsSQLException{
//存放map对象到list中
List
ListcolumnLables=getColumnLable(resultSet);//映射列名
//声明单个map
Mapvalue=null;
//结果集存放
while(resultSet.next()){
value=newHashMap();
for(Stringcollable:
columnLables){
Objectv=resultSet.getObject(collable);//值
value.put(collable,v);
}
values.add(value);
}
returnvalues;
}
代码片段3:
privateListgetColumnLable(ResultSetrs){
Listlables=newArrayList();
try{
ResultSetMetaDatametaData=rs.getMetaData();
for(inti=0;ilables.add(metaData.getColumnLabel(i+1));
}catch(Exceptione){
e.printStackTrace();
}
returnlables;
}
代码片段4:
privateListhandleEntity(Classclazz,
List>values)throwsInstantiationException,
IllegalAccessException,InvocationTargetException{
Listresults=newArrayList();
//对象反射
Tbean=null;//声明空实体
if(values.size()>0){
for(Mapm:
values){
bean=clazz.newInstance();//实例化实体对象
for(Map.Entryentry:
m.entrySet()){
Stringtkey=entry.getKey();//获取键
Objecttvalue=entry.getValue();//获取值
BeanUtils.setProperty(bean,tkey,tvalue);//反射对象
}
results.add(bean);
}
}
returnresults;
}
第三节优化sql
3.1使用PreparedStatement接口
拼接字符串是很费时间而且容易出错的,在SQL中使用占位符,使用
PreparedStatement对象的setXXX方法填补占位符相对是比较可观的,代码如下
Connectionconnection=null;
PreparedStatementstatement=null;//使用
Stringsql="insertintomembervalues(?
?
?
?
)";//使用占位符
try{
connection=JDBCUtils.getConnection();
statement=connection.prepareStatement(sql);//创建实现
statement.setString(1,"KE");//填补占位符
statement.setString(2,"Bob");
statement.setDate(3,newDate(newjava.util.Date().getTime()));
statement.setString(4,"li@");
statement.execute();//执行更新,不再使用sql
}catch(Exceptione){
e.printStackTrace();
}finally{
JDBCUtils.close(null,statement,connection);
}
运行结果如下:
图3-1显示结果
3.2存取blob大对象
在某些数据表中需要存入大对象,如图片,文本等,以下介绍blob的使用,代码如下
更新数据表:
publicbooleanupdate(){
Connectionconnection=null;
PreparedStatementpreparedStatement=null;
Stringsql="insertintotb_order(id,member,number,img,commodity,comment)"
+"values(?
?
?
?
?
?
)";
try{
connection=JDBCUtils.getConnection();
preparedStatement=connection.prepareStatement(sql);
preparedStatement.setString(1,newRandom(8*8).toString());
preparedStatement.setObject(2,"88");
preparedStatement.setString(3,"5898");
preparedStatement.setBlob(4,newFileInputStream("img/yb.jpg"));//需要输入流
preparedStatement.setObject(5,"A5");
preparedStatement.setString(6,"MD");
if(preparedStatement.executeUpdate()>0)
returntrue;
}catch(Exceptione){
e.printStackTrace();
}finally{
JDBCUtils.close(null,preparedStatement,connection);
}
returnfalse;
}
获取blob:
***************部分代码省略****************
resultSet=preparedStatement.executeQuery();
if(resultSet.next()){
Stringid=resultSet.getString
(1);
Stringmember=resultSet.getString
(2);
//读取blob大对象类型
Blobimg=resultSet.getBlob(4);
InputStreamin=img.getBinaryStream();
OutputStreamout=newFileOutputStream("img/copy.jpg");
byte[]b=newbyte[1024];
intlen=0;
while((len=in.read(b))!
=-1){
out.write(b,0,len);
}
in.close();
out.close();
//blob处理完毕
*********部分代码省略************
3.3数据库隔离级别
如果DBMS支持事务处理,它必须有某种途径来管理两个事务同时对一个数据库进行操作时可能发生的冲突。
用户可指定事务隔离级别,以指明DBMS应该花多大精力来解决潜在冲突。
例如,当事务更改了某个值而第二个事务却在该更改被提交或还原前读取该值。
JDBC的数据隔离级别设置:
图3-2数据库隔离级别
以下是示例代码截图
图3-3数据库隔离级别
3.4数据库事务
数据库事务默认为自动提交,如果未对其设置,有可能会产生更新不同步,部分数据中断等诸多问题。
因此,我们需要设置事务为手动提交,待执行完所有操作后统一提交,如中途异常,可以回滚,返回最初状态。
具体代码如下
//获取数据库连接.........代码省略
connection.setAutoCommit(false);//设置为手动提交
//操作数据库............代码略
connection.