码迷,mamicode.com
首页 > 数据库 > 详细

JDBC二

时间:2018-09-16 19:43:35      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:rac   程序   demo   编写   创建   ati   array   value   .data   

1 批处理

  • 通过降低和数据库的连接次数,来提高效率。

 

  • 示例:
@Test
    public void test() throws Exception {
        //加载驱动
        Class.forName("com.mysql.jdbc.Driver");

        String url = "jdbc:mysql://localhost:3306/test";
        String user = "root";
        String password = "123456";

        //获取连接
        Connection connection = DriverManager.getConnection(url, user, password);

        String sql = " insert into user(name) values(?)";


        PreparedStatement pstmt = connection.prepareStatement(sql);

        for (int i = 0; i < 10; i++) {
            pstmt.setString(1,"许威威"+i);
            pstmt.addBatch();
        }

        pstmt.executeBatch();

        pstmt.close();
        connection.close();
    }

 

  • 示例:
@Test
    public void test() throws Exception {
        //加载驱动
        Class.forName("com.mysql.jdbc.Driver");

        String url = "jdbc:mysql://localhost:3306/test";
        String user = "root";
        String password = "123456";

        //获取连接
        Connection connection = DriverManager.getConnection(url, user, password);

        String sql = " insert into user(name) values(?)";


        PreparedStatement pstmt = connection.prepareStatement(sql);

        for (int i = 0; i < 10000; i++) {
            pstmt.setString(1,"许威威"+i);
            
            if(i % 1000 ==0){
                pstmt.addBatch();
                pstmt.clearBatch();
            }
        }
        pstmt.executeBatch();

        pstmt.close();
        connection.close();
    }

 

2 调用存储过程

delimiter $
create procedure proc(IN num int ,out name VARCHAR(20))
BEGIN
  SELECT `user`.`name` into name from user where `user`.id = num ;
end $

 

  • 示例:
package com.xuweiwei;

import org.junit.Test;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Types;

public class jdbc2 {

    @Test
    public void test() throws Exception {
        //加载驱动
        Class.forName("com.mysql.jdbc.Driver");

        String url = "jdbc:mysql://localhost:3306/test";
        String user = "root";
        String password = "123456";

        //获取连接
        Connection connection = DriverManager.getConnection(url, user, password);


        CallableStatement callableStatement = connection.prepareCall(" { call proc(?,?)}  ");

        callableStatement.setInt(1,1);
        callableStatement.registerOutParameter(2, Types.VARBINARY);

        callableStatement.execute();

        String string = callableStatement.getString(2);
        System.out.println(string);


        connection.close();
    }
}

 

3 数据库连接池的原理

3.1 应用程序直接获取连接的缺点

技术分享图片

  • 缺点:用户每次请求都需要向数据库获取连接,而数据库创建连接通常需要消耗相对比较大的资源,创建的时间也比较长。假设一个网站一天的访问量是10万,数据库服务器就需要至少创建10万次的连接,极大的浪费了数据库的资源,并且非常容易造成数据库服务器内存溢出,严重甚至会宕机。

技术分享图片

  • 示例:模拟连接池的原理
package com.xuweiwei.pool;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class ConnectionPoolDemo {
    //内置一个连接池
    private static List<Connection> pool = new ArrayList<>();

    static {
        for (int i = 0; i < 10; i++) {
            //加载驱动
            try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

            String url = "jdbc:mysql://localhost:3306/test";
            String user = "root";
            String password = "123456";
            //获取连接
            try {
                Connection conn = DriverManager.getConnection(url, user, password);
                pool.add(conn);
            } catch (SQLException e) {
                e.printStackTrace();
            }


        }
    }

    /**
     * 从连接池中获取一个连接
     *
     * @return
     */
    public synchronized static Connection getConnection() {
        if (pool.size() > 0) {
            return pool.remove(0);
        } else {
            throw new RuntimeException("服务器真忙");
        }
    }

    /**
     * 将连接还到连接池里
     *
     * @param connection
     */
    public synchronized static void release(Connection connection) {
        pool.add(connection);
    }


}

3.2 编写标准的连接池

  • 自定义Java类去实现java.sql.DataSource接口即可。

 

  • 示例:
package com.xuweiwei.pool;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;

public class MyDataSource1 implements DataSource {

    //内置一个连接池
    private static List<Connection> pool = Collections.synchronizedList(new ArrayList<>());

    static {
        for (int i = 0; i < 20; i++) {
            //加载驱动
            try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

            String url = "jdbc:mysql://localhost:3306/test";
            String user = "root";
            String password = "123456";
            //获取连接
            try {
                Connection conn = DriverManager.getConnection(url, user, password);
                pool.add(conn);
            } catch (SQLException e) {
                e.printStackTrace();
            }


        }
    }

    /**
     * 从池子里获取连接
     * @return
     * @throws SQLException
     */
    @Override
    public Connection getConnection() throws SQLException {
        if(null != pool && pool.size() > 0){
            return pool.remove(0);
        }else{
            throw new RuntimeException("服务器正忙");
        }
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
}
  • 但是,这样还是有问题的,一般用户调用Connection.close()方法,会把连接关闭,这样就失去了连接池的意义。
  • 使用装饰模式来改写close()方法。

 

JDBC二

标签:rac   程序   demo   编写   创建   ati   array   value   .data   

原文地址:https://www.cnblogs.com/xuweiweiwoaini/p/9656920.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!