Java-EE DAO模式、连接池和DBUtils应用

                        DAO模式、连接池和DBUtils应用

 

第一节 工具类封装、DAO模式和自定义连接池

1.1.1 封装DbUtils

由于多个地方都需要使用数据库连接和释放,所以把功能封装到工具类中DbUtils

四个功能:1注册驱动 2 获取连接 3 释放资源 4 执行命令 【5 执行查询】


import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class  DbUtils{
    private static String driver;
    private static String url;
    private static String user;
    private static String password;
    static{
//        driver="com.mysql.jdbc.Driver";
//        url="jdbc:mysql://localhost:3306/myschool?useSSL=true&characterEncoding=utf8";
//        user="root";
//        password="root";

        //注册驱动
        try {
            //读取文件1
//            Properties properties=new Properties();
//            FileInputStream fis=new FileInputStream("src\\db.properties");
//            properties.load(fis);
//            fis.close();

            //读取文件2 使用类加载器 加载配置文件
            Properties properties=new Properties();
            InputStream is= DbUtils.class.getClassLoader().getResourceAsStream("db.properties");
            properties.load(is);
            is.close();


            driver=properties.getProperty("driver");
            url=properties.getProperty("url");
            user=properties.getProperty("user");
            password=properties.getProperty("password");


            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("注册驱动失败");
        }

    }

    public static Connection getConnection(){
        try {
            return DriverManager.getConnection(url, user, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void closeAll(Connection conn, Statement stat, ResultSet rs){
        try {
            if(rs!=null){
                rs.close();
            }
            if(stat!=null){
                stat.close();
            }
            if(conn!=null){
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static int executeUpdate(String sql,Object...params){ //insert update delete  ?????
                          //编译器会在背地里把这最后一个形参转化为一个数组形参,
                          //并在编译出的class文件里作上一个记号,表明这是个实参个数可变的方法。
        Connection conn =null;
        PreparedStatement pstat=null;
        try {
            conn = getConnection();
            pstat = conn.prepareStatement(sql);
            //设置参数
            if(params!=null){
                for (int i = 0; i < params.length; i++) {
                    pstat.setObject(i+1, params[i]);
                }
            }
            return pstat.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            closeAll(conn, pstat, null);
        }
        return -1;

    }
}

配置文件信息:db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/student?useSSL=true&characterEncoding=utf8
user=root
password=123456

1.2 DAO设计模式

DAO(Database Access Object 数据库访问对象)

为了降低耦合性,提出了DAO封装数据库操作的设计模式。

它可以实现业务逻辑与数据库访问相分离。相对来说,数据库是比较稳定的,其中DAO组件依赖于数据库系统,提供数据库访问的接口,隔离了不同的数据库实现。

DAO模式的组成部分

1 DAO接口(主要包 添加 修改 查询 删除方法)

2 DAO实现类

3 实体类 (domain(领域)、beans、entity、pojo、model)

PO (VO)(Persistent Object, Value Object)

VO (View Object)

DTO (Data Transfer Object)

--作用:用在数据访问代码和业务逻辑代码之间通过实体类来传输数据

--实体类特征:

◦属性一般使用private修饰

◦提供public修饰的getter/setter方法

◦实体类提供无参构造方法,根据业务提供有参构造

◦实现java.io.Serializable接口,支持序列化机制

4 数据库连接和关闭工具类

设计的包名 :

domain 存放实体类

utils 存放工具类

dao 存放接口

dao.impl 存放实现类

 

连接池

第二节 DBCP连接池

DBCP(DataBase Connection Pool),[数据库连接池]。是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。单独使用dbcp需要2个包:commons-dbcp.jar,commons-pool.jar由于建立数据库连接是一个非常耗时的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。

2.1 DBCP连接池的使用

2.1.1 创建项目

创建Java项目

2.1.2 导入相应jar包

mysql驱动包

commons-dbcp.jar

commons-pool.jar

commons-logging.jar 日志支持

DBCP连接池的配置文件信息:dbcp.properties

#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/student?useSSL=true&characterEncoding=utf8
username=root
password=123456
#<!--初始化连接-->
initialSize=10
#<!--最大空闲连接-->
maxTotal=50
#<!--最小空闲连接-->
minIdle=20
#<!--超时等待-->
maxWaitMillis=5000

DbUtils_dbcp:


package com.vince.utiles;

import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;

import java.beans.PropertyDescriptor;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/*
 * wgy 2019/8/26 14:28
 * 佛祖保佑,永无BUG!
 */
/*四个功能
 * (1)注册驱动(一次)
 * (2)获取连接
 * (3)释放资源
 * (4)执行SQL (增删改)
 *
 * */
public class DbUtils_DBCP {



    private static BasicDataSource dataSource;
    static {
        try {
            Properties properties=new Properties();
            InputStream is = DbUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcp.properties");
             properties.load(is);
             is.close();
            dataSource = BasicDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("初始化失败!");
        }

           /* dataSource = new BasicDataSource();
            //设置四个基本属性
            dataSource.setDriverClassName("com.mysql.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql://localhost:3306/student?useSSL=true&characterEncoding=utf8");
            dataSource.setUsername("root");
            dataSource.setPassword("123456");

            //其他属性
            //设置初始大小
            dataSource.setInitialSize(20);
            //设置最大个数
            dataSource.setMaxTotal(50);
            //设置最大空闲连接
            dataSource.setMaxIdle(10);
            //设置最小空闲连接
            dataSource.setMinIdle(5);
            //设置超时时间
            dataSource.setMaxWaitMillis(5000);*/

    }

    public static Connection getConnection(){

        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void closeAll(Connection conn, Statement stat, ResultSet rs){
        try {
            if(rs!=null){
                rs.close();
            }
            if(stat!=null){
                stat.close();
            }
            if(conn!=null){
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static int executeUpdate(String sql,Object...params){ //insert update delete  ?????

        Connection conn =null;
        PreparedStatement pstat=null;
        try {
            conn = getConnection();
            pstat = conn.prepareStatement(sql);
            //设置参数
            if(params!=null){
                for (int i = 0; i < params.length; i++) {
                    pstat.setObject(i+1, params[i]);
                }
            }
            return pstat.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            closeAll(conn, pstat, null);
        }
        return -1;

    }

    //返回List集合的方法
    public  static <T> List<T> findList(String sql,  Class<T> class1,Object... params){
        List<T> list=new ArrayList<>();
        Connection conn=null;
        PreparedStatement pstat=null;
        ResultSet rs=null;
        //查询数据
        try {
            conn=getConnection();
            pstat = conn.prepareStatement(sql);
            if(params!=null){
                for (int i = 0; i < params.length; i++) {
                    pstat.setObject(i+1, params[i]);
                }
            }
            rs = pstat.executeQuery();
            //获取rs中的列名
            ResultSetMetaData metaData = rs.getMetaData();
            while(rs.next()){
                //创建一个对象
                T t=convertToObject(metaData, rs, class1);
                list.add(t);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            closeAll(conn, pstat, rs);
        }

        return list;
    }



    //返回单个对象的方法
    public static <T> T findSingle(String sql,Class<T> class1,Object...params ){

        Connection conn=null;
        PreparedStatement pstat=null;
        ResultSet rs=null;
        //查询数据
        try {
            conn=getConnection();
            pstat = conn.prepareStatement(sql);
            if(params!=null){
                for (int i = 0; i < params.length; i++) {
                    pstat.setObject(i+1, params[i]);
                }
            }
            rs = pstat.executeQuery();
            //获取rs中的列名
            ResultSetMetaData metaData = rs.getMetaData();
            if(rs.next()){
                //创建一个对象
                return convertToObject(metaData, rs, class1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            closeAll(conn, pstat, rs);
        }
        return null;
    }

    public static <T> T convertToObject(ResultSetMetaData metaData,ResultSet rs,Class<T> class1){
        try {
            T t=class1.newInstance();
            for(int i=0;i<metaData.getColumnCount();i++){
                String columnLabel=metaData.getColumnLabel(i+1);
                Object value = rs.getObject(columnLabel);//empno  ename job
                //System.out.println(columnLabel+"==="+value);
                //创建属性描述符
                try {
                    PropertyDescriptor pd=new PropertyDescriptor(columnLabel, class1);
                    if(pd!=null){
                        //System.out.println(pd.getName());
                        Method writeMethod = pd.getWriteMethod(); //setEmpno setEname setJob
                        writeMethod.invoke(t,value);
                    }
                } catch (Exception e) {
                    continue;
                }
            }
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}

 

第三节 C3P0连接池

C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。

c3p0与dbcp区别
     1.
        dbcp没有自动回收空闲连接的功能
        c3p0有自动回收空闲连接功能
     2. 
        dbcp需要手动加载配置文件
        c3p0自动加载

3.1 使用步骤

3.1.1 创建项目

3.1.2 导入jar包

c3p0-0.9.1.2.jar

mchange-commons-java-0.2.11.jar

mysql驱动包

3.1.3.添加配置文件

c3p0是在外部添加配置文件,工具直接进行应用,因为直接引用,所以要求固定的命名和文件位置

文件位置: src

文件命名:c3p0-config.xml/c3p0.properties

c3p0.properties:

c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/student?useSSL=false&characterEncoding=utf8
c3p0.user=root
c3p0.password=123456

c3p0.acquireIncrement=5
c3p0.initialPoolSize=20
c3p0.minPoolSize=10
c3p0.maxPoolSize=50
c3p0.checkoutTimeout=5000

DbUtils_c3p0:

package com.vince.utiles;



import com.mchange.v2.c3p0.ComboPooledDataSource;

import java.sql.*;

public class DbUtils_C3p0 {

    private static ComboPooledDataSource dataSource;


    static{
        try {
            dataSource=new ComboPooledDataSource();  //默认会加载配置文件
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static Connection getConnection(){
        try {
            return  dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void closeAll(Connection conn, Statement stat, ResultSet rs){
        try {
            if(rs!=null){
                rs.close();
            }
            if(stat!=null){
                stat.close();
            }
            if(conn!=null){
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static int executeUpdate(String sql,Object...params){ //insert update delete  ?????

        Connection conn =null;
        PreparedStatement pstat=null;
        try {
            conn = getConnection();
            pstat = conn.prepareStatement(sql);
            //设置参数
            if(params!=null){
                for (int i = 0; i < params.length; i++) {
                    pstat.setObject(i+1, params[i]);
                }
            }
            return pstat.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            closeAll(conn, pstat, null);
        }
        return -1;

    }
}

 

注意:

1: c3p0的配置文件内部可以包含命名配置文件和默认配置文件!默认是选择默认配置!如果需要切换命名配置可以在创建c3p0连接池的时候填入命名即可!

2:如果xml配置文件和属性文件都存在时,xml优先级高于属性文件

 

第四节 Druid连接池

Druid 是目前比较流行的高性能的,分布式列存储的OLAP框架(具体来说是MOLAP)。它有如下几个特点:
一. 亚秒级查询
     druid提供了快速的聚合能力以及亚秒级的OLAP查询能力,多租户的设计,是面向用户分析应用的理想方式。
二.实时数据注入
     druid支持流数据的注入,并提供了数据的事件驱动,保证在实时和离线环境下事件的实效性和统一性
三.可扩展的PB级存储
     druid集群可以很方便的扩容到PB的数据量,每秒百万级别的数据注入。即便在加大数据规模的情况下,也能保证时其效性
四.多环境部署
     druid既可以运行在商业的硬件上,也可以运行在云上。它可以从多种数据系统中注入数据,包括hadoop,spark,kafka,storm和samza等
五.丰富的社区
     druid拥有丰富的社区,供大家学习

4.1 使用步骤

4.1.1 导入jar包

druid-1.1.5.jar

4.1.2 编写工具类

4.1.3 测试

druid.properties:

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/student?useSSL=false&characterEncoding=utf8
username=root
password=123456
#<!--初始化连接-->
initialSize=10
#<!--最大连接数量-->
maxActive=50
#<!--最小空连接-->
minIdle=5
maxWait=5000

 

DbUtils_Druid:


package com.vince.utiles;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

import java.beans.PropertyDescriptor;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/*
 * wgy 2019/8/26 14:28
 * 佛祖保佑,永无BUG!
 */
/*四个功能
 * (1)注册驱动(一次)
 * (2)获取连接
 * (3)释放资源
 * (4)执行SQL (增删改)
 *
 * */
public class DbUtils_Druid {



    private static DruidDataSource dataSource;
        static {
            try {
                Properties properties =new Properties();
                InputStream is = DbUtils_Druid.class.getClassLoader().getResourceAsStream("druid.properties");
                properties.load(is);
                is.close();
                dataSource =  (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    public static Connection getConnection(){

        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void closeAll(Connection conn, Statement stat, ResultSet rs){
        try {
            if(rs!=null){
                rs.close();
            }
            if(stat!=null){
                stat.close();
            }
            if(conn!=null){
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static int executeUpdate(String sql,Object...params){ //insert update delete  ?????

        Connection conn =null;
        PreparedStatement pstat=null;
        try {
            conn = getConnection();
            pstat = conn.prepareStatement(sql);
            //设置参数
            if(params!=null){
                for (int i = 0; i < params.length; i++) {
                    pstat.setObject(i+1, params[i]);
                }
            }
            return pstat.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            closeAll(conn, pstat, null);
        }
        return -1;

    }

    //返回List集合的方法
    public  static <T> List<T> findList(String sql,  Class<T> class1,Object... params){
        List<T> list=new ArrayList<>();
        Connection conn=null;
        PreparedStatement pstat=null;
        ResultSet rs=null;
        //查询数据
        try {
            conn=getConnection();
            pstat = conn.prepareStatement(sql);
            if(params!=null){
                for (int i = 0; i < params.length; i++) {
                    pstat.setObject(i+1, params[i]);
                }
            }
            rs = pstat.executeQuery();
            //获取rs中的列名
            ResultSetMetaData metaData = rs.getMetaData();
            while(rs.next()){
                //创建一个对象
                T t=convertToObject(metaData, rs, class1);
                list.add(t);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            closeAll(conn, pstat, rs);
        }

        return list;
    }



    //返回单个对象的方法
    public static <T> T findSingle(String sql,Class<T> class1,Object...params ){

        Connection conn=null;
        PreparedStatement pstat=null;
        ResultSet rs=null;
        //查询数据
        try {
            conn=getConnection();
            pstat = conn.prepareStatement(sql);
            if(params!=null){
                for (int i = 0; i < params.length; i++) {
                    pstat.setObject(i+1, params[i]);
                }
            }
            rs = pstat.executeQuery();
            //获取rs中的列名
            ResultSetMetaData metaData = rs.getMetaData();
            if(rs.next()){
                //创建一个对象
                return convertToObject(metaData, rs, class1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            closeAll(conn, pstat, rs);
        }
        return null;
    }

    public static <T> T convertToObject(ResultSetMetaData metaData,ResultSet rs,Class<T> class1){
        try {
            T t=class1.newInstance();
            for(int i=0;i<metaData.getColumnCount();i++){
                String columnLabel=metaData.getColumnLabel(i+1);
                Object value = rs.getObject(columnLabel);//empno  ename job
                //System.out.println(columnLabel+"==="+value);
                //创建属性描述符
                try {
                    PropertyDescriptor pd=new PropertyDescriptor(columnLabel, class1);
                    if(pd!=null){
                        //System.out.println(pd.getName());
                        Method writeMethod = pd.getWriteMethod(); //setEmpno setEname setJob
                        writeMethod.invoke(t,value);
                    }
                } catch (Exception e) {
                    continue;
                }
            }
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}

 

第五节 DBUtils使用

Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。

5.1 DBUtils简介

DBUtils是java编程中的数据库操作实用工具,小巧简单实用,

1.对于数据表的读操作,可以把结果转换成List,Array,Set等java集合,便于程序员操作。

2.对于数据表的写操作,也变得很简单(只需写sql语句)。

DBUtils包括主要类

DbUtils类:启动类

ResultSetHandler接口:转换类型接口

--ArrayHandler类:实现类,把记录转化成数组

--ArrayListHandler类:把记录转化成数组,并放入集合中

--ColumnListHandler类:取某一列的数据。封装到List中。

--ScalarHandler类:适合获取一行一列数据。

--BeanHandler类:实现类,把记录转成对象。

--BeanListHandler类:实现类,把记录转化成List,使记录为JavaBean类型的对象

QueryRunner类:执行SQL语句的类

 

5.2 DBUtils工具类封装

5.2.1 项目准备

  • 创建项目

  • 导入jar包 工具类 配置文件

  • commons-dbutils-1.6.jar

  • druid-1.1.5.jar

  • DruidUtils.java工具类

  • database.properties配置文件

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值