仓酷云
标题:
JAVA网页编程之利用JDBC创立数据库会见程序
[打印本页]
作者:
谁可相欹
时间:
2015-1-18 11:50
标题:
JAVA网页编程之利用JDBC创立数据库会见程序
你说是sun公司对她研究的透还是微软?针对自己工具开发的.net性能上肯定会站上风的。程序|创立|会见|数据|数据库
甚么是数据库?
数据库是以某种文件布局存储的一系列信息表,这类文件布局使您可以会见这些表、选择表中的列、对表举行排序和依据各类尺度选择行。数据库一般有多个索引与这些表中的很多列相干联,以是我们能尽量快地会见这些表。
以员工纪录为例,您能够假想一个含有员工姓名、地点、人为、扣税和补助等外容的表。让我们思索一下这些内容大概怎样构造在一同。您能够假想一个表包括员工姓名、地点和德律风号码。您但愿保留的别的信息大概包含人为、人为局限、前次加薪工夫、下次加薪工夫、员产业绩评定等外容。
这些内容是不是应保留在一个表格中?几近能够一定不该该云云。分歧种别的员工的人为局限大概没有区分;如许,您能够仅将员工范例贮存在员工纪录表中,而将人为局限贮存在另外一个表中,经由过程范例编号与这个表联系关系。思索以下情形:
KeyLastnameSalaryTypeSalaryTypeMinMax1Adams2130000450002Johnson1245000600003Smyth3360000750004Tully15Wolff2
SalaryType列中的数据援用第二个表。我们能够设想出很多种如许的表,如用于存储寓居乡村和每一个乡村的税值、安康企图扣除金额等的表。每一个表都有一个主键列(如下面两个表中最右边的列)和多少数据列。在数据库中创建表格既是一门艺术,也是一门迷信。这些表的布局由它们的范式指出。我们一般说表属于1NF、2NF或3NF。
第一范式:表中的每一个表元应当只要一个值(永久不成能是一个数组)。(1NF)
第二范式:满意1NF,而且每个非主键列完整依附于主键列。这暗示主键和该行中的残剩表元之间是1对1的干系。(2NF)
第三范式:满意2NF,而且一切非主键列是相互自力的。任何一个数据列中包括的值都不克不及从其他列的数据盘算失掉。(3NF)如今,几近一切的数据库都是基于“第三范式(3NF)”创立的。这意味着一般都有相称多的表,每一个表中的信息列都绝对较少。
从数据库中猎取数据
假定我们但愿天生一个包括员工及其人为局限的表,在我们计划的一个实习中将利用这个表。这个表格不是间接存在在数据库中,但能够经由过程向数据库收回一个查询来构建它。我们但愿失掉以下所示的一个表:
NameMinMaxTully$30,000.00$45,000.00Johnson$30,000.00$45,000.00Wolff$45,000.00$60,000.00Adams$45,000.00$60,000.00Smyth$60,000.00$75,000.00
我们发明,取得这些表的查询情势以下所示
SELECTDISTINCTROWEmployees.Name,SalaryRanges.Min,SalaryRanges.MaxFROMEmployeesINNERJOINSalaryRangesONEmployees.SalaryKey=SalaryRanges.SalaryKeyORDERBYSalaryRanges.Min;
这类言语称为布局化查询言语,即SQL,并且它是几近今朝一切数据库都可使用的一种言语。SQL-92尺度被以为是一种基本尺度,并且已更新屡次。
数据库的品种
PC上的数据库,如dBase、BorlandParadox、MicrosoftAccess和FoxBase。
数据库服务器:IBMDB/2、MicrosoftSQLServer、Oracle、Sybase、SQLBase和XDB。
一切这些数据库产物都撑持多种绝对相似的SQL方言,因而,一切数据库最后看起来好象能够交换。每种数据库都有分歧的功能特性,并且每种都有分歧的用户界面和编程接口。
ODBC
假如我们可以以某种体例编写不依附于特定厂商的数据库的代码,而且可以不改动本人的挪用程序便可从这些数据库中失掉不异的了局,那将是一件很好的事。假如我们能够仅为一切这些数据库编写一些封装,使它们具有类似的编程接口,这类对数据库编程自力于供给商的特征将很简单完成。
甚么是JDBC?
JDBC是对ODBCAPI举行的一种面向对象的封装和从头计划,它易于进修和利用,而且它真正可以使您编写不依附厂商的代码,用以查询和利用数据库。只管它与一切JavaAPI一样,都是面向对象的,但它并非很初级其余对象集.除Microsoft以外,多半厂商都接纳了JDBC,并为其数据库供应了JDBC驱动程序;这使您可轻松地真正编写几近完整不依附数据库的代码。别的,JavaSoft和Intersolv已开辟了一种称为JDBC-ODBCBridge的产物,可以使您毗连还没有间接的JDBC驱动程序的数据库。撑持JDBC的一切数据库必需最少能够撑持SQL-92尺度。这在很年夜水平上完成了跨数据库战争台的可移植性。
安装和利用JDBC
JDBC的类都被回到java.sql包中,在安装JavaJDK1.4时会主动安装。但是,假如您想利用JDBC-ODBC桥。JDBC-ODBC驱动程序可从Sun的Java网站(http://java.sun.com/)轻松地找到并下载。在您扩大并安装了这个驱动程序后,必需实行以下步骤:
将jdbc-odbcclasses;路径增加到您的PATH情况变量中。
将jdbc-odbcclasses;路径增加到您的CLASSPATH情况变量中。
JDBC驱动程序的范例
Java程序毗连数据库的办法实践上有四种:
1.JDBC-ODBC桥和ODBC驱动程序--在这类体例下,这是一个当地办理计划,由于ODBC驱动程序和桥代码必需呈现在用户的每台呆板中。从基本上说这是一个一时办理计划。
2.本机代码和Java驱动程序--它用另外一个当地办理计划(该平台上的Java可挪用的本机代码)代替ODBC和JDBC-ODBC桥。
3.JDBC收集的纯Java驱动程序--由Java驱动程序翻译的JDBC构成传送给服务器的自力协定。然后,服务器可毗连任何数目的数据库。这类办法使您大概从客户机Applet中挪用服务器,并将了局前往到您的Applet。在这类情形下,两头件软件供应商可供应服务器。
4.本机协定Java驱动程序--Java驱动程序间接转换为该数据库的协定并举行挪用。这类办法也能够经由过程收集利用,并且能够在Web扫瞄器的Applet中显现了局。在这类情形下,每一个数据库厂商将供应驱动程序。
假如您但愿编写代码来处置PC客户机数据库,如dBase、Foxbase或Access,则您大概会利用第一种办法,而且具有用户呆板上的一切代码。更年夜的客户机-服务器数据库产物(如IBM的DB2)已供应了第3级其余驱动程序。
两层模子和三层模子
当数据库和查询它的使用程序在统一台呆板上,并且没有服务器代码的干涉时,我们将天生的程序称为两层模子。一层是使用程序,而另外一层是数据库。在JDBC-ODBC桥体系中一般是这类情形。
当一个使用程序或applet挪用服务器,服务器再往挪用数据库时,我们称其为三层模子。当您挪用称为“服务器”的程序时一般是这类情形。
编写JDBC代码会见数据库
用ODBC注册您的数据库
毗连数据库
一切与数据库有关的对象和办法都在java.sql包中,因而在利用JDBC的程序中必需到场"importjava.sql.*"。JDBC要毗连ODBC数据库,您必需起首加载JDBC-ODBC桥驱动程序
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
该语句加载驱动程序,并创立该类的一个实例。然后,要毗连一个特定的数据库,您必需创立Connect类的一个实例,并利用URL语法毗连数据库。
Stringurl="jdbc:odbc:Northwind";
Connectioncon=DriverManager.getConnection(url);
请注重,您利用的数据库名是您在ODBC设置面板中输出的“数据源”称号。
URL语法大概因数据库范例的分歧而变更极年夜。
jdbc:subprotocol:subname
第一组字符代表毗连协定,而且一直是jdbc。还大概有一个子协定,在此处,子协定被指定为odbc。它划定了一类数据库的连通性机制。假如您要毗连别的呆板上的数据库服务器,大概也要指定该呆板和一个子目次:jdbc:bark//doggie/elliott
最初,您大概要指定用户名和口令,作为毗连字符串的一部分:
jdbc:bark//doggie/elliot;UID=GoodDog;PWD=woof
会见MSSQLServer办法:(驱动程序必要:msutil.jar,msbase.jar,mssqlServer.jar)
DBDriver=com.microsoft.jdbc.sqlserver.SQLServerDriverURL=jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=demousername=sapassword=maxcon=10mincon=1poolName=SkyDev
使用我们开辟的数据库类,利用办法以下:
DbObjectDbO=newDbObject(newSqlServerConnectionFactory("localhost",1433,"demo","sa",""));Connectioncon=DbO.getConnection();//类代码(不含毗连工场完成)packageskydev.modules.data;
publicfinalclassSqlServerConnectionFactoryextendsConnectionFactory{privatefinalStringdbDriver="com.microsoft.jdbc.sqlserver.SQLServerDriver";privateStringhost;privateintport;privateStringdatabaseName;
publicSqlServerConnectionFactory(){super.setDriverName(dbDriver);}
/****@paramhost数据库地点的主机名:如"localhost"*@paramportSQL服务器运转的端标语,假如利用缺省值1433,传进一个正数便可*@paramdatabaseName数据库称号*@paramuserName用户名*@parampassword口令*/
publicSqlServerConnectionFactory(Stringhost,intport,StringdatabaseName,StringuserName,Stringpassword){this.setHost(host);this.setPort(port);this.setDatabaseName(databaseName);this.setUserName(userName);this.setPassword(password);
init();}
privatevoidinit(){super.setDriverName(dbDriver);super.setUrl("jdbc:microsoft:sqlserver://"+host.trim()+":"+newInteger(port).toString()+";DatabaseName="+databaseName.trim());//super.setUrl("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=demo");}……
//-----------------------------------------
会见MySQL的办法:
DBDriver=com.mysql.jdbc.DriverURL=jdbc:mysql://localhost/demousername=password=maxcon=5mincon=1poolName=zhengmao
会见数据库
一旦毗连到数据库,就能够哀求表名和表列的称号和内容等信息,并且您能够运转SQL语句来查询数据库大概增加或修正其内容。可用来从数据库中猎取信息的对象有:
DatabaseMetaData有关全部数据库的信息:表名、表的索引、数据库产物的称号和版本、数据库撑持的操纵。
ResultSet关于某个表的信息或一个查询的了局。您必需逐行会见数据行,可是您能够任何按次会见列。
ResultSetMetaData有关ResultSet中列的称号和范例的信息。
只管每一个对象都有大批的办法让您取得数据库元素的极其具体的信息,但在每一个对象中都有几种次要的办法使您可取得数据的最主要信息。但是,假如您但愿看到比此处更多的信息,倡议您进修文档以取得其他办法的申明。
ResultSet
ResultSet对象是JDBC中最主要的单个对象。从实质上讲,它是对一个一样平常宽度和未知长度的表的一种笼统。几近一切的办法和查询都将数据作为ResultSet前往。ResultSet包括恣意数目的定名列,您能够按称号会见这些列。它还包括一个或多个行,您能够按按次自上而下一一会见。在您利用ResultSet之前,必需查询它包括几个列。此信息存储在ResultSetMetaData对象中。
//从元数据中取得列数ResultSetMetaDatarsmd;rsmd=results.getMetaData();numCols=rsmd.getColumnCount();
当您取得一个ResultSet时,它恰好指向第一行之前的地位。您可使用next()办法失掉其他每行,当没有更多行时,该办法会前往false。因为从数据库中猎取数据大概会招致毛病,您必需一直将了局集处置语句包含在一个try块中。
您能够多种情势猎取ResultSet中的数据,这取决于每一个列中存储的数据范例。别的,您能够按列序号或列名猎取列的内容。请注重,列序号从1入手下手,而不是从0入手下手。ResultSet对象的一些最经常使用办法以下所示。
getInt(int);将序号为int的列的内容作为整数前往。
getInt(String);将称号为String的列的内容作为整数前往。
getFloat(int);将序号为int的列的内容作为一个float型数前往。
getFloat(String);将称号为String的列的内容作为float型数前往。
getDate(int);将序号为int的列的内容作为日期前往。
getDate(String);将称号为String的列的内容作为日期前往。
next();将行指针移到下一行。假如没有残剩行,则前往false。
Close();封闭了局集。
getMetaData();前往ResultSetMetaData对象。
ResultSetMetaData
您利用getMetaData()办法从ResultSet中猎取ResultSetMetaData对象。您可使用此对象取得列的数量和范例和每列的称号。
getColumnCount();前往ResultSet中的列数。
getColumnName(int);前往列序号为int的列名。
getColumnLabel(int);前往此列暗含的标签。
isCurrency(int);假如此列包括带有泉币单元的一个数字,则前往true。
isReadOnly(int);假如此列为只读,则前往true。
isAutoIncrement(int);假如此列主动递增,则前往true。这类列一般为键,并且一直是只读的。
getColumnType(int);前往此列的SQL数据范例。这些数据范例包含
BIGINTBINARYBITCHAR
DATEDECIMALDOUBLEFLOATINTEGERLONGVARBINARYLONGVARCHARNULLNUMERICOTHERREALSMALLINTTIMETIMESTAMPTINYINTVARBINARYVARCHARDatabaseMetaData
DatabaseMetaData对象可为您供应全部数据库的信息。您次要用它猎取数据库中表的称号,和表中列的称号。因为分歧的数据库撑持分歧的SQL变体,因而,也有多种办法查询数据库撑持哪些SQL办法。getCatalogs()前往该数据库中的信息目次列表。利用JDBC-ODBCBridge驱动程序,您能够取得用ODBC注册的数据库列表。这很罕用于JDBC-ODBC数据库。
getTables(catalog,schema,tableNames,columnNames)前往表名与tableNames符合并且列名与columnNames符合的一切表的申明。getColumns(catalog,schema,tableNames,columnNames)前往表名与tableNames符合并且列名与columnNames符合的一切表列申明。getURL();取得您所毗连的URL称号。
getDriverName();取得您所毗连的数据库驱动程序的称号。
猎取有关表的信息
您可使用DataBaseMetaData的getTables()办法来猎取数据库中表的信息。这个办法有以下4个String参数:results=dma.getTables(catalog,schema,tablemask,types[]);
个中参数的意义是:
Catalog要在个中查找表名的目次名。关于JDBC-ODBC数据库和很多其他数据库而言,可将其设置为null。这些数据库的目次项实践上是它在文件体系中的相对路径称号。
Schema要包含的数据库“计划”。很多数据库不撑持计划,而对另外一些数据库而言,它代表数据库一切者的用户名。一样平常将它设置为null。
Tablemask一个掩码,用来形貌您要检索的表的称号。假如您但愿检索一切表名,则将其设为通配符%。请注重,SQL中的通配符是%标记,而不是一样平常PC用户的*标记。
types[]这是形貌您要检索的表的范例的String数组。数据库中一般包含很多用于外部处置的表,而对作为用户的您没甚么代价。假如它是空值,则您会失掉一切这些表。假如您将其设为包括字符串“TABLES”的单位素数组,您将仅取得对用户有效的表格。
一个复杂的JDBC程序
我们已进修了JDBC的一切基础功效,如今我们能够编写一个复杂的程序,该程序翻开数据库,打印它的表名和某一表列的内容,然后对该数据库实行查询。此程序以下所示:
packageskydevkit;importjava.sql.*;publicclassJdbcOdbc_test{ResultSetresults;ResultSetMetaDatarsmd;DatabaseMetaDatadma;Connectioncon;
publicJdbcOdbc_test()throwsSQLException{Stringurl="jdbc:odbc:Northwind";try{//加载JDBC-ODBC桥驱动程序Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");con=DriverManager.getConnection(url);//毗连数据库dma=con.getMetaData();//猎取数据库的元数据System.out.println("Connectedto:"+dma.getURL());System.out.println("Driver"+dma.getDriverName());}catch(Exceptione){System.out.println(e);}try{Statementstmt=con.createStatement();
results=stmt.executeQuery("select*from客户;");ResultSetMetaDataresultMetaData=results.getMetaData();intcols=resultMetaData.getColumnCount();StringresultRow="";for(inti=1;i<cols;i++){resultRow+=resultMetaData.getColumnName(i)+";";}System.out.println(resultRow);while(results.next()){resultRow="";for(inti=1;i<cols;i++){try{resultRow+=results.getString(i)+";";}catch(NullPointerExceptione){System.out.println(e.getMessage());}}System.out.println(resultRow);}}catch(Exceptione){System.out.println("queryexception");}finally{results.close();}}}
关于挪用SQLServer存储历程的例子:(用到了我们开辟的数据库毗连类)
CREATEPROCEDURE[dbo].[sp_getStudentByName](@namechar(10))ASSelect*fromStudentswhere[Name]=@nameGO
DbObjectDbO=newDbObject(newSqlServerConnectionFactory("localhost",1433,"demo","sa",""));Connectioncon=DbO.getConnection();CallableStatementpstmt=null;System.out.println("TestDB1()............");/*try{pstmt=con.prepareCall("{callsp_getStudentById(?)}");pstmt.setInt(1,1);}*/try{pstmt=con.prepareCall("{callsp_getStudentByName(?)}");//注重参数怎样传送pstmt.setString(1,"Tom");}……利用输入参数:
CREATEPROCEDURE[dbo].[sp_insertStudent](@namechar(10),@ageint,@idintOUTPUT)ASinsertintoStudents([Name],[Age])values(@name,@age)select@id=@@IDENTITYGO
try{pstmt=con.prepareCall("{callsp_insertStudent(?,?,?)}");pstmt.setString(1,"zengqingsong");pstmt.setInt(2,22);
pstmt.registerOutParameter(3,Types.INTEGER);pstmt.executeUpdate();
intid=pstmt.getInt(3);System.out.println(id);}利用前往参数的例子:
CREATEPROCEDURE[dbo].[sp_insertStudent](@namechar(10),@ageint,@idintOUTPUT)ASinsertintoStudents([Name],[Age])values(@name,@age)select@id=@@IDENTITY–测试输入参数return30–测试前往30GO
try{pstmt=con.prepareCall("{?=callsp_insertStudent(?,?,?)}");pstmt.setString(2,"zengqingsong");pstmt.setInt(3,22);
pstmt.registerOutParameter(4,Types.INTEGER);pstmt.registerOutParameter(1,Types.INTEGER);intret=pstmt.executeUpdate();//实行影响的行数
intret2=pstmt.getInt(1);//前往参数(输入参数)intid=pstmt.getInt(4);//输入参数System.out.println(ret);System.out.println(ret2);System.out.println(id);}
最初被命名为Oak,目标设定在家用电器等小型系统的编程语言,来解决诸如电视机、电话、闹钟、烤面包机等家用电器的控制和通讯问题。
作者:
乐观
时间:
2015-1-21 16:17
是一种将安全性(Security)列为第一优先考虑的语言
作者:
冷月葬花魂
时间:
2015-1-30 20:59
在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。
作者:
海妖
时间:
2015-2-2 21:51
有时间再研究一下MVC结构(把Model-View-Control分离开的设计思想)
作者:
老尸
时间:
2015-2-12 09:53
Java 编程语言的风格十分接近C、C++语言。
作者:
谁可相欹
时间:
2015-2-16 02:06
学Java必读的两个开源程序就是Jive和Pet Store.。 Jive是国外一个非常著名的BBS程序,完全开放源码。论坛的设计采用了很多先进的技术,如Cache、用户认证、Filter、XML等,而且论坛完全屏蔽了对数据库的访问,可以很轻易的在不同数据库中移植。论坛还有方便的安装和管理程序,这是我们平时编程时容易忽略的一部份(中国程序员一般只注重编程的技术含量,却完全不考虑用户的感受,这就是我们与国外软件的差距所在)。
作者:
因胸联盟
时间:
2015-2-20 04:41
是一种突破用户端机器环境和CPU
作者:
活着的死人
时间:
2015-3-1 04:28
Java自面世后就非常流行,发展迅速,对C++语言形成了有力冲击。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台
作者:
蒙在股里
时间:
2015-3-3 11:42
多重继承(以接口取代)等特性,增加了垃圾回收器功能用于回收不再被引用的对象所占据的内存空间,使得程序员不用再为内存管理而担忧。在 Java 1.5 版本中,Java 又引入了泛型编程(Generic Programming)、类型安全的枚举、不定长参数和自动装/拆箱等语言特性。
作者:
莫相离
时间:
2015-3-11 10:30
学Java必读的两个开源程序就是Jive和Pet Store.。 Jive是国外一个非常著名的BBS程序,完全开放源码。论坛的设计采用了很多先进的技术,如Cache、用户认证、Filter、XML等,而且论坛完全屏蔽了对数据库的访问,可以很轻易的在不同数据库中移植。论坛还有方便的安装和管理程序,这是我们平时编程时容易忽略的一部份(中国程序员一般只注重编程的技术含量,却完全不考虑用户的感受,这就是我们与国外软件的差距所在)。
作者:
金色的骷髅
时间:
2015-3-18 05:33
你一定会高兴地说,哈哈,原来成为Java高手就这么简单啊!记得Tomjava也曾碰到过一个项目经理,号称Java很简单,只要三个月就可以学会。
作者:
小魔女
时间:
2015-3-19 05:26
在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。
作者:
兰色精灵
时间:
2015-4-6 10:39
有时间再研究一下MVC结构(把Model-View-Control分离开的设计思想)
作者:
小女巫
时间:
2015-4-11 06:09
学Java必读的两个开源程序就是Jive和Pet Store.。 Jive是国外一个非常著名的BBS程序,完全开放源码。论坛的设计采用了很多先进的技术,如Cache、用户认证、Filter、XML等,而且论坛完全屏蔽了对数据库的访问,可以很轻易的在不同数据库中移植。论坛还有方便的安装和管理程序,这是我们平时编程时容易忽略的一部份(中国程序员一般只注重编程的技术含量,却完全不考虑用户的感受,这就是我们与国外软件的差距所在)。
作者:
若天明
时间:
2015-4-26 11:13
象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。
作者:
若相依
时间:
2015-4-28 02:46
你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。
作者:
灵魂腐蚀
时间:
2015-5-6 03:12
是一种突破用户端机器环境和CPU
作者:
飘灵儿
时间:
2015-5-6 08:09
一直感觉JAVA很大,很杂,找不到学习方向,前两天在网上找到了这篇文章,感觉不错,给没有方向的我指了一个方向,先不管对不对,做下来再说。
作者:
柔情似水
时间:
2015-6-4 22:03
应用在电视机、电话、闹钟、烤面包机等家用电器的控制和通信。由于这些智能化家电的市场需求没有预期的高,Sun公司放弃了该项计划。随着1990年代互联网的发展
欢迎光临 仓酷云 (http://ckuyun.com/)
Powered by Discuz! X3.2