java数据库连接

本文以mysql数据库为例

一:Java访问数据库的具体步骤:

1.加载(注册)数据库

Class.forName("com.mysql.jdbc.Driver").newInstance(); 

2.建立链接

java.sql.DriverManager类中有三种获取数据库连接的方法,虽说是三种,但是获取链接的方法是大同小异的,方法中都是通过return (getConnection(url, info, Reflection.getCallerClass()))语句来返回一个Connection:
1.getConnection(String url,java.util.Properties info)
参数说明:
url: 数据库url,例如jdbc:mysql://localhost:3306/media2
info: 一个Properties 至少包括”user” and “password”

2.getConnection(String url,String user, String password):
参数说明:
url: 数据库url,例如jdbc:mysql://localhost:3306/media2
user:数据库用户名
password:数据库密码

3.getConnection(String url):
参数说明:
url:数据库url,例如jdbc:mysql://localhost:3306/media2?user=root&password=123456&useUnicode=true&characterEncoding=gb2312*/

3.执行SQL语句和处理结果集

可以通过创建Statement对象或者PreparedStatement对象两种方式来执行SQL语句。
首先来讲述一下这两个对象的区别:
1.PreparedStatement是预编译的,对于批量处理可以大大提高效率.也叫JDBC存储过程,通过set不同数据只需要生成一次执行计划,可以重用。
而Statement处理两次相似操作必须执行两条sql语句。
例如:

PreparedStatement pst = null;//代码中需要添加try-catch,这里为了演示效果未添加,可参考下面给出的完整代码。
String sql="select * from fuser where name = ? and email = ?";
pst = connection.prepareStatement(sql);
pst.setString(1, "4");
pst.setString(2, "4@qq.com");

2.PreparedStatement对象的开销比Statement大,对于一次性操作并不会带来额外的好处,所以综合第一点:在对数据库只执行一次性存取的时侯,它应该和普通的对象毫无差异,体现不出它预编译的优越性。此时使用 Statement 对象进行处理较为方便。

3.prepareStatement会先初始化SQL,先把这个SQL提交到数据库中进行预处理,多次使用可提高效率。
createStatement不会初始化,没有预处理,每次都是从0开始执行SQL。

4.安全性:
prepareStatement相比于Statement更加安全,比如一个简单的查询,当我们输入用户名为[’ or ‘1’ = ‘1]时,传入的任何内容就不会和原来的语句发生任何匹配的关系,因此也不会执行。

String sql="select * from fuser where email = ? and password = ?";
pst = connection.prepareStatement(sql);
pst.setString(1, "1@qq.com");
//pst.setString(2, "xMpCOKC5I4INzFCab3WEmw==");
pst.setString(2, "' or '1' = '1");

如果使用的是Statement,那是可以查出来的

String email="4@qq.com";
String password = "' or '1' = '1";
String sql = "select * from fuser where email= '"+email+"' and password='"+password+"'";
statement = (Statement) connection.createStatement();
rs = statement.executeQuery(sql);

综上,建议在任何时候都使用PreparedStatement较好。

附上此段代码:

package com.v512.mysql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import com.mysql.jdbc.Statement;

public class Test {
    public static Connection getconn(){
/*1 加载(注册)数据库 驱动加载就是把各个数据库提供的访问数据库的API加载到我们程序进来,加载JDBC驱动,并将其注册到DriverManager中,每一种数据库提供的数据库驱动不一样,*/
        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
        } catch (InstantiationException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IllegalAccessException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (ClassNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        //2 建立链接 
        Connection conn = null;
        try {
/*3种获取connection的方法:
1.getConnection(String url,java.util.Properties info)
参数说明:
url: 数据库url,例如jdbc:mysql://localhost:3306/media2
info: 一个Properties 至少包括"user" and "password"
2.getConnection(String url,String user, String password):传入数据库名,用户名,密码
参数说明:
url: 数据库url,例如jdbc:mysql://localhost:3306/media2
user:数据库用户名
password:数据库密码
3.getConnection(String url):直接传入URL
参数说明:
url:数据库url,例如jdbc:mysql://localhost:3306/media2?user=root&password=123456&useUnicode=true&characterEncoding=gb2312*/
            Properties properties = new Properties();
            properties.put("user", "root");
            properties.put("password", "123456");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/media2", properties);
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/media2", "root","123456");
            String url="jdbc:mysql://localhost:3306/media2?user=root&password=123456&useUnicode=true&characterEncoding=gb2312";
            conn=DriverManager.getConnection(url);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return conn;
    }
    public static void main(String[] args) {
/*3. 执行SQL语句
数据库连接建立好之后,接下来就是一些准备工作和执行sql语句了,
准备工作要做的就是建立Statement对象PreparedStatement对象,例如:*/

        //1.使用Statement对象
/*      Connection connection = getconn();
        PreparedStatement pst = null;
        ResultSet rs = null;
        try {
            String sql="select * from fuser where name = ? and email = ?";
            pst = connection.prepareStatement(sql);
            pst.setString(1, "4");
            pst.setString(2, "4@qq.com");
            rs = pst.executeQuery();
            if(rs.next()){
                int id = rs.getInt("id");
                System.out.println("id:"+id);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                rs.close();
                pst.close();
                connection.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }*/

        //2.使用PreparedStatement对象
/*      Connection connection = getconn();
        ResultSet rs = null;
        Statement statement = null;
        try {
            String sql="select * from fuser where name = '4' and email = '4@qq.com' ";
            statement = (Statement) connection.createStatement();
            rs = statement.executeQuery(sql);
            if(rs.next()){
                int id = rs.getInt("id");
                System.out.println("id:"+id);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                rs.close();
                statement.close();
                connection.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }*/

        //PreparedStatement对比Statement安全性问题
        //使用PreparedStatement
/*      Connection connection = getconn();
        PreparedStatement pst = null;
        pst.executeQuery()
        pst.execute()
        ResultSet rs = null;
        try {
            String sql="select * from fuser where email = ? and password = ?";
            pst = connection.prepareStatement(sql);
            pst.setString(1, "1@qq.com");
            //pst.setString(2, "xMpCOKC5I4INzFCab3WEmw==");
            pst.setString(2, "' or '1' = '1");
            rs = pst.executeQuery();
            if(rs.next()){
                int id = rs.getInt("id");
                System.out.println("id:"+id);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                rs.close();
                pst.close();
                connection.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }*/

        //使用Statement
/*      Connection connection = getconn();
        ResultSet rs = null;
        Statement statement = null;
        try {
            String email="4@qq.com";
            String password = "' or '1' = '1";
            String sql = "select * from fuser where email= '"+email+"' and password='"+password+"'";
            statement = (Statement) connection.createStatement();
            rs = statement.executeQuery(sql);
            if(rs.next()){
                int id = rs.getInt("id");
                System.out.println("id:"+id);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                rs.close();
                statement.close();
                connection.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }*/ 
    }
}

这是我测试用的数据表:
数据表

二、数据库连接池

对于大多数应用程序,当它们正在处理通常需要数毫秒完成的事务时,仅需要能够访问JDBC连接的 1 个线程。当不处理事务时,这个连接就会闲置。相反,连接池允许闲置的连接被其它需要的线程使用。
事实上,当一个线程需要用 JDBC 对一个 GBase 或其它数据库操作时,它从池中请求一个连接。当这个线程使用完了这个连接,将它返回到连接池中,这样这就可以被其它想使用它的线程使用。
当连接从池中“借出”,它被请求它的线程专有地使用。从编程的角度来看,这和用户的线程每当需要一个 JDBC 连接的时候调用DriverManager.getConnection() 是一样的,采用连接池技术,可通过使用新的或已有的连接结束线程。

常用的连接池有以下这些:DBCP 连接、C3P0 连接、JndI与 Tomact 连接池,C3PO 连接池是一个优秀的连接池,推荐使用,但并说明其他连接池不好,只是各有优点, C3P0 能够更好的支持高并发,但是在稳定性方面略逊于DBCP 。这里我就主要介绍一下C3P0的使用:

1.需要导入的Jar包:
c3p0需要导入c3p0.jar、mchange-commons-.jar,如果操作的是Oracle数据库,还需要导入c3p0-oracle-thin-extras-pre1.jar。
下载地址:http://download.csdn.net/detail/loverestart/9841162

2.修改配置文件(配置文件也放在上述资源中了):
修改可参考下图
这里写图片描述

3.JdbcUtils类:
我们需要通过这个类来获取数据库连接或者释放连接,方法说明类中有了我就不重复了。

package com.v512.util;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class JdbcUtils {
       /**
        * 释放连接
        * @param connection
        */
       public static void releaseConnection(Connection connection){
              try {
                     if(connection != null ) {
                            connection.close();
                     }
              }catch (Exception e) {
                     e.printStackTrace();
              }
       }
       private static DataSource dataSource = null;
       static{
              //dataSource资源只能初始化一次
              dataSource= new ComboPooledDataSource("mvcApp");
       }
       /**
        * 获取连接
        * @return
        * @throws SQLException
        */
       public static Connection getConnection() throws SQLException{
              return dataSource.getConnection();
       }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值