java学习笔记——JDBC中的 数据库连接池、事务的commit与rollback、DBUtils工具类的使用

JDBC中的 数据库连接池

//C3P0 数据库连接池,方式一
    @Test
    public void test1() throws Exception{
        ComboPooledDataSource ds = new ComboPooledDataSource();
        
        ds.setDriverClass("com.mysql.jdbc.Driver");
        ds.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        ds.setUser("root");
        ds.setPassword("123456");
        
        ds.setMaxPoolSize(10);
        ds.setAcquireIncrement(3);
        
        Connection conn = ds.getConnection();
        
        System.out.println(conn);
        
        conn.close();

    }


//C3P0 数据库连接池,方式二
    @Test
    public void test2() throws Exception{
        DataSource ds = new ComboPooledDataSource("helloc3p0");
        
        Connection conn = ds.getConnection();
        
        System.out.println(conn);

    }

代码段二中采用c3p0数据库连接池的是加载配置文件的方式创建数据库连接池的,配置文件名字必须统一叫做c3p0-config.xml,还要加载.jar文件,方法如下:



c3p0-config.xml的内容:

<c3p0-config>
  <named-config name="helloc3p0">
      
      <!-- 四个连接字符串 -->
      <property name="driverClass">com.mysql.jdbc.Driver</property>
      <property name="jdbcUrl">jdbc:mysql://localhost:3306/gome</property>
      <property name="user">root</property>
      <property name="password">123456</property>
 
      <!-- 若连接池满了,一次增上的连接数 -->
    <property name="acquireIncrement">5</property>
    
    <!-- 初始连接池大小 -->
    <property name="initialPoolSize">10</property>
    
    <!-- 连接池中最小连接数量 -->
    <property name="minPoolSize">5</property>
    
    <!-- 连接池中最大连接数量 -->
    <property name="maxPoolSize">10</property>

    <!-- 连接池中最多管理的 Statment 的个数 -->
    <property name="maxStatements">5</property>
    
    <!-- 连接池中每个连接管理的 Statement 的个数 -->
    <property name="maxStatementsPerConnection">5</property>
  </named-config>

</c3p0-config>


//DBCP 数据库连接池,方式一:
    @Test
    public void test3() throws Exception{
        BasicDataSource bds = new BasicDataSource();
        
        bds.setDriverClassName("com.mysql.jdbc.Driver");
        bds.setUrl("jdbc:mysql://localhost:3306/test");
        bds.setUsername("root");
        bds.setPassword("123456");
        
        bds.setInitialSize(10);
        bds.setMaxActive(10);
        
        Connection conn = bds.getConnection();
        
        System.out.println(conn);

    }


//DBCP 数据库连接池,方式二:
    @Test
    public void test4() throws Exception{
        Properties props = new Properties();
        props.load(this.getClass().getClassLoader().getResourceAsStream("com/gome/day1/properties"));
        
        DataSource ds = BasicDataSourceFactory.createDataSource(props);
        
        Connection conn = ds.getConnection();
        
        System.out.println(conn);

    }

上边代码块二的方式是DBCP数据库连接池加载资源文件的方式,先加载两个.jar文件,在添加资源文件。properties详情如下:

需要注意的是,使用类加载器的方式加载资源文件,资源文件交放在包下与代码同一级别,并且资源文件中key的名字要严格按照方法中的名字取,不然无法成功。





事务的commit与rollback


下列程序在两次更新数据库表中数据的中间模拟故障,用来测试commit与rollback的作用:

public class TestTransaction {

    // 模拟:
    @Test
    public void test1(){
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnection();
            
            conn.setAutoCommit(false); //取消自动提交,事务开启
            
            String sql1 = "update user_table set balance = balance - 100 where user = ?";
            update(conn, sql1, "AA");
            
            //模拟故障
//            int num = 10 / 0;
            
            String sql2 = "update user_table set balance = balance + 100 where user = ?";
            update(conn, sql2, "BB");
            
            conn.commit(); //提交
        } catch (Exception e) {
            e.printStackTrace();
            
             //回滚
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            JDBCUtils.close(null, null, conn);
        }
    }
    
    /*
     * 考虑事务的通用查询
     */
    public <T> T get(Connection conn, String sql, Class<T> clazz, Object... args) {
        
        T t = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(sql);
            
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }

            rs = ps.executeQuery();

            // 获取当前结果集的元数据
            ResultSetMetaData rsmd = rs.getMetaData();

            // 获取结果集的列数
            int columnCount = rsmd.getColumnCount();
            if (rs.next()) {
                t = clazz.newInstance();

                for (int i = 0; i < columnCount; i++) {
                    // 获取列名
                    String columnName = rsmd.getColumnLabel(i + 1);

                    // 根据列名获取对应列的数据
                    Object columnValue = rs.getObject(columnName);

                    Field field = clazz.getDeclaredField(columnName);// 注意:必须保证结果集中列名(别名),与属性名称保持一致!!!!!
                    field.setAccessible(true);// 忽略访问权限
                    field.set(t, columnValue);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(rs, ps, null);
        }

        return t;

    }

    /*
     * 考虑事务的,通用的增、删、改方法,适用于任何表
     */
    public int update(Connection conn, String sql, Object... args) {

        // 2. 获取 PreparedStatement , 用于发送 SQL
        PreparedStatement ps = null;
        // 4. 执行 SQL
        int row = 0;
        try {
            ps = conn.prepareStatement(sql);

            // 3. 填充占位符
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }

            row = ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 5. 关闭连接
            JDBCUtils.close(ps, null);
        }
        return row;
    }

}



DBUtils工具类的使用


public class TestDBUtils {
    
    private QueryRunner qr = new QueryRunner();
    
    //获取特殊某个值
    @Test
    public void test6(){
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnectionForC3P0();
            String sql = "select count(*) from customers";
            ResultSetHandler<Object> rsh = new ScalarHandler();
            Object obj = qr.query(conn, sql, rsh);

            System.out.println(obj);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(null, null, conn);
        }
    }
    
    //查询多个对象组成的存入 Map 集合, List 集合
    @Test
    public void test5(){
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnectionForC3P0();
            String sql = "select id, name, email, birth from customers where id < ?";
            ResultSetHandler<List<Map<String,Object>>> rsh = new MapListHandler();
            List<Map<String,Object>> list = qr.query(conn, sql, rsh, 21);
            
            for (Map<String, Object> map : list) {
                
                Set<Entry<String,Object>> entrySet = map.entrySet();
                
                for (Entry<String, Object> entry : entrySet) {
                    System.out.println(entry.getKey() + "   =   " + entry.getValue());
                }
                
                System.out.println("-----------------------------------------------------------------");
                
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(null, null, conn);
        }
    }
    
    //查询多个对象组成的 List 集合
    @Test
    public void test4(){
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnectionForC3P0();
            String sql = "select id, name, email, birth from customers where id < ?";
            ResultSetHandler<List<Customer>> rsh = new BeanListHandler<Customer>(Customer.class);
            List<Customer> list = qr.query(conn, sql, rsh, 21);
            
            for (Customer customer : list) {
                System.out.println(customer);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(null, null, conn);
        }
        
        
    }
    
    //查询一个对象
    @Test
    public void test3(){
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnectionForC3P0();
            String sql = "select id, name, email, birth from customers where id = ?";
            ResultSetHandler<Customer> rsh = new BeanHandler<Customer>(Customer.class);
            Customer cust = qr.query(conn, sql, rsh, 20);
            
            System.out.println(cust);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(null, null, conn);
        }
    }
    
    @Test
    public void test2(){
        ResultSetHandler<List<Customer>> rsh = new ResultSetHandler<List<Customer>>() {
            @Override
            public List<Customer> handle(ResultSet arg0) throws SQLException {
                return null;
            }
        };
    }
    
    //添加数据
    @Test
    public void test1(){
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnectionForC3P0();
            
            String sql = "insert into customers(id, name, email, birth) values(?,?,?,?)";
            
            int row = qr.update(conn, sql, 20, "陈晨", "chenchen@abc.com", "1999-9-9");
            
            System.out.println("已影响 " + row + " 行");
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(null, null, conn);
        }
    }

}

发布了65 篇原创文章 · 获赞 46 · 访问量 1万+
展开阅读全文

求解JDBC使用批处理executeBatch()之后commit(),数据库没有变化。

07-24

Java的JDBC使用批处理executeBatch()之后commit(),数据库没有变化。 代码 ``` public static boolean newProblem_state(List<User_t> auditorlist, Problems_t problems)throws ClassNotFoundException, SQLException { KrakenRecord.debug("正在建立关联"+auditorlist.size()); Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection(URL, USER, PASSWORD); conn.setAutoCommit(false); // 设置手动提交 String sql = "insert into problemstate_ta (problemstate_problem_id,problemstate_auditor_id,problemstate_state) values(" + problems.getProblems_id() + ",?,0)"; PreparedStatement ps = conn.prepareStatement(sql); for (User_t user_t : auditorlist) { ps.setInt(1, user_t.getUser_id()); ps.addBatch();// 添加到批次 } int[] i = ps.executeBatch();// 提交批处理 conn.commit();// 执行 for (int j : i) { System.out.println(j); } // 关闭资源 ps.close(); conn.close(); return true; } ``` 以上代码运行后,显示: 正在建立关联4 1 1 1 1 auditorlist的size是4正确,打印的四个1应该是executeBatch()正确执行了,但是数据库没有变化,求解 补充:昨晚发现是插入的数据库没反应,也就是problemstate_ta 这个表,无法插入数据,命令没有写错,在Navicat中窗口模式手动插入数据,数据的自动增长id显示+1,插入数据也没有报错,但是刷新表,数据没了,求解 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览