• 22Java之JDBCTemplate总结


    写在前面:这里总结4种方式来操作数据库(SE阶段)

    一、JDBC

            JDBC有关的类:都在java.sql 和 javax.sql 包下.
     

            1.数据准备

                    这里假设已经在数据库中新建立了mydb4数据库,并且也插入了一些数据,
                    并且还需要导入一个jar包mysql-connector-java-8.0.11.jar(可从官网下载)

            2.JDBC 编程步骤

                    步骤1:装载驱动    DriverManager.registerDriver(new Driver());   
                                tips:在装载驱动的时候推荐使用Class.forName(“com.mysql.jdbc.Driver”);
                                         一、查看Driver的源代码可以看到,如果采用此种方式,会导致驱动程序注册两次,也就是在内存中会有两个Driver对象。
                                         二、程序依赖mysql的api,脱离mysql的jar包,程序将无法编译,将来程序切换底层数据库将会非常麻烦。
                    步骤2:建立连接    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb4", "root", "111");
                                tips:MySQL驱动 8 版本之后关于driverClass 与 url 参数的书写变化 :
    com.mysql.cj.jdbc.Driver
    jdbc:mysql://localhost:3306/day04?serverTimezone=UTC&characterEncoding=utf-8
     
                    步骤3:操作数据库
                                        Statement statement = conn.createStatement();
    ResultSet rs = statement.executeQuery(sql);
    while (rs.next()) {
     System.out.println(rs.getString("username"));
     System.out.println(rs.getString("email"));
    }
     
                    步骤4:释放资源

    rs.close();

    statement.close();

    conn.close();

            3.一步到位的操作方式(更加面向对象&&解决SQL注入问题):

                        将重复的内容 提取到JDBCUtils工具类中:
                      
                        这里提供两种版本分别是硬编码和软编码
     
                        硬编码(信息写入到程序中):
    JDBCUtils工具类
    <wiz_code_mirror>
     
     
     
     
     
    public class JDBCUtils {
     
        private static final String driverClass = "com.mysql.cj.jdbc.Driver";
        // 当时本地默认3306 可以省略,也可写成 "jdbc:mysql://localhost:3306/mydb4?severTimezone=UTC&characterEncoding=utf-8"
        private static final String url = "jdbc:mysql:///mydb4?serverTimezone=UTC&character=utf-8";        
        private static final String user = "root";
        private static final String password = "111";
     
        // 加载驱动
        public static void loadDriver() {
            // 1. 加载驱动
            try {
                Class.forName(driverClass);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                throw new RuntimeException("驱动加载失败!");
            }
        }
     
        // 获取连接
        public static Connection getConnection() throws SQLException {
            Connection conn = DriverManager.getConnection(url, user, password);
            return conn;
        }
     
        // 释放资源
        public static void release(Connection conn, Statement stmt, ResultSet rs) {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                rs = null;
            }
            release(conn, stmt);
        }
     
        public static void release(Connection conn, Statement stmt) {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                stmt = null;
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                conn = null;
            }
        }
    }
     
     
    测试类
    <wiz_code_mirror>
     
     
     
     
     
        @Test
        public void test_query() {
            // 1. 加载驱动
            JDBCUtils.loadDriver();
     
            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;
     
            try {
                // 2. 建立连接
                conn = JDBCUtils.getConnection();
                // 3. 操作数据
                String sql = "select * from user;";
                // 这里有可能引起sql注入问题,换成prepareStatement(sql)
                stmt = conn.createStatement();
                rs = stmt.executeQuery(sql);
                while (rs.next()) {
                    String username = rs.getString("username");
                    String password = rs.getString("password");
                    System.out.println(username + " = " + password);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                // 4. 释放资源
                JDBCUtils.release(conn, stmt, rs);
            }
        }
     
     
     
     
                软编码:从配置文件中读取(配置文件名字jdbc.properties)
    <wiz_code_mirror>
     
     
     
     
     
    #配置文件
    #jdbc.properties
    #mysql
    driverClass=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql:///mydb4?serverTimezone=UTC&character=utf-8
    user=root
    passwrod=111
     
     
    <wiz_code_mirror>
     
     
     
     
     
    public class JDBCUtils {
     
        // 属性
        private static String driverClass;
        private static String url;
        private static String username;
        private static String password;
     
        // 请问 : 什么时候加载外部配置文件最合适 ???   
        // 特点1 : 随着类的加载而加载.
        // 特点2 : 静态代码块只在类加载的被执行一次. 仅一次.
        static {
            Properties prop = new Properties();
     
            try {
                prop.load(new FileReader("jdbc.properties")); // 这里直接放在项目的目录下,具体要切合实际
     
                // 如果程序执行到这里, 说明外部资源文件加载成功, 需要给我们的静态属性赋值
                driverClass = prop.getProperty("driverClass");
                url = prop.getProperty("url");
                username = prop.getProperty("username");
                password = prop.getProperty("password");
     
                // 直接执行加载驱动
                loadDriver();
     
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException("文件资源加载失败!");
            }
        }
     
        // 加载驱动
        public static void loadDriver() {
            try {
                // 1. 加载驱动
                Class.forName(driverClass);
            } catch (ClassNotFoundException e) {
                // e.printStackTrace();
                // 驱动加载失败!
                throw new RuntimeException("驱动加载失败!");
            }
        }
     
        // 建立连接
        public static Connection getConnection() throws SQLException {
            // 2. 建立连接
            return DriverManager.getConnection(url, username, password);
        }
     
        // 释放资源
        public static void release(Connection conn, Statement stmt, ResultSet rs) {
            // 4. 释放资源
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                // 将 rs 清空
                rs = null;
            }
            // 直接调用
            release(conn, stmt);
        }
        public static void release(Connection conn, Statement stmt) {
            // 4. 释放资源
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                stmt = null;
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                conn = null;
            }
        }
    }
     
     
    测试类:
    <wiz_code_mirror>
     
     
     
     
     
        @Test
        public void test_query() {
     
            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;
     
            try {
                // 1. 建立连接
                conn = JDBCUtils.getConnection();
                // 2. 操作数据
                String sql = "select * from user where username = ? and password = ?;";
                // 预编译sql
                stmt = conn.prepareStatement(sql);
                // 设置sql语句的参数
                stmt.setString(1, username);
                stmt.setString(2, password);
                // 执行sql语句
                rs = stmt.executeQuery();
                // 判断返回的结果
                if (rs.next()) {
                    // 登录成功
                    int id = rs.getInt("id");
                    String u_name = rs.getString("username");
                    String u_pwd = rs.getString("password");
                    String email = rs.getString("email");
                    System.out.println(id + " : " + u_name + " : " + u_pwd + " : " + email);
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                // 3. 释放资源
                JDBCUtils.release(conn, stmt, rs);
            }
        }
     
     
     
     
     
    JDBCUtils中避免sql注入问题之后最终版总结:
                    PreparedStatement的CRUD
    <wiz_code_mirror>
     
     
     
     
     
        @Test
        public void test_update() {
            Connection conn = null;
            PreparedStatement stmt = null;
            try {
                // 2. 建立连接
                conn = JDBCUtils.getConnection();
     
     // U 修改           
                // 3. 操作数据
                String sql = "update user set username = ?, password = ?, email = ? where id = ?;";
                stmt = conn.prepareStatement(sql);
                // 设置参数
                stmt.setString(1, "张三");
                stmt.setString(2, "888");
                stmt.setString(3, "zs@qiezi.cn");
                stmt.setInt(4, 1);
                // 执行
                int affectedRowNum = stmt.executeUpdate();
                System.out.println(affectedRowNum);
     
            
    // 删除
            
                // 2. 操作数据
                String sql = "delete from user where id = ?;";
                stmt = conn.prepareStatement(sql);
                stmt.setInt(1, 4);
                int affectedRowNum = stmt.executeUpdate();
                System.out.println(affectedRowNum);
                
                
    // 增加
                
                
                // 2. 操作数据
                String sql = "insert into user values(?,?,?,?);";
                stmt = conn.prepareStatement(sql);
                // 设置参数
                stmt.setInt(1, 4);
                stmt.setString(2, "赵六");
                stmt.setString(3, "888");
                stmt.setString(4, "zl@qiezi.cn");
                int affectedRowNumber = stmt.executeUpdate();
                System.out.println(affectedRowNumber);
            
            
                
    // 查询
                
                
                            // 2. 操作数据
                String sql = "select * from user where username = ? and password = ?;";
                stmt = conn.prepareStatement(sql);
                // 设置sql语句的参数
                stmt.setString(1, username);
                stmt.setString(2, password);
                // 执行sql语句
                rs = stmt.executeQuery();
                // 判断返回的结果
                if (rs.next()) {
                    // 登录成功
                    int id = rs.getInt("id");
                    String u_name = rs.getString("username");
                    String u_pwd = rs.getString("password");
                    String email = rs.getString("email");
                    System.out.println(id + " : " + u_name + " : " + u_pwd + " : " + email);
                }
            
            
        
            
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                // 4. 释放资源
                JDBCUtils.release(conn, stmt);
            }
        }
     
     
     
     
     

    二、JdbcTemplate

            

             JdbcTemplate 介绍

            JDBC已经能够满足大部分用户最基本的需求,但是在使用JDBC时,必须自己来管理数据库资源如:获取PreparedStatement,设置SQL语句参数,关闭连接等步骤。JdbcTemplate就是Spring对JDBC的封装,目的是使JDBC更加易于使用。JdbcTemplate是Spring的一部分
            JdbcTemplate处理了资源的建立和释放。他帮助我们避免一些常见的错误,比如忘了总要关闭连接。他运行核心的JDBC工作流,如Statement的建立和执行,而我们只需要提供SQL语句和提取结果。
     
            在JdbcTemplate中执行SQL语句的方法大致分为3类:
    1. execute:可以执行所有SQL语句,一般用于执行DDL语句。
    2. update:用于执行INSERT、UPDATE、DELETE等DML语句。
    3. queryXxx:用于DQL数据查询语句。
    ********新增加,新复习
    DDL (数据定义语言)
    数据定义语言 - Data Definition Language
    用来定义数据库的对象,如数据表、视图、索引等
    create drop alter truncate
    DML (数据操纵语言)
    数据处理语言 - Data Manipulation Language
    在数据库表中更新,增加和删除记录
    如 update, insert, delete 不包含查询
    DCL (数据控制语言)
    数据控制语言 – Data Control Language
    指用于设置用户权限和控制事务语句
    如grant,revoke,if…else,while,begin transaction
    DQL (数据查询语言)(★★★★★)
    数据查询语言 – Data Query Language
    数据表记录的查询。
    select
    *********
     
     

               JDBCTemplate使用:

                             API介绍:
                                1.org.springframework.jdbc.core.JdbcTemplate类方便执行SQL语句
    <wiz_code_mirror>
     
     
     
     
     
    public JdbcTemplate(DataSource dataSource)
    创建JdbcTemplate对象,方便执行SQL语句
    public void execute(final String sql)
    execute可以执行所有SQL语句,因为没有返回值,一般用于执行DML语句。
    public int update(final String sql)
    用于执行`INSERT`、`UPDATE`、`DELETE`等DML语句。
    public <T> T queryForObject(String sql, Class<T> requiredType, Object... args):
       传入参数, 执行查询语句,返回一个指定类型的数据。
       
       
       public Map<String, Object> queryForMap(String sql, Object... args)
    传入参数,执行查询语句,将一条记录放到一个Map中。
    public List<Map<String, Object>> queryForList(String sql, Object... args)
    传入参数,执行查询语句,返回一个List集合,List中存放的是Map类型的数据。
    public <T> List<T> query(String sql, RowMapper<T> rowMapper)
    执行查询语句,返回一个List集合,List中存放的是RowMapper指定类型的数据。
    public <T> List<T> query(String sql, RowMapper<T> rowMapper)
    执行查询语句,返回一个List集合,List中存放的是RowMapper指定类型的数据。
    public class BeanPropertyRowMapper<T> implements RowMapper<T>
    BeanPropertyRowMapper类实现了RowMapper接口
     
     
     
                            1.数据准备:
                                    这里采用c3p0数据流连接池,集成到JDBCUtils 工具类中,需要将c3p0的配置文件放入到src目录下
                                    导入依赖的jar包
                                             - spring-beans-5.0.2.RELEASE.jar
    - spring-core-5.0.2.RELEASE.jar
    - spring-jdbc-5.0.2.RELEASE.jar
    - spring-tx-5.0.2.RELEASE.jar
    - com.springsource.org.apache.commons.logging-1.1.1.jar
                              2.创建JdbcTemplate对象,传入c3p0连接池
                             3.调用 execute、update、queryXxx等方法
                                 
    c3p0-config.xml 配置文件
    <wiz_code_mirror>
     
     
     
     
     
    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
        <!-- 默认配置,c3p0框架默认加载这段默认配置 -->
        <default-config>
            <!-- 配置JDBC 四个基本属性 -->
            <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb4?serverTimezone=UTC&amp;characterEncoding=utf-8</property>
            <property name="user">root</property>
            <property name="password">111</property>
        </default-config>
        <!-- 可以自定义配置,为这段配置起一个名字,c3p0指定名称加载配置 -->
        <named-config name="zidingyimingzi">
            <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb4?serverTimezone=UTC&amp;characterEncoding=utf-8</property>
            <property name="user">root</property>
            <property name="password">111</property>
        </named-config>
    </c3p0-config>
     
     
    JDBCUtils 工具类
    <wiz_code_mirror>
     
     
     
     
     
    public class JDBCUtils {
        // 核心连接池类
        private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
        public static DataSource getDataSource() {
            return dataSource;
        }
        // 获取连接
        public static Connection getConnection() throws SQLException {
            return dataSource.getConnection();
        }
        // 释放资源
        public static void release(Connection conn, Statement stmt, ResultSet rs) {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                rs = null;
            }
            release(conn, stmt);
        }
        public static void release(Connection conn, Statement stmt) {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                stmt = null;
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                conn = null;
            }
        }
    }
     
     
    测试类(实现增改)
    <wiz_code_mirror>
     
     
     
     
     
    public class JDBCTemplateExecute {
        public static void main(String[] args) {
     // 查询语句
            
            
            
            // 1. 创建表的SQL语句
            String sql = "create table product (" +
                    "pid int primary key auto_increment," +
                    "pname varchar(20)," +
                    "price double" +
                    ");";
            // 2. 创建 jdbcTemplate 对象, 并将数据库连接池作为参数传入
            JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
            // 3. 使用 jdbcTemplate 对象调用 execute 方法, 执行 sql 语句, 创建数据库表.
            jdbcTemplate.execute(sql);
            
            
            
    // 增加数据
            
            // 2. 编写 sql 语句
            String sql = "insert into product values(null, ?, ?);";
            // 3. 执行 update 方法.
            jdbcTemplate.update(sql, "iPhone3GS", 3333);
            jdbcTemplate.update(sql, "iPhone4", 5000);
            
            
            
     //   修改数据
            
            // 2. 执行 update 语句
            String sql = "update product set pname = ?, price = ? where pid = ?;";
            int count = jdbcTemplate.update(sql, "XVIII", 18888, 10);
            System.out.println("count = " + count);
            
         
    // 删除数据
            // 2. 执行 delete 操作
            String sql = "delete from product where pid = ?;";
            int count = jdbcTemplate.update(sql, 7);
            System.out.println("count = " + count);
        }
    }
     
     
    总结:JdbcTemplate的update方法用于执行DML语句。同时还可以在SQL语句中使用?占位,在update方法的Object... args可变参数中传入对应的参数。
     
     
    测试类(实现查询)
    <wiz_code_mirror>
     
     
     
     
     
        @Test
        public void test1() {
            // 1. 创建一个 JdbcTemplate 对象
            JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
            
            
    //  queryForObject 方法
            
            
            // 2. 执行 queryForObject 方法
            String sql = "select pname from product where price = 7777";
            String pname = jdbcTemplate.queryForObject(sql, String.class);
            System.out.println("pname = " + pname);
            
         
            
    // queryForMap 方法 
            
            // 2. 执行 queryForMap 方法
            String sql = "select * from product where pid = ?;";
            Map<String, Object> map = jdbcTemplate.queryForMap(sql, 6);
            System.out.println("map = " + map);
            
            
         
            
     // objectForList
            
            // 2. 执行 objectForList 方法
            String sql = "select * from product where pid < ?;";
            List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, 8);
            for (Map<String, Object> map : list) {
                System.out.println(map);
            }
            
            
            
            
     // 使用RowMapper做映射返回对象
            
    1. 定义Product类
    2. 创建JdbcTemplate对象
    3. 编写查询的SQL语句
    4. 使用JdbcTemplate对象的query方法,并传入RowMapper匿名内部类
    5. 在匿名内部类中将结果集中的一行记录转成一个Product对象
            // 2. 执行 query 方法
            String sql = "select * from product;";
            List<Product> list = jdbcTemplate.query(sql, new RowMapper<Product>() {
                @Override
                public Product mapRow(ResultSet rs, int i) throws SQLException {
                    Product product = new Product();
                    int pid = rs.getInt("pid");
                    String pname = rs.getString("pname");
                    double price = rs.getDouble("price");
                    product.setPid(pid);
                    product.setPname(pname);
                    product.setPrice(price);
                    return product;
                }
            });
            // 遍历 list 集合
            for (Product product : list) {
                System.out.println(product);
            }
    1. 定义Product类
    2. 创建JdbcTemplate对象
    3. 编写查询的SQL语句
    4. 使用JdbcTemplate对象的query方法,并传入BeanPropertyRowMapper对象
             // 2. 执行 query 方法
            String sql = "select * from product;";
            List<Product> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Product.class));
            // 3. 遍历 list 集合
            for (Product product : list) {
                System.out.println(product);
            }
        }
     
     
    总结:
            JDBCTemplate的query方法用于执行SQL语句,简化JDBC的代码。同时还可以在SQL语句中使用?占位,在query方法的Object... args可变参数中传入对应的参数。
     
     
    三、c3p0
    在Hibernate和Spring 都提供对C3P0连接池支持.
    导入2个包
            c3p0-0.9.5.2.jar
            mchange-commons-java-0.2.11.jar
            mysql的jar包
            mysql-connector-java-8.0.11.jar
    基本操作
              // 核心连接池类
      ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
      // 设置四个JDBC基本连接属性
      comboPooledDataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
      comboPooledDataSource.setJdbcUrl("jdbc:mysql:///mydb4?serverTimezone=UTC&characterEnconding=utf-8");
      comboPooledDataSource.setUser("root");
      comboPooledDataSource.setPassword("111");
     
    常用基本连接池属性
        

    acquireIncrement  如果连接池中连接都被使用了,一次性增长">3个新的连接

    initialPoolSize  连接池中初始化连接数量默认:3

    maxPoolSize      最大连接池中连接数量默认:15连接

    maxIdleTime      如果连接长时间没有时间,将被回收默认:0 连接永不过期

        minPoolSize      连接池中最小连接数量 默认:">3

    通过c3p0创建数据库连接池对象方式提取到JDBCUtils中
    <wiz_code_mirror>
     
     
     
     
     
    public class JDBCUtils {
     
        // c3p0 数据库连接池对象属性
        // 这里会自动读取 位于src目录下的c3p0-config.xml 数据库连接池配置文件
        private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();
     
        // 获取连接
        public static Connection getConnection() throws SQLException {
            return dataSource.getConnection();
        }
     
        // 释放资源
        public static void release(Connection conn, Statement stmt, ResultSet rs) {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                rs = null;
            }
            release(conn, stmt);
        }
     
        public static void release(Connection conn, Statement stmt) {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                stmt = null;
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                conn = null;
            }
        }
    }
     
     
    c3p0-config.xml 数据库连接池配置文件 位于src 目录下
    <wiz_code_mirror>
     
     
     
     
     
    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
        <!-- 默认配置,c3p0框架默认加载这段默认配置 -->
        <default-config>
            <!-- 配置JDBC 四个基本属性 -->
            <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb4?serverTimezone=UTC&amp;characterEncoding=utf-8</property>
            <property name="user">root</property>
            <property name="password">111</property>
        </default-config>
        <!-- 可以自定义配置,为这段配置起一个名字,c3p0指定名称加载配置 -->
        <named-config name="zidingyi">
            <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb4?serverTimezone=UTC&amp;characterEncoding=utf-8</property>
            <property name="user">root</property>
            <property name="password">111</property>
        </named-config>
    </c3p0-config>
     
     
    测试类:
    <wiz_code_mirror>
     
     
     
     
     
        @Test
        public void test_jdbcUtils() {
     
            // 需求 : 查询 user 表中的所有数据
     
            Connection conn = null;
            PreparedStatement stmt = null;
            ResultSet rs = null;
     
            try {
                // 1. 建立连接
                conn = JDBCUtils.getConnection();
                // 2. 操作数据
                String sql = "select * from user;";
                stmt = conn.prepareStatement(sql);
                rs = stmt.executeQuery();
                while (rs.next()) {
                    int id = rs.getInt("id");
                    String username = rs.getString("username");
                    String password = rs.getString("password");
                    String email = rs.getString("email");
                    System.out.println(id + " : " + username + " : " + password + " : " + email);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                // 3. 释放资源
                JDBCUtils.release(conn, stmt, rs);
            }
        }
     
     
     
     

    四、druid

            Druid (德鲁伊) 是阿里巴巴开发的号称为监控而生的数据库连接池,Druid是目前最好的数据库连接池。在功能、性能、扩展性方面,都超过其他数据库连接池,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。Druid地址:https://github.com/alibaba/druid 
    DRUID连接池使用的jar包:druid-1.0.9.jar
    参数 说明
    url 连接数据库的url:jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC&characterEncoding=utf-8
    username 数据库的用户名
    password 数据库的密码
    driverClassName 驱动类名。根据url自动识别,这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName(建议配置下)
    initialSize 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
    maxActive 最大连接池数量
    maxIdle 已经不再使用,配置了也没效果
    minIdle 最小连接池数量
    maxWait 获取连接时最大等待时间,单位毫秒。
     
            API介绍
     
                    com.alibaba.druid.pool.DruidDataSourceFactory类有创建连接池的方法
     
    <wiz_code_mirror>
     
     
     
     
     
    public static DataSource createDataSource(Properties properties)
    创建一个连接池,连接池的参数使用properties中的数据
     
     
    tips:我们可以看到DRUID连接池在创建的时候需要一个Properties对象来设置参数,所以我们使用properties文件来保存对应的参数。
    DRUID连接池的配置文件名称随便,因为该配置文件需要我们手动实现加载。
    druid.properties文件内容:
    <wiz_code_mirror>
     
     
     
     
     
    driverClassName=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC&characterEncoding=utf-8
    username=root
    password=111
      
      
    initialSize=5
    maxActive=10
    maxWait=3000
    maxIdle=6
    minIdle=3
     
     
            使用步骤
    1. 在src目录下创建一个properties文件,并设置对应参数
    2. 加载properties文件的内容到Properties对象中
    3. 创建DRUID连接池,使用配置文件中的参数
    4. 从DRUID连接池中取出连接
    5. 执行SQL语句
    6. 关闭资源
     
    JDBCUtils 工具类集成 Druid 数据库连接池
    <wiz_code_mirror>
     
     
     
     
     
    public class JDBCUtils {
        // 属性
        private static final DataSource dataSource;
        static {
            Properties prop = new Properties();
            try {
                // 加载配置文件
                // 配置文件的位置无所谓,这里放的是项目的目录下,因为Druid数据库连接池需要手动加载配置文件
                prop.load(new FileReader("druid.properties"));
                // 创建数据库连接池
                dataSource = DruidDataSourceFactory.createDataSource(prop);
            } catch (Exception e) {
                throw new RuntimeException("连接池初始化失败!");
            }
        }
        public static DataSource getDataSource() {
            return dataSource;
        }
        // 建立连接
        public static Connection getConnection() throws SQLException {
            return dataSource.getConnection();
        }
        // 释放资源
        public static void release(Connection conn, Statement stmt, ResultSet rs) {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                rs = null;
            }
            release(conn, stmt);
        }
        public static void release(Connection conn, Statement stmt) {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                stmt = null;
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    // e.printStackTrace();  ignore 忽略.
                }
                conn = null;    // 目的: 让 conn 对象尽早被回收.
            }
        }
    }
     
     
    测试类:
     
    <wiz_code_mirror>
     
     
     
     
     
        @Test
        public void test3() {
            Connection conn = null;
            PreparedStatement stmt = null;
            ResultSet rs = null;
            try {
                // 1. 建立连接
                conn = JDBCUtils.getConnection();
                // 2. 操作数据
                String sql = "select * from user;";
                stmt = conn.prepareStatement(sql);
                rs = stmt.executeQuery();
                while (rs.next()) {
                    int id = rs.getInt("id");
                    String username = rs.getString("username");
                    String password = rs.getString("password");
                    String email = rs.getString("email");
                    System.out.println(id + " : " + username + " : " + password + " : " + email);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                // 3. 释放资源
                JDBCUtils.release(conn, stmt, rs);
            }
        }
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    五、Hibernate
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    六、MyBatis
  • 相关阅读:
    Java基础面试题总结
    mysql面试题总结
    记7.9面试题
    深入理解Java虚拟机学习笔记(三)-----类文件结构/虚拟机类加载机制
    jvm类加载子系统
    多线程与高并发基础三
    多线程与高并发基础二
    多线程与高并发基础一
    多线程与高并发笔记一
    Unknown initial character set index '255' received from server. Initial client character set can be forced via the 'characterEncoding' property.
  • 原文地址:https://www.cnblogs.com/zhengyuan/p/9496355.html
Copyright © 2020-2023  润新知