唤醒状态

Stay hungry,stay foolish!

导航

JDBC连接

工作好久了,突然涉及到数据源开发,一下子懵逼了,后来查资料,才得以完成工作,今天过来记录以下:

1.首先来了解以下JDBC

JDBC全称:Java Database Connection

sun公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的接口的规范,这样各个数据库厂商可以自己定义自己的实现

2.JDBC入门案例

package com.jdbc;

import com.mysql.jdbc.Driver;

import java.sql.*;

/**
 * jdbc的几个步骤
 * 1.注册驱动
 * 2.获取连接
 * 3.获取发送sql的对象
 * 4.处理结果
 * 5.关闭资源
 * */
public class JDBC {
    public void demo1() throws SQLException {
        //注册驱动
        DriverManager.registerDriver(new Driver());
        //获取连接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/user","root","root");
        //获取发送sql的对象(这里涉及到两个可选对象Statement/PreparedStatement)
        Statement stat = conn.createStatement();
        //处理结果
        ResultSet rs = stat.executeQuery("select * from user ");
        while(rs.next()){
            System.out.println(rs.getInt("id") + "--" + rs.getString("name"));
        }
        //关闭资源
        rs.close();
        stat.close();
        conn.close();
    }

    public static void main(String[] args) throws SQLException {
        new JDBC().demo1();
    }
}

3、我们先来分析一下上面的程序

JDBC中DriverManager用于加载驱动、并创建与数据库的链接

我们在代码上述代码中使用了

//注册驱动
DriverManager.registerDriver(new Driver());
这里的new Driver()是mysql的驱动jar包,但是很少有人会这么写,为啥?
请看下面的分析!
package com.mysql.jdbc;

import java.sql.DriverManager;
import java.sql.SQLException;

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

    static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}

看到红色的代码吗?这是刚刚进入那个new Driver()看到的mysql的驱动类的代码,这里面又进行注册了一遍了

 

所以一般我们都会使用Class.forName("com.mysql.jdbc.Driver")来加载驱动类

我们来看看一个完整的案例:

 public void demo2() throws ClassNotFoundException, SQLException {
        //注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //获取连接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/user","root","root");
        //获取发送sql的对象
        Statement stat = conn.createStatement();
        //row受影响的行数
        int row = stat.executeUpdate("insert into user(id,name) values(32000,'hello')");
        if(row > 0){
            System.out.println("受影响的行数: " + row);
        }
        //关闭资源,资源一定要从后往前关,至于原因自己想想
        stat.close();
        conn.close();
    }

4、我们再来分析一下Statement,前面的demo1我们使用了executeQuery,demo2使用了executeUpdate方法

相信都看出来了,第一个方法(executeQuery)是用来查询用的,executeUpdate方法是用来执行增删改的,当然还有一个综合方法execute方法,我们看下面的示例:

public void demo3() throws ClassNotFoundException, SQLException {
        //注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //获取连接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/user","root","root");
        //获取发送sql的对象
        Statement stat = conn.createStatement();
        //如果是true就相当于执行的executeQuery反之就是executeUpdate
        boolean e = stat.execute("update user set name='信息' where id = 1");
        ResultSet rs = null;
        if(e){
            rs = stat.getResultSet();
            while(rs.next()){
                System.out.println(rs.getInt("id") + "---" + rs.getString("name"));
            }
        } else {
            int row = stat.getUpdateCount();
            System.out.println("受影响的行数: " + row);
        }
        //关闭资源
        if(null != rs){
            rs.close();
        }
        if(null != stat){
            stat.close();
        }
        if(null != conn){
            conn.close();
        }
    }

5、前面每次都要写数据连接的重复代码以及关闭资源的操作,下面我们将其封装

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JDBCUtils {
    private static String url;
    private static String username;
    private static String password;
    private static String driver;
    static {
        Properties properties = new Properties();
        InputStream in = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
        try {
            properties.load(in);
            url = (String) properties.get("url");
            username = (String) properties.get("username");
            password = (String) properties.get("password");
            driver = (String) properties.get("driver");
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    public static Connection getConnection(){
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url,username,password);
        }catch (Exception e){
            e.printStackTrace();
        }
        return conn;
    }

    public static void releaseResource(ResultSet rs,Statement stat,Connection conn){
        try {
            if(null != rs){
                rs.close();
            }
            rs = null;//将对象置为null,GC回收
            if(null != stat){
                stat.close();
            }
            stat = null;
            if(null != conn){
                conn.close();
            }
            conn = null;
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void releaseResource(ResultSet rs, PreparedStatement ps,Connection conn){
        try {
            if(null != rs){
                rs.close();
            }
            rs = null;
            if(null != ps){
                ps.close();
            }
            ps = null;
            if(null != conn){
                conn.close();
            }
            conn = null;
        }catch (Exception e){
            e.printStackTrace();
        }
    }

6、下面我们用用我们的工具类以及使用另外一个PreparedStatement,为什么用PreparedStatement呢?因为可以防止SQL注入的问题啦

  public void demo4() throws SQLException {
        Connection conn = JDBCUtils.getConnection();
        //这里使用了PrepareStatement
        PreparedStatement ps = conn.prepareStatement("update user set name=? where id = ?");
        ps.setString(1,"你好");
        ps.setInt(2,1);
        int row = ps.executeUpdate();
        if(row > 0){//使用工具类一下子代码精简了很多
            System.out.println("受影响的行数: " + row);
        }
    }

7、下面是批处理的示例

/**
     * 下面是一个批处理的示例
     *
     * */
    public void demo5() throws SQLException {
        Connection conn = JDBCUtils.getConnection();
        PreparedStatement ps = conn.prepareStatement("insert into user (id,name) values (?,?)");
        for(int i = 1;i <= 10000;i++){
            ps.setInt(1,i);
            ps.setString(2,i+"");
            ps.addBatch();
            if(i % 500 == 0){
                ps.executeBatch();
                ps.clearBatch();
            }
        }
        JDBCUtils.releaseResource(null,ps,conn);
    }

8、下面是一个完整的事务控制的示例

/**
     * 完整的jdbc示例
     *
     *
     * */
    public void demo6(){
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JDBCUtils.getConnection();
            //开启事务
            conn.setAutoCommit(false);
            ps = conn.prepareStatement("update user set name=? where id = ?");
            ps.setString(1,"kkk");
            ps.setInt(2,1);
            int rows = ps.executeUpdate();
            conn.commit();
            if(rows > 0){
                System.out.println("受影响的行数: " + rows);
            }
        }catch (Exception e){
            e.printStackTrace();
        } finally {
            JDBCUtils.releaseResource(rs,ps,conn);
        }
    }

 

posted on 2019-05-17 00:49  唤醒状态  阅读(236)  评论(0)    收藏  举报