数据库连接可以说是学习web最基础的部分,也是非常重要的一部分,今天我们就来介绍下数据库的连接为下面学习真正的web打下基础

java中连接数据库一般有两种方式:

1.ODBC——Open Database Connectivity(开放数据库连接性):基于C语言的一套数据库编程接口,主要功能是提供数据库的访问和操作
所有的数据库厂商对这套接口进行实现,不同数据库厂商提供的实现是不一样的,也就是通常所说的第三方支持,而这套编程接口就是我们的标准

2.JDBC——Java Database Connectivity(java版的ODBC)
专门为java语言提供的一套访问操作数据库的编程标准,由sun公司提供,所有可以被java语言操作的数据库厂商都对其进行了实现

我们一般都是采用JDBC,优势:

1.效率上jdbc会相对的高一些

2.安全角度来考虑,jdbc比odbc高

3.jdbc使用非常方便,只要加入相应的驱动包就可以了,而不像odbc还需要Jdbc-odbc桥驱动

4.使用jdbc可以很方便在各类数据库间进行更换,只要更改相应的驱动就可以了

下面列举用jdbc连接各类数据库的方式:

  1. 常用JDBC连接数据库方法总结如下:
  2.  
  3. 一、JDBC连接DB2
  4. Class.forName("Com.ibm.db2.jdbc.net.DB2Driver");
  5. String url="jdbc:db2://dburl:port/DBname"
  6. cn = DriverManager.getConnection( url, sUsr, sPwd );
  7.  
  8. 二、JDBC连接Microsoft SQLServer(microsoft)
  9. Class.forName( "com.microsoft.jdbc.sqlserver.SQLServerDriver" );
  10. cn = DriverManager.getConnection( "jdbc:microsoft:sqlserver://DBServerIP:1433;databaseName=master", sUsr, sPwd );
  11.  
  12. 三、JDBC连接Sybase(jconn2.jar)
  13. Class.forName( "com.sybase.jdbc2.jdbc.SybDriver" );
  14. cn = DriverManager.getConnection( "jdbc:sybase:Tds:DBServerIP:2638", sUsr, sPwd );
  15.  
  16. 四、JDBC连接MySQL(mm.mysql-3.0.2-bin.jar)
  17. Class.forName( "org.gjt.mm.mysql.Driver" );
  18. cn = DriverManager.getConnection( "jdbc:mysql://DBServerIP:3306/myDatabaseName", sUsr, sPwd );
  19.  
  20. 五、JDBC连接PostgreSQL(pgjdbc2.jar)
  21. Class.forName( "org.postgresql.Driver" );
  22. cn = DriverManager.getConnection( "jdbc:postgresql://DBServerIP/myDatabaseName", sUsr, sPwd );
  23.  
  24. 六、JDBC连接Oracle(classes12.jar)
  25. Class.forName( "oracle.jdbc.driver.OracleDriver" );
  26. cn = DriverManager.getConnection( "jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL", sUsr, sPwd );
  27.  
  28. 七、JDBC连接ODBC
  29. Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );
  30. Connection cn = DriverManager.getConnection( "jdbc:odbc:" + sDsn, sUsr, sPwd );

下面我以Microsoft SQLServer 2000为例进行数据库连接的讲解,我们在连接前先将jar包放到项目的lib目录下,这里我们只需jtds-1.2.5.jar

下面我们先来看一段完整连接数据库代码:

  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5.  
  6. public class JdbcTest {
  7. //数据库的连接驱动,一般是不需要变的
  8. private static final String DRIVER="com.microsoft.jdbc.sqlserver.SQLServerDriver";
  9. //数据库连接的URL,1433为默认的数据库端口号,test为当前你要操作的数据库名
  10. private static final String URL="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=test";
  11. //登录账户
  12. private static final String DBNAME="sa";
  13. //登录的密码
  14. private static final String DBPASS="123";
  15.  
  16. public void test(){
  17. Connection con=null;
  18. PreparedStatement psm=null;
  19. ResultSet rs=null;
  20. try{
  21. Class.forName(DRIVER);
  22. con = DriverManager.getConnection(URL,DBNAME,DBPASS);
  23. String sql="select* from admin where id=1";
  24. psm=con.prepareStatement(sql);
  25. rs=psm.executeQuery();
  26. while(rs.next()){
  27. System.out.println(rs.getString("aPassword"));
  28. }
  29. }catch(Exception e){
  30. con.close();
  31. rs.close();
  32. psm.close();
  33. e.printStackTrace();
  34. }finally{
  35. if(rs!=null){
  36. rs.close();
  37. }
  38. if(psm==null){
  39. psm.close();
  40. }
  41. if(con!=null){
  42. con.close();
  43. }
  44. }
  45. }
  46.  
  47. }

对于上面的数据库连接查询,我们分6步来进行分析:
a.加载JDBC驱动程序:

在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),这通过java.lang.Class类的静态方法forName(String  className)实现。

如上面代码:Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");  我们在单独进行连接时一般要在进行异常的捕获,即加上try..catch

try{

  Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");

}catch(ClassNotFoundException e){

  System.out.println("找不到驱动程序类 ,加载驱动失败!");

  e.printStackTrace() ;

}

成功加载后,会将Driver类的实例注册到DriverManager类中。

b.提供JDBC连接的URL并进行连接 :

如上面的代码:(也进行异常的捕获)

private static final String URL="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=test";
private static final String DBNAME="sa";
private static final String DBPASS="123";

try{

  con = DriverManager.getConnection(URL,DBNAME,DBPASS);

}catch{
  System.out.println("数据库连接失败");

  e.printStackTrace() ;

}

c.创建一个Statement

  •要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3种类型:

  1.执行静态SQL语句。通常通过Statement实例实现。

  2.执行动态SQL语句。通常通过PreparedStatement实例实现。

  3.执行数据库存储过程。通常通过CallableStatement实例实现。

  具体的实现方式:

  1.Statement stmt = con.createStatement() ;

  2.如上代码:PreparedStatement psm = con.prepareStatement(sql) ;

  3.CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}") ;

d.执行SQL语句

  Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate  和execute

  1.ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句 ,返回一个结果集(ResultSet)对象。

  2.int executeUpdate(String sqlString):用于执行INSERT、UPDATE或DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等

  3.execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的语句。

  具体实现的代码:

  ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;

  int rows = stmt.executeUpdate("INSERT INTO ...") ;

  boolean flag = stmt.execute(String sql) ;

e.处理结果

  两种情况:

  1.执行更新返回的是本次操作影响到的记录数。

  2.执行查询返回的结果是一个ResultSet对象。

  • ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些行中数据的访问。

  • 使用结果集(ResultSet)对象的访问方法获取数据:

  如上例:

    while(rs.next()){
       System.out.println(rs.getString("aPassword"));
      }

  处理结果集还有种方式就是:根据数据库表列的编号(从左到右,第一列为1)如rs.getString(1)表示获取对应表中第一列的数据

f.关闭JDBC对象

   操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声明顺序相反:

  1.关闭记录集

   if(rs!=null){
       rs.close();
     }

  2.关闭声明

  if(psm==null){
     psm.close();
     }

  3.关闭连接对象

  if(con!=null){
        con.close();
     }

连接数据库基本结束,里面包含的有些基础方面的知识大家自己回去看看书吧,我这里还提供一个封装好了的数据库连接操作,只需要调用即可

http://www.cnblogs.com/shenliang123/archive/2012/04/19/2456665.html

下次我们将进行数据库操作的实战

注:

java中PreparedStatement和Statement区别

第一:     
    数据库在执行sql语句的时候如果使用PreparedStatement语句会有一点优势:因为数据库会preparedStatement 
语句进行预编译,下次执行相同的sql语句时,数据库端不会再进行预编译了,而直接用数据库的缓冲区,提高数据访问的效率(但尽量尽量采用使用?号的方式传递参数),如果sql语句只执行一次,以后不再复用. 
第二: 
   在JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替Statement.也就是说,在任何时候都不要使用Statement. 基于以下的原因: 
一.代码的可读性和可维护性. 
虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:  
stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");  
perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)"); perstmt.setString(1,var1); perstmt.setString(2,var2); perstmt.setString(3,var3); perstmt.setString(4,var4); perstmt.executeUpdate();

不用我多说,对于第一种方法.别说其他人去读你的代码,就是你自己过一段时间再去读,都会觉得伤心.  
二.PreparedStatement尽最大可能提高性能. 
每一种数据库都会尽最大努力对预编译语句提供最大的性能优化.因为预编译语句有可能被重复调用.所以语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行.这并不是说只有一个Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹配.那么在任何时候就可以不需要再次编译而可以直接执行.而statement的语句中,即使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配.比如: insert into tb_name (col1,col2) values ('11','22'); insert into tb_name (col1,col2) values ('11','23'); 
即使是相同操作但因为数据内容不一样,所以整个个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存.  
当然并不是所以预编译语句都一定会被缓存,数据库本身会用一种策略,比如使用频度等因素来决定什么时候不再缓存已有的预编译结果.以保存有更多的空间存储新的预编译语句.  
三.最重要的一点是极大地提高了安全性. (sql注入) 

String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'"; 
如果我们把[' or '1' = '1]作为varpasswd传入进来.用户名随意,看看会成为什么?  
select * from tb_name = '随意' and passwd = '' or '1' = '1'; 因为'1'='1'肯定成立,所以可以任何通过验证.更有甚者: 把[';drop table tb_name;]作为varpasswd传入进来,则: 
select * from tb_name = '随意' and passwd = '';drop table tb_name;有些数据库是不会让你成功的,但也有很多数据库就可以使这些语句得到执行.  
而如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系.只要全使用预编译语句,你就用不着对传入的数据做任何过虑.而如果使用普通的statement,有可能要对drop,;等做费尽心机的判断和过虑.

java入门第三步之数据库连接【转】的更多相关文章

  1. java入门第三步之数据库连接

    数据库连接可以说是学习web最基础的部分,也是非常重要的一部分,今天我们就来介绍下数据库的连接为下面学习真正的web打下基础 java中连接数据库一般有两种方式: 1.ODBC——Open Datab ...

  2. java入门第五步之数据库项目实战【转】

    在真正进入代码编写前些进行一些工具的准备: 1.保证有一个可用的数据库,这里我用sql server 2000为例,2.拥有一个ide,如ecelise或myeclipse等,这里我使用的是myecl ...

  3. java入门第四步之应用服务器的安装(Tomcat)【转】

    首先打开myeclipse,在myeclipse菜单栏下面有两个按钮: 左边的按钮是进行项目的部署的(即将项目部署到服务器上),右边的按钮是进行服务器的启动的,如果你安装了tomcat服务器,那你就可 ...

  4. Java基础:三步学会Java Socket编程

    Java基础:三步学会Java Socket编程 http://tech.163.com 2006-04-10 09:17:18 来源: java-cn 网友评论11 条 论坛        第一步 ...

  5. jQuery入门第三

    jQuery入门第三 1.HTML 2.CSS 衣服 3.javascript 可以动的人 4.DOM 编程 对html文档的节点操作 5.jQuery 对 javascript的封装 简练的语法 复 ...

  6. 第二节:Java入门第一行代码

    前言 大家好,今天带来Java入门第一行代码的概述,希望你们喜欢 第一行代码 学习Java基础课程,学会使用eclipse,eclipse为Java集成开发坏境IDE,创建第一个Java源文件代码: ...

  7. JavaMail入门第三篇 发送邮件

    JavaMail API中定义了一个java.mail.Transport类,它专门用于执行邮件发送任务,这个类的实例对象封装了某种邮件发送协议的底层实施细节,应用程序调用这个类中的方法就可以把Mes ...

  8. DBArtist之Oracle入门第3步: 安装配置PL/SQL Developer

    操作系统:            WINDOWS 7 (64位) 数据库:               Oracle 11gR2 (64位) PL/SQL Developer :    PL/SQL ...

  9. Java线程入门第三篇

    Java内存模型(jmm) Why:保证多线程正确协同工作 看图说明: 文字解释:线程a和线程b通信过程,首先线程a把本地内存的共享变量更新到主内存中,然后线程b去读取主内存的共享变量,最后更新到自己 ...

随机推荐

  1. python_way ,day11 线程,怎么写一个多线程?,队列,生产者消费者模型,线程锁,缓存(memcache,redis)

    python11 1.多线程原理 2.怎么写一个多线程? 3.队列 4.生产者消费者模型 5.线程锁 6.缓存 memcache redis 多线程原理 def f1(arg) print(arg) ...

  2. FLASH CC 2015 CANVAS (七)总结

    FLASH CC 2015 CANVAS (一至七)确切来说是自己在摸索学习过程中而写.所以定为“开荒教程”. 去年年底转战H5,半年中一直非常忙也不敢用CC来做项目,担心有BUG或者无法实现需求,所 ...

  3. 如何让div上下左右都居中

    在做登陆页面的话,需要login的div 上下左右都居中. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ...

  4. 利用JDK的中Proxy动态代理实现Spring的AOP技术

    首先给出设计模式静态代理与动态代理的学习: http://layznet.iteye.com/blog/1182924   讲的不错 然后我们实现AOP 就要求我们对委托的所有方法的调用实现拦截 代理 ...

  5. Ext.net 异常统一管理,铥掉可恶的 Request Failure

    Ext.net 异常统一管理,铥掉可恶的 Request Failure 看着这样的框框是不是很不爽 灭他.也不难.. .如果全部页面都有继承一个自定义的父类 ..那整个项目代码量就只有几行了.. 单 ...

  6. HTTP refere

    什么是 http refere ? 简言之,放在web浏览器的header上的 当我通过我的主页访问我朋友的网站时,就可以获得refere , 可以获取网页访问流量,也可以防盗链 一般 referer ...

  7. [转载] ORMs under the hood

    原文: http://www.vertabelo.com/blog/technical-articles/orms-under-the-hood It often happens that if so ...

  8. poj2420A Star not a Tree?(模拟退火)

    链接 求某一点到其它点距离和最小,求这个和,这个点 为费马点. 做法:模拟退火 #include <iostream> #include<cstdio> #include< ...

  9. mysql 变量

    用户变量 1.用户变量,用户变量和数据库连接有关,连接后声明变量,连接断开后,自动消失. 2.用户变量以@开头,select一个没有赋值的用户变量,返回NULL,也就是没有值,注意取值为NULL与取值 ...

  10. 转:随机函数 C++中rand()函数的用法

    转自:http://blog.163.com/wujiaxing009@126/blog/static/719883992011113011359154/ 一.C++中不能使用random()函数   ...