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

转载于:https://www.cnblogs.com/zhengyuan/p/9496355.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/266298.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

福布斯评科技未来五大趋势:电脑消失融入生活时间

福布斯评科技未来五大趋势&#xff1a;电脑消失融入生活时间 谈趋势似乎并不讨巧&#xff0c;因为所谓趋势通常都是指时尚。每每谈及趋势&#xff0c;人们立刻就会想到穿着夸张服饰在T台上昂首阔步的模特&#xff0c;但每当下一季的新款推出&#xff0c;再华丽的时装都会很快…

Windows如何开启虚拟化,以安装虚拟机?

参考&#xff1a;Windows如何开启虚拟化&#xff0c;以安装虚拟机&#xff1f; 作者&#xff1a;一只青木呀 发布时间&#xff1a;2020-08-28 20:58:45 网址&#xff1a;https://blog.csdn.net/weixin_45309916/article/details/108286787 设置BIOS 安装 Ubuntu 时报错&#x…

php生成文件index.html,Typecho生成静态首页index.html文件

Typecho生成静态首页index.html文件作者&#xff1a;佚名来源&#xff1a;爱好者时间&#xff1a;2019-11-02在挨踢路看到的教程&#xff0c;不仅仅适用于Typecho&#xff0c;wordpress也是可以通用。教程在网站根目录新建文件f5.php然后里面写入下面的代码。$nowtimetime();$p…

python语言1002python语言_PYTHON语言学习

PYTHON 语言学习 通过两个星期的自学 python 语言&#xff0c;初步了解到 python 的知识构架。它比 C 语言和 C 语 言在某种程度上来说要简单些&#xff0c; 但是也有很多我不懂的东西。 陈老师给我安排的课堂任务是 第 21 章的 Database Programming &#xff0c;通过 python …

python数据结构之栈

栈栈&#xff08;stack&#xff09;&#xff0c;有些地方称为堆栈&#xff0c;是一种容器&#xff0c;可存入数据元素、访问元素、删除元素&#xff0c;它的特点在于只能允许在容器的一端&#xff08;称为栈顶端指标&#xff0c;英语&#xff1a;top&#xff09;进行加入数据&a…

Ubuntu 16.04安装教程及虚拟机设置

摘自&#xff1a;Ubuntu 16.04安装教程及设置 作者&#xff1a;一只青木呀 发布时间&#xff1a; 2020-07-09 22:36:50 网址&#xff1a;https://blog.csdn.net/weixin_45309916/article/details/107239119 配合这篇博文&#xff1a;安装ubuntu20.04并进行优化——安装vim,gcc,…

matlab vision工具箱使用手册,matlab-Computer Vision System ToolBox的系统对象使用

在MATLAB中&#xff0c;调用计算机视觉工具箱中的vision.GeometricScaler可实现对输入图像的缩放变换。 vision.GeometricScaler的具体使用方法如下&#xff1a; vision.GeometricScaler 功能&#xff1a;对图像进行几何尺寸的放缩&#xff1b; 语法&#xff1a;A step(vision…

python方法名加__学习python中__name__方法使用

今天在自学生产者消费者模型时&#xff0c;发现了一个有趣的方法 if__name__ "__main__": for i in range(2): p Producer() p.start() for i in range(10): c Consumer() c.start() 于是就去确认了一下度娘&#xff0c;果然好多初学者都会问这个问题&#xff0c;…

牛客小白月赛6 J 洋灰三角

J 洋灰三角 题目&#xff1a; 链接&#xff1a;https://www.nowcoder.com/acm/contest/136/J来源&#xff1a;牛客网 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K64bit IO Format: %lld题目描述 洋灰是…

PureMVC(AS3)剖析:设计模式(二)

PureMVC&#xff08;AS3&#xff09;剖析&#xff1a;设计模式&#xff08;二&#xff09; 模式 上一篇中介绍了PureMVC中使用的3种设计模式&#xff1a;单例模式、观察者模式、外观模式。本篇将继续介绍剩下的3种设计模式&#xff1a; l 使用中介者&#xff08;Mediator&…

FileZilla的下载与安装以及简单使用(Ubuntu和Windows之间互传文件需要下载——客户端)

参考&#xff1a;FileZilla的下载与安装以及简单使用&#xff08;有图解超简单&#xff09; 作者&#xff1a;一只青木呀 发布时间&#xff1a; 2020-08-04 13:20:59 网址&#xff1a;https://blog.csdn.net/weixin_45309916/article/details/107782070?ops_request_misc%257B…

基于Matlab的循环码实验报告,基于MATLAB的循环码实验报告

及g(x)|C(x)上述定理告诉了构造(n&#xff0c;k)循环码的方法如下&#xff1a; ① 对xn-1 (在二元域中等效于对xn1)实行因式分解, 找出其中的(n-k)次因式。② 以找出的(n-k)次因式为循环码生成多项式g(x)&#xff0c;与信息多项式m(x)相乘&#xff0c;即得码多项式&#xff1a;…

前后端交互中,返回前端的自定义响应数据结构

在前后端交互分离的体系下&#xff0c;我们后端一般会将返回给前端的信息数据进行格式的统一&#xff0c;然后返回前端json串&#xff1b;&#xff0c;一下我提供了一个模板&#xff0c;在实际开发中可进行参考 package com.project.util;/** * Description: 自定义响应数据结构…

如何解决Filezilla 与虚拟机连接不上的问题

摘自&#xff1a;如何解决Filezilla 与虚拟机连接不上的问题 作者&#xff1a;一只青木呀 发布时间&#xff1a; 2020-08-28 21:48:04 网址&#xff1a;https://blog.csdn.net/weixin_45309916/article/details/108287326?ops_request_misc%257B%2522request%255Fid%2522%253A…

php 访问 sharepoint列表,SharePoint—用REST方式访问列表

REST的定义与作用在SharePoint 2010中&#xff0c;基本上有如下几种数据访问方式&#xff1a; 服务器端对象模型LINQ to SharePointWeb Service客户端对象模型ADO.NET Data Service (REST协议)ADO.NET Data Service (强类型)REST是SharePoint中一种数据访问方式&#xff0c;这种…

python去除特殊字符_python去除BOM头\ufeff等特殊字符

1.\ufeff 字节顺序标记 去掉\ufeff&#xff0c;只需改一下编码就行&#xff0c;把UTF-8编码改成UTF-8-sig with open(file_path, moder, encodingUTF-8-sig) as f: s f.read() 2.\xa0 是不间断空白符 \xa0 是不间断空白符 我们通常所用的空格是 \x20 &#xff0c;是在标准AS…

Vmware虚拟机三种网络模式配图详解

目录Vmware虚拟机三种网络模式详解Vmware虚拟机三种网络模式详解 具体的文字描述参见博文&#xff1a;https://www.cnblogs.com/linjiaxin/p/6476480.html Linux——Vmware虚拟机三种网络模式详解

SQL SERVER 中identity

SQL SERVER 中identity用法&#xff1a; 在数据库中, 常用的一个流水编号通常会使用 identity 栏位来进行设置, 这种编号的好处是一定不会重覆, 而且一定是唯一的, 这对table中的唯一值特性很重要, 通常用来做客户编号, 订单编号等功能, 以下介绍关于此种栏位常用方式及相关技…

php content-type: multipart/mixed,{error:invalid multipart format} 这是什么原因,我已经在HEADER中设置了Content-...

用CULR向七牛的API上传文件每次总是invalid multipart format但是我已经设置了Content-type:multipart/form-data呀function uploadFile($localPath, $remoteFileName, $headersarray()){global $conf;$remoteFileName trim($remoteFileName,/);$policy array(scope > $co…

【AGC005F】Many Easy Problems (NTT)

Description ​ 给你一棵\(~n~\)个点的树和一个整数\(~k~\)。设为\(~S~\)为树上某些点的集合&#xff0c;定义\(~f(S)~\)为最小的包含\(~S~\)的联通子图的大小。\(~n~\)个点选\(~k~\)个点一共有\(~C_n^k~\)种方案&#xff0c;请你求出所有方案的\(~f(S)~\)的和&#xff0c; 对\…