Java数据库连接,(JavaDatabaseConnectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是SunMicrosystems的商标。它JDBC是面向关系型数据库的。
简单地说,就是用于执行SQL语句的一类JavaAPI,通过JDBC使得我们可以直接使用Java编程来对关系数据库进行操作。通过封装,可以使开发人员使用纯JavaAPI完成SQL的执行。
使用JDBC操作数据库之前,首先你需要有一个数据库。这里提供了3个链接供读者自学,如果曾有过SQL语言的使用经历(包括在学校中的课堂学习),前两个链接足以上手。
建议边看入门教程,边练习,在练习insert、update、select、delete等基本操作的同时,将后面要用的表建好。
下图是我接下来用于演示的数据库的表。
在工程的图标上右击,选择”Properties”,在”JavaBulidPath”中选择”AddExternalJARs…”,选择下载并解压后获得的jar包。
如果对MySQL进行操作,这时下面的import就不会报错了:
importcom.mysql.jdbc.Connection;importcom.mysql.jdbc.PreparedStatement;除此以外,还需要JDBC的包,直接import即可。
importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;
先看具体代码并实践,本文第五部分对用到的API稍作了研究。
下面的所有方法和数据成员都在publicclassJDBCOperation内部。
这样做主要是为了便于操作和接口定义,是非必须的。
staticclassStudent{privateStringId;privateStringName;privateStringSex;privateStringAge;Student(StringName,StringSex,StringAge){this.Id=null;//defaultthis.Name=Name;this.Sex=Sex;this.Age=Age;}publicStringgetId(){returnId;}publicvoidsetId(StringId){this.Id=Id;}publicStringgetName(){returnName;}publicvoidsetName(StringName){this.Name=Name;}publicStringgetSex(){returnSex;}publicvoidsetSex(StringSex){this.Sex=Sex;}publicStringgetAge(){returnAge;}publicvoidsetage(StringAge){this.Age=Age;}}
在操作前必须先获取与数据库的连接。
privatestaticConnectiongetConn(){Stringdriver="com.mysql.jdbc.Driver";Stringurl="jdbc:mysql://localhost:3306/samp_db";Stringusername="root";Stringpassword="";Connectionconn=null;try{Class.forName(driver);//classLoader,加载对应驱动conn=(Connection)DriverManager.getConnection(url,username,password);}catch(ClassNotFoundExceptione){e.printStackTrace();}catch(SQLExceptione){e.printStackTrace();}returnconn;}
privatestaticintinsert(Studentstudent){Connectionconn=getConn();inti=0;Stringsql="insertintostudents(Name,Sex,Age)values(,,)";PreparedStatementpstmt;try{pstmt=(PreparedStatement)conn.prepareStatement(sql);pstmt.setString(1,student.getName());pstmt.setString(2,student.getSex());pstmt.setString(3,student.getAge());i=pstmt.executeUpdate();pstmt.close();conn.close();}catch(SQLExceptione){e.printStackTrace();}returni;}
privatestaticintupdate(Studentstudent){Connectionconn=getConn();inti=0;Stringsql="updatestudentssetAge='"+student.getAge()+"'whereName='"+student.getName()+"'";PreparedStatementpstmt;try{pstmt=(PreparedStatement)conn.prepareStatement(sql);i=pstmt.executeUpdate();System.out.println("resutl:"+i);pstmt.close();conn.close();}catch(SQLExceptione){e.printStackTrace();}returni;}
以select*fromXXX为例。
privatestaticIntegergetAll(){Connectionconn=getConn();Stringsql="select*fromstudents";PreparedStatementpstmt;try{pstmt=(PreparedStatement)conn.prepareStatement(sql);ResultSetrs=pstmt.executeQuery();intcol=rs.getMetaData().getColumnCount();System.out.println("============================");while(rs.next()){for(inti=1;i<=col;i++){System.out.print(rs.getString(i)+"\t");if((i==2)&&(rs.getString(i).length()<8)){System.out.print("\t");}}System.out.println("");}System.out.println("============================");}catch(SQLExceptione){e.printStackTrace();}returnnull;}
privatestaticintdelete(Stringname){Connectionconn=getConn();inti=0;Stringsql="deletefromstudentswhereName='"+name+"'";PreparedStatementpstmt;try{pstmt=(PreparedStatement)conn.prepareStatement(sql);i=pstmt.executeUpdate();System.out.println("resutl:"+i);pstmt.close();conn.close();}catch(SQLExceptione){e.printStackTrace();}returni;}
在测试前,需要在系统中打开对应数据库的服务。MySQL在Windows下的启动命令为
netstartmysql
测试代码
publicstaticvoidmain(Stringargs[]){JDBCOperation.getAll();JDBCOperation.insert(newStudent("Achilles","Male","14"));JDBCOperation.getAll();JDBCOperation.update(newStudent("Bean","","7"));JDBCOperation.delete("Achilles");JDBCOperation.getAll();}
Eclipse中的输出
============================1Endermale82Beanmale63Petrafema94Petermale95_Graffmale406GODfema255========================================================1Endermale82Beanmale63Petrafema94Petermale95_Graffmale406GODfema2557AchillesMale14============================resutl:1resutl:1============================1Endermale82Beanmale73Petrafema94Petermale95_Graffmale406GODfema255============================
在上述对数据库进行增删改查的过程中,可以发现其共性部分,即通用的流程:
(1)创建Connection对象、SQL查询命令字符串;
(2)对Connection对象传入SQL查询命令,获得PreparedStatement对象;
(3)对PreparedStatement对象执行executeUpdate()或executeQurey()获得结果;
(4)先后关闭PreparedStatement对象和Connection对象。
可见,使用JDBC时,最常打交道的是Connection、PreparedStatement这两个类,以及select中的ResultSet类。查阅JavaAPI手册可以了解其具体的意义和方法。
Connection
与特定数据库的连接(会话)。在连接上下文中执行SQL语句并返回结果。
Connection对象的数据库能够提供描述其表、所支持的SQL语法、存储过程、此连接功能等等的信息。此信息是使用getMetaData方法获得的。
PreparedStatemnt
SQL语句被预编译并存储在PreparedStatement对象中。然后可以使用此对象多次高效地执行该语句。
常用方法
booleanexecute()
在此PreparedStatement对象中执行SQL语句,该语句可以是任何种类的SQL语句。
ResultSetexecuteQuery()
在此PreparedStatement对象中执行SQL查询,并返回该查询生成的ResultSet对象。
intexecuteUpdate()
在此PreparedStatement对象中执行SQL语句,该语句必须是一个SQL数据操作语言(DataManipulationLanguage,DML)语句,比如INSERT、UPDATE或DELETE语句;或者是无返回内容的SQL语句,比如DDL语句。
ResultSet
1.每次SQL操作都需要建立和关闭连接,这势必会消耗大量的资源开销,如何避免?
分析:可以采用连接池,对连接进行统一维护,不必每次都建立和关闭。事实上这是很多对JDBC进行封装的工具所采用的。
2.Java代码中,传入的数据格式与数据库定义不同怎么办?如把Java的String对象赋值给数据库的tinyint属性。
分析:在执行SQL语句时,数据库会尝试进行转换。根据我的实验,如果用内容为纯字母的String对象传入tinyint的age属性时,会被转化成0。具体转化规则应该和数据库有关。