• jdbc


    JDBC

    今日任务

    • 使用JDBC完成对分类表CRUD的操作(JDBC的回顾)
    • 使用DBCP,C3P0连接池完成基本数据库的操作(抽取工具类)
    • 能够使用DBUtils完成CRUD的操作

     

    教学导航

    教学目标

    掌握DBCPC3P0连接池的使用并掌握连接池的原理.

    能够使用DBUtils完成基本的CRUD的操作

    教学方法

    案例驱动法

    1.1 使用JDBC完成对于分类的CRUD的操作-回顾JDBC

    1.1.1 需求:

    网上商城中对分类添加,修改,删除,查询的操作.使用JDBC完成对分类的CRUD的操作.

    1.1.2 分析:

    1.1.2.1 技术分析

    JDBC的回顾】

    • JDBC的概念:

    JDBCJava Data Base Connectivity.

    • 驱动:

     

    • JDBC的开发步骤:

    步骤一:注册驱动.

    步骤二:获得连接.
    步骤三:创建执行SQL语句对象.

    步骤四:释放资源.

    • JDBCAPI的详解:

    DriverManager

        * 注册驱动:

        * 获得连接:

    Connection

        * 获得执行SQL语句对象.

            * Statement createStatement();

            * PreparedStatement prepareStatement(String sql);

            * CallableStatement prepareCall(String sql);

        * 进行事务管理:

            * setAutoCommit(boolean flag);

            * commit();

            * rollback();

    Statement:

        * 执行SQL语句:

            * int executeUpate(String sql); --执行insert update delete语句.

            * ResultSet executeQuery(String sql); --执行select语句.

            * boolean execute(String sql); --执行select返回true 执行其他的语句返回false.

      

    ResultSet:

        * 遍历结果集:next();

        * 获得结果集中的数据.getXXX(int c); getXXX(String name);

    1.1.2.2 步骤分析

    • 步骤一:创建Java项目,引入mysql的驱动包.
    • 步骤二:编写程序
    • 步骤三:注册驱动
    • 步骤四:获得连接
    • 步骤五:执行SQL
    • 步骤六:释放资源

    1.1.3 代码实现:

    抽取工具类:

    package com.itheima.jdbc.utils;

     

    import java.io.FileInputStream;

    import java.io.FileNotFoundException;

    import java.io.IOException;

    import java.sql.Connection;

    import java.sql.DriverManager;

    import java.sql.ResultSet;

    import java.sql.SQLException;

    import java.sql.Statement;

    import java.util.Properties;

     

    /**

     * JDBC的工具类

     * @author apple

     *

     */

    public class JDBCUtils {

    public static final String DRIVERCLASS;

    public static final String URL;

    public static final String USERNAME;

    public static final String PASSWORD;

     

    static{

    // 获得属性文件中的数据.

    Properties properties = new Properties();

    try {

    properties.load(new FileInputStream("src/db.properties"));

    } catch (FileNotFoundException e) {

    e.printStackTrace();

    } catch (IOException e) {

    e.printStackTrace();

    }

     

    DRIVERCLASS = properties.getProperty("jdbc.driverClass");

    URL = properties.getProperty("jdbc.url");

    USERNAME = properties.getProperty("jdbc.username");

    PASSWORD = properties.getProperty("jdbc.password");

    }

     

    // 加载驱动:

    public static void loadDriver(){

    try {

    Class.forName(DRIVERCLASS);

    } catch (ClassNotFoundException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

     

    // 获得连接:

    public static Connection getConnection(){

    loadDriver();

    Connection conn = null;

    try {

    conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);

    } catch (SQLException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    return conn;

    }

     

    // 释放资源:

    public static void release(Statement stmt,Connection conn){

    if(stmt != null){

    try {

    stmt.close();

    } catch (SQLException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    stmt = null;

    }

     

    if(conn != null){

    try {

    conn.close();

    } catch (SQLException e) {

    e.printStackTrace();

    }

    conn = null;

    }

    }

     

    public static void release(ResultSet rs,Statement stmt,Connection conn){

    if(rs!= null){

    try {

    rs.close();

    } catch (SQLException e) {

    e.printStackTrace();

    }

    rs = null;

    }

    if(stmt != null){

    try {

    stmt.close();

    } catch (SQLException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    stmt = null;

    }

     

    if(conn != null){

    try {

    conn.close();

    } catch (SQLException e) {

    e.printStackTrace();

    }

    conn = null;

    }

    }

    }

     

    1.2 使用连接池改造JDBC的程序:

    1.2.1 需求:

    提升程序运行的效率,采用连接池对JDBC的部分的效率进行提升.

    1.2.2 分析:

    1.2.2.1 技术分析:

    【连接池的概述】

    • 为什么使用连接池

    Connection对象在JDBC使用的时候.使用的时候就会去创建一个对象,使用结束以后就会将这个对象给销毁了.每次创建和销毁对象都是耗时操作.需要使用连接池对其进行优化.程序初始化的时候,初始化多个连接,将多个连接放入到池中(内存中).每次获取的时候,都可以直接从连接池中进行获取.使用结束以后,将连接归还到池中.

    • 常见连接池:

    DBCP :Apache.

    C3P0 :

    【连接池的原理】

    javax.sql.DataSource接口--连接池的接口

    * 功能:初始化多个连接.把多个连接放入到内存中.

    * 归还:将连接对象放回到内存中.

    【自定义连接池--了解】

    public class MyDataSource implements DataSource{

     

    // 创建一个集合List集合.

    List<Connection> list = new ArrayList<Connection>();

     

    // 初始化连接池的时候,初始化5个连接.

    public  MyDataSource() {

    for (int i = 1; i <= 5; i++) {

    Connection conn = JDBCUtils.getConnection();

    list.add(conn);

    }

    }

     

    @Override

    // 从连接池中获得连接

    public Connection getConnection() throws SQLException {

    if(list.size()==0){

    for (int i = 1; i <= 3; i++) {

    Connection conn = JDBCUtils.getConnection();

    list.add(conn);

    }

    }

    Connection conn = list.remove(0);

    return conn;

    }

     

    // 归还连接:

    public void addBack(Connection conn){

    list.add(conn);

    }

    ...

    }

     

    【自定义连接池中问题】

    1.创建连接池的时候能不能面向接口编程.

    2.额外增加连接池的方法,那么程序员需要记住这些方法.能不能不额外去提供一些方法.

    ***** 解决:就是要去增强Connectionclose方法.

           1.继承的方法:

                * 继承的使用条件:能够控制这个类的构造.

           2.装饰者模式:(*****)

                * 装饰者模式的使用条件:

                    * 2.1增强的类和被增强的类实现相同的接口.

                    * 2.2在增强的类中能够获得被增强的类的引用.

                * 接口中方法过多,只增强其中的一个方法.其他方法都需要原样调用原有方法.

           3.动态代理:(*****)

                * JDK的动态代理使用条件:

                     * 被代理的对象必须实现接口.

    【使用开源连接池优化程序】

    • DBCP连接池:

     

    核心API

     

     

    @Test

    /**

     * DBCP的一个入门:手动设置参数

     */

    public void demo1(){

    Connection conn = null;

    PreparedStatement pstmt = null;

     

    // 创建连接池:

    BasicDataSource dataSource = new BasicDataSource();

    dataSource.setDriverClassName("com.mysql.jdbc.Driver");

    dataSource.setUrl("jdbc:mysql:///web07");

    dataSource.setUsername("root");

    dataSource.setPassword("1234");

    try{

    // 获得连接:

    conn = dataSource.getConnection();

    // 编写SQL语句.

    String sql = "insert into category values (null,?)";

    // 预编译SQL:

    pstmt = conn.prepareStatement(sql);

    // 设置参数:

    pstmt.setString(1, "鞋靴箱包");

    //执行SQL

    pstmt.executeUpdate();

    }catch(Exception e){

    e.printStackTrace();

    }finally{

    JDBCUtils.release(pstmt, conn);

    }

    }

     

    @Test

    /**

     * DBCP的带有配置文件的方式

     */

    public void demo2(){

    Connection conn = null;

    PreparedStatement pstmt = null;

     

    // 创建连接池:

    try{

    Properties properties = new Properties();

    properties.load(new FileInputStream("src/dbcp.properties"));

    DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);

    // 获得连接:

    conn = dataSource.getConnection();

    // 编写SQL语句.

    String sql = "insert into category values (null,?)";

    // 预编译SQL:

    pstmt = conn.prepareStatement(sql);

    // 设置参数:

    pstmt.setString(1, "生活用品");

    //执行SQL

    pstmt.executeUpdate();

    }catch(Exception e){

    e.printStackTrace();

    }finally{

    JDBCUtils.release(pstmt, conn);

    }

    }

     

    DBCP的参数的设置:

    #连接设置

    driverClassName=com.mysql.jdbc.Driver

    url=jdbc:mysql://localhost:3306/jdbc

    username=root

    password=1234

     

    #<!-- 初始化连接 -->

    initialSize=10

     

    #最大连接数量

    maxActive=50

     

    #<!-- 最大空闲连接 -->

    maxIdle=20

     

    #<!-- 最小空闲连接 -->

    minIdle=5

     

    #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60-->

    maxWait=60000

    • C3P0连接池的使用:

     

     

    代码实现:

    @Test

    /**

     * 手动设置参数的方式:

     */

    public void demo1(){

    Connection conn = null;

    PreparedStatement stmt = null;

    // System.err.println("");

    try{

    // 创建连接池:

    ComboPooledDataSource dataSource = new ComboPooledDataSource();

    // 设置参数:

    dataSource.setDriverClass("com.mysql.jdbc.Driver");

    dataSource.setJdbcUrl("jdbc:mysql:///web07");

    dataSource.setUser("root");

    dataSource.setPassword("1234");

     

    conn = dataSource.getConnection();

    // 编写SQL

    String sql = "insert into category values (null,?)";

    // 预编译SQL:

    stmt = conn.prepareStatement(sql);

    // 设置参数:

    stmt.setString(1, "食品饮料");

    stmt.executeUpdate();

    }catch(Exception e){

    e.printStackTrace();

    }finally{

    JDBCUtils.release(stmt, conn);

    }

    }

     

    @Test

    /**

     * 配置文件的方式:

     */

    public void demo2(){

    Connection conn = null;

    PreparedStatement stmt = null;

    // System.err.println("");

    try{

    // 创建连接池:

    ComboPooledDataSource dataSource = new ComboPooledDataSource("mysql11111");

     

    conn = dataSource.getConnection();

    // 编写SQL

    String sql = "insert into category values (null,?)";

    // 预编译SQL:

    stmt = conn.prepareStatement(sql);

    // 设置参数:

    stmt.setString(1, "食品饮料222");

    stmt.executeUpdate();

    }catch(Exception e){

    e.printStackTrace();

    }finally{

    JDBCUtils.release(stmt, conn);

    }

    }

    使用C3P0改写了工具类

    public class JDBCUtils2 {

     

    private static final ComboPooledDataSource DATASOURCE =new ComboPooledDataSource();

     

    public Connection getConnection(){

    Connection conn = null;

    try {

    conn = DATASOURCE.getConnection();

    } catch (SQLException e) {

    e.printStackTrace();

    }

    return conn;

    }

         ...

    }

    1.3 DBUtils完成CRUD的操作

    1.3.1 需求:

    简化DAO的开发.

    1.3.2 分析:

    1.3.2.1 技术分析:

    DBUtils

    【概述】

    DBUtilsjava编程中的数据库操作实用工具,小巧简单实用。

    DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码。

    Dbutils三个核心功能介绍

    l QueryRunner中提供对sql语句操作的API.

    l ResultSetHandler接口,用于定义select操作后,怎样封装结果集.

    l DbUtils类,它就是一个工具类,定义了关闭资源与事务处理的方法

    【QueryRunner核心类

    l QueryRunner(DataSource ds) ,提供数据源(连接池),DBUtils底层自动维护连接connection

    l update(String sql, Object... params) ,执行更新数据

    l query(String sql, ResultSetHandler<T> rsh, Object... params) ,执行查询

    【ResultSetHandler结果集处理类

    ArrayHandler

    将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值

    ArrayListHandler

    将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。

    BeanHandler

    将结果集中第一条记录封装到一个指定的javaBean中。

    BeanListHandler

    将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中

    ColumnListHandler

    将结果集中指定的列的字段值,封装到一个List集合中

    KeyedHandler

    将结果集中每一条记录封装到Map<String,Object>,在将这个map集合做为另一个Mapvalue,另一个Map集合的key是指定的字段的值。

    MapHandler

    将结果集中第一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值

    MapListHandler

    将结果集中每一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值,在将这些Map封装到List集合中。

    ScalarHandler

    它是用于单数据。例如select count(*) from 表操作。

    【DbUtils】

    closeQuietly(Connection conn) 关闭连接,如果有异常try后不抛。

    commitAndCloseQuietly(Connection conn) 提交并关闭连接

    rollbackAndCloseQuietly(Connection conn) 回滚并关闭连接

  • 相关阅读:
    SQL Server高可用性(High Availability)——Database Replication
    sql server中意向锁的作用
    面试题36:数组中的逆序对
    SQL Server高可用性(High Availability)——Log Shipping
    SQL Server Join方式
    Enabling the Dedicated Administrator Connection (DAC) in SQL Server Express
    执行计划重编译的时机
    SQL Server高可用性(High Availability)——Failover Clustering
    面试题34:丑数
    sql server 性能分析工具
  • 原文地址:https://www.cnblogs.com/nextgg/p/7642848.html
Copyright © 2020-2023  润新知