DAB模式,连接池和DBUtils应用

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

案例实现:实现emp表的查询、添加、删除、修改

1.1.1 封装DbUtils

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

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

public class DbUtils {
	private static String driver;
	private static String url;
	private static String user;
	private static String password;

	static{
	
		try {			
			driver="com.mysql.jdbc.Driver";
          	 url="jdbc:mysql://localhost:3306/school";
			//   数据库MySQL8.0使用:jdbc:mysql://localhost:3306/mydb2?	useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone = GMT	
			 user="root";
          	 password="root";
			//加载驱动
			Class.forName(driver);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	/**
	 * 获取连接
	 * @return
	 * @throws SQLException
	 */
	public static Connection getConnection() throws SQLException{
		return DriverManager.getConnection(url,user,password);
	}
	
	/**
	 * 释放资源
	 * @param rs
	 * @param stat
	 * @param conn
	 */
	public static void release(ResultSet rs,Statement stat,Connection conn){
		if(rs!=null){
			try {
				rs.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(stat!=null){
			try {
				stat.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(conn!=null){
			try {
				conn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 根据参数执行sql语句  Insert Delete Update
	 * @param sql
	 * @param params
	 * @return
	 */
	public static int executeUpdate(String sql, Object...params){
		Connection conn=null;
		PreparedStatement pstat=null;
		try {
			//1创建连接
			conn=getConnection();
			//2创建命令对象
			pstat=conn.prepareStatement(sql);
			//3设置参数
			for (int i = 0; i < params.length; i++) {
				pstat.setObject(i+1, params[i]);
			}
			//4执行
			int result=pstat.executeUpdate();
			return result;
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}finally {
			release(null, pstat, conn);
		}
	}
	
}

1.1.2优化DbUtils工具类:把数据库连接信息封装到Properties文件中

		Properties properties=new Properties();
		InputStream is=DbUtils.class.getClassLoader().getResourceAsStream("database.properties");
		properties.load(is);
		//初始化参数
		driver=properties.getProperty("driver");
		url=properties.getProperty("url");
		user=properties.getProperty("user");
		password=properties.getProperty("password");

部分改动代码:

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;
    }
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 存放实现类

在这里插入图片描述

使用DAO设计模式实现emp表的查询、添加、删除、修改

Emp类

package com12.qf0827.Demo2.domain;

import java.io.Serializable;
import java.util.Date;

/**
 * 2019/8/2720:19
 * <p>
 * 未知的事情 永远充满变数
 */
public class Emp implements Serializable {
    private static final long serialVersionUID=373910607014836778L;
    private int empno;
    private String ename;
    private String job;
    private int mgr;
    private Date hiredate;
    private double sal;
    private double comm;
    private int deptno;

    public Emp() {
    }

    public Emp(int empno, String ename, String job, int mgr, Date hiredate, double sal, double comm, int deptno) {
        this.empno = empno;
        this.ename = ename;
        this.job = job;
        this.mgr = mgr;
        this.hiredate = hiredate;
        this.sal = sal;
        this.comm = comm;
        this.deptno = deptno;
    }

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    public int getEmpno() {
        return empno;
    }

    public void setEmpno(int empno) {
        this.empno = empno;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public int getMgr() {
        return mgr;
    }

    public void setMgr(int mgr) {
        this.mgr = mgr;
    }

    public Date getHiredate() {
        return hiredate;
    }

    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }

    public double getSal() {
        return sal;
    }

    public void setSal(double sal) {
        this.sal = sal;
    }

    public double getComm() {
        return comm;
    }

    public void setComm(double comm) {
        this.comm = comm;
    }

    public int getDeptno() {
        return deptno;
    }

    public void setDeptno(int deptno) {
        this.deptno = deptno;
    }


    @Override
    public String toString() {
        return "Emp{" +
                "empno=" + empno +
                ", ename='" + ename + '\'' +
                ", job='" + job + '\'' +
                ", mgr=" + mgr +
                ", hiredate=" + hiredate +
                ", sal=" + sal +
                ", comm=" + comm +
                ", deptno=" + deptno +
                '}';
    }
}

DbUtils工具类别:

package com.qf.utils;

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;

/*
 *  2019/8/26 14:28
 */
/*四个功能
* (1)注册驱动(一次)
* (2)获取连接
* (3)释放资源
* (4)执行SQL (增删改)
*
* */
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  ?????

        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;
    }


}

db.properties 文件内容:

#驱动
driver=com.mysql.cj.jdbc.Driver
#连接字符串
url=jdbc:mysql://localhost:3306/mydb2?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone = GMT
#用户名
user=root
#密码
password=root

接口:。
package com12.qf0827.Demo2.dao;

import com12.qf0827.Demo2.domain.Emp;

import java.util.List;

/**
 * 2019/8/2720:27
 * <p>
 * 未知的事情 永远充满变数
 */

//接口
public interface EmployeeDao {

    //查询
    List<Emp>findAll();
    //更新
    void update(Emp e);
    //删除
    void delete(int empno);
    //添加
    void add(Emp e);


}

实现类

package com12.qf0827.Demo2.dao.impl;

import com12.qf0827.Demo2.dao.EmployeeDao;
import com12.qf0827.Demo2.domain.Emp;
import com12.qf0827.Demo2.utils.DbUtils;

import java.util.List;

/**
 * 2019/8/2720:37
 * <p>
 * 未知的事情 永远充满变数
 */
public class EmployeeDaoImpl implements EmployeeDao {
    @Override
    public List<Emp> findAll() {
        	ArrayList<Employee> employees=new ArrayList<Employee>();
	//1获取连接
	Connection conn=null;
	PreparedStatement pstat=null;
	ResultSet rs=null;
	try {
		conn=DbUtils.getConnection();
		pstat=conn.prepareStatement("select * from emp;");
		rs=pstat.executeQuery();
		while(rs.next()){
			int empno=rs.getInt("empno");
			String ename=rs.getString("ename");
			String job=rs.getString("job");
			int mgr=rs.getInt("mgr");
			Date date=rs.getDate("hiredate");
			double sal=rs.getDouble("sal");
			double comm=rs.getDouble("comm");
			int deptno=rs.getInt("deptno");
			
			Employee employee=new Employee(empno, ename, job, mgr, date, sal, comm, deptno);
			employees.add(employee);
		}
		return employees;
	} catch (Exception e) {
		throw new RuntimeException("查询emp失败");
	} finally {
		DbUtils.closeAll(rs, pstat, conn);
	}
	
    }

    @Override //更新
    public void update(Emp e) {
        Object[] params={e.getEname(),e.getJob(),e.getMgr(),e.getHiredate(),e.getSal(),e.getComm(),e.getDeptno(),e.getEmpno()};
            DbUtils.executeUpd("update emp set ename=?,job=?,mgr=?,hiredate=?,sal=?,comm=?,deptno=? where empno=?",params);
    }

    @Override
    public void delete(int empno) {
            DbUtils.executeUpd("delete from emp where empno=?",empno);
    }


    @Override
    public void add(Emp e) {
            Object [] params = {e.getEmpno(),e.getEname(),e.getJob(),e.getMgr(),e.getHiredate(),e.getSal(),e.getComm(),e.getDeptno()};
            DbUtils.executeUpd("insert into emp values(?,?,?,?,?,?,?,?)",params);


    }
}

测试类:

package com12.qf0827.Demo2;
import com12.qf0827.Demo2.dao.impl.EmployeeDaoImpl;
import com12.qf0827.Demo2.domain.Emp;
import org.junit.Test;

import java.util.Date;

/**
 * 2019/8/2720:16
 * <p>
 * 未知的事情 永远充满变数
 */
public class test {
    EmployeeDaoImpl empDao=new EmployeeDaoImpl();
        @Test
        public void testAdd(){

            Emp emp=new Emp(77232,"hello" ,"java开发" ,6666 ,new Date(),20000.0 ,0.0 ,20 );
            empDao.add(emp);
        }
        @Test
        public void testudpate(){

            Emp emp=new Emp(7934,"dd" ,"java开发" ,6666 ,new Date(),30000.0 ,0.0 ,20 );
            empDao.update(emp);
        }
    }

1.3 自定义实现连接池

为什么要使用连接池:

​ 用户每次请求都需要向数据库获得连接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出、拓机。

Java为连接池实现提供了一个规范(接口),规范的写法,我们需要实现DataSource接口!

package com12.qf0827.连接池.自定义连接池;

import com12.qf0827.Demo2.utils.DbUtils;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;

/**
 * 2019/8/2722:02
 * <p>
 * 未知的事情 永远充满变数
 */
public class MyDbpool implements DataSource {

    public static List<Connection> connections=null;

    static {
        connections= Collections.synchronizedList(new LinkedList<Connection>());
        for(int i=0;i<5;i++){
            Connection connection =DbUtils.getConnection();
            connections.add(connection);
        }
    }





    @Override
    public Connection getConnection() throws SQLException {
        synchronized (connections){
            if(connections.size()>0){
                Connection connection = connections.remove(0);
                System.out.println("获取一个连接池。。"+connection.hashCode());

                System.out.println("池中还有"+connections.size());
                return connection;
            }
        }

       return null;
    }


    //把连接池放入池中
    public void release(Connection connection){
        connections.add(connection);
        System.out.println("放入一个连接"+ connection.hashCode());
        System.out.println("池中还有"+connections.size());

    }



    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
}

测试:

	package com12.qf0827.连接池.自定义连接池;
	
	import java.sql.Connection;
	import java.sql.SQLException;
	
	/**
	 * 2019/8/2721:58
	 * <p>
	 * 未知的事情 永远充满变数
	 */
	public class Test01 {
	    public static void main(String[] args) {
	        MyDbpool myDbpool = new MyDbpool();
	        for (int i = 0; i <10 ; i++) {
	            try {
	                Connection conn= myDbpool.getConnection();
	                if(conn!=null){
	                    System.out.println("获取了:"+conn.hashCode());
	
	                }else {
	                    System.out.println("没有获取");
	                }
	
	            } catch (SQLException e) {
	                e.printStackTrace();
	            }
	        }



    }
}
第二节 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 日志支持

2.1.3 硬编码使用DBCP

所谓的硬编码方式就是在代码中添加配置

在DBCP连接池获取连接 在代码中写入连接信息
连接成功后更改表emp的信息sal 为5002.0 然后关闭连接释放资源

代码:

package com.qf.c3p0;

import org.apache.commons.dbcp2.BasicDataSource;
import org.junit.Test;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * 2019/9/117:57
 * <p>
 * 未知的事情 永远充满变数
 */
public class Test1 {

    @Test
    public void demo1() throws Exception{
    	//TODO 硬编码 使用DBCP连接池子
        BasicDataSource source = new BasicDataSource();
        //设置连接信息
        source.setDriverClassName("com.mysql.cj.jdbc.Driver");
        source.setUrl("jdbc:mysql://localhost:3306/mydb2?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone = GMT");
        source.setUsername("root");
        source.setPassword("root");
        Statement   stat=null;
        Connection connection=null;
        try {
             connection = source.getConnection();
            System.out.println("连接成功!");
             stat = connection.createStatement();
             int s =stat.executeUpdate("update emp set sal=5002.0 where empno=7369");
            System.out.println(s);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            stat.close();
            connection.close();
        }
    }
}
2.1.4 软编码使用DBCP

所谓的软编码,就是在项目中添加配置文件,这样就不需要每次代码中添加配合!

  1. 项目中添加配置

文件名称: dbcp.properties

​ 文件位置: src下

#连接设置
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb2?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone = GMT
username=root
password=root
#<!-- 初始化连接-->
initialSize=10
#最大连接数
maxTotal=50
#<!-- 最大空闲连接数-->
maxIdle=20
#<!-- 最小空闲连接-->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒
maxWaitMillis=5000

代码实现

package com.qf.c3p0;

import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.junit.Test;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.Statement;
import java.util.Properties;

/**
 * 2019/9/119:07
 * <p>
 * 未知的事情 永远充满变数
 */
public class Test2 {
    // 软编码使用连接池
    @Test
    public void testSoft()throws Exception{
        Properties properties = new Properties();

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

        //生成连接池子 需要配置文件
       //InputStream is = Test2.class.getClassLoader().getResourceAsStream("properties");
        DataSource source = BasicDataSourceFactory.createDataSource(properties);
        Connection connection = source.getConnection();
        Statement stat =connection.createStatement();
        int s =stat.executeUpdate("update emp set sal=5003.0 where empno=7369");
        System.out.println(s);
        stat.close();
        connection.close();

    }
}

第三节 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-config>
	<!-- 默认配置,如果没有指定则使用这个配置 -->
	<default-config>
		<!-- 基本配置 -->
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/school</property>
		<property name="user">root</property>
		<property name="password">root</property>
		<!--扩展配置-->
		<!-- 连接超过10秒报错-->
		<property name="checkoutTimeout">10000</property>
		<!--30秒检查空闲连接 -->
		<property name="idleConnectionTestPeriod">30</property>
		<!-- 初始大小 -->
		<property name="initialPoolSize">10</property>
		<!-- 每次增长的个数 -->
		<property name="acquireIncrement">5</property>
		 <!-- 30秒不适用丢弃-->
		<property name="maxIdleTime">30</property>
		<property name="maxPoolSize">50</property>
		<property name="minPoolSize">5</property>
	</default-config> 
	<!-- 命名的配置 -->
	<named-config name="bj1805">
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/day2</property>
		<property name="user">root</property>
		<property name="password">111</property>
		<!-- 如果池中数据连接不够时一次增长多少个 -->
		<property name="acquireIncrement">5</property>
		<property name="initialPoolSize">20</property>
		<property name="minPoolSize">10</property>
        <property name="maxPoolSize">40</property>
	</named-config>
</c3p0-config> 

c3p0.properties

c3p0.driverClass=com.mysql.cj.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/mydb2? 	useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone = GMT
c3p0.user=root
c3p0.password=root
c3p0.acquireIncrement=5
c3p0.initialPoolSize=20
c3p0.minPoolSize=10
c3p0.maxPoolSize=40
c3p0.checkoutTimeout=5000

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

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

package com.qf.c3p0;


import com.mchange.v2.c3p0.ComboPooledDataSource;

import java.sql.Connection;
import java.sql.Statement;

/**
 * 2019/9/122:48
 * <p>
 * 未知的事情 永远充满变数
 */
public class Test01 {

    public static void main(String[] args)throws Exception {
        //创建ComboPooledDataSource对象使用默认配置、
        ComboPooledDataSource  dataSource = new ComboPooledDataSource();
        //1创建C3P0连接池子
        Connection connection = dataSource.getConnection();

        Statement createStatment = connection.createStatement();

        int s =createStatment.executeUpdate("update emp set sal=5004.0 where empno=7369");
        System.out.println(s);
        createStatment.close();         //"update emp set sal=5003.0 where empno=7369"
        createStatment.close();

    }
}

第四节 Druid连接池

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

配置文件 database.properties:

#连接设置
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:jdbc:mysql://localhost:3306/mydb2? 	useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone = GMT
username=root
password=root
#<!-- 初始化连接 -->
initialSize=10
#最大连接数量
maxActive=50
#<!-- 最小空闲连接 -->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=5000
4.1.1 导入jar包

​ druid-1.1.5.jar

4.1.2 编写工具类
	package com.qf.druid;

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

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * 2019/9/28:42
 * <p>
 * 未知的事情 永远充满变数
 */
public class TEst01 {
    private static DruidDataSource ds;
    static{
        //实列化配置对象
        Properties properties= new Properties();
        try {
           // properties.load(TEst01.class.getResourceAsStream("database.properties")); 会报空指针异常
            properties.load(new FileInputStream("database.properties"));
                ds = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
            public static Connection getConnection(){
                try {
                    return ds.getConnection();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                return null;
            }
}

4.1.3 测试

package com.qf.utils;

import java.sql.Connection;

public class Test {
	public static void main(String[] args) throws Exception {
		for(int i=0;i<100;i++) {
			Connection connection=DbUtils.getConnection();
			if(connection!=null) {
				System.out.println("连接成功"+i+"..."+connection.hashCode()+connection.toString());
			}
			connection.close();
		}
	}
}
第五节 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配置文件(同上)

      package com.qf.druid;
      
      import com.alibaba.druid.pool.DruidDataSource;
      import com.alibaba.druid.pool.DruidDataSourceFactory;
      
      import java.io.FileInputStream;
      import java.io.InputStream;
      import java.util.Properties;
      
      /**
       * 2019/9/218:55
       * <p>
       * 未知的事情 永远充满变数
       */
      public class DruidUtils {
          private static DruidDataSource dataSource;
      
          static {
              try {
              Properties properties = new Properties();
              InputStream is =new  FileInputStream("database.properties");
      
                  properties.load(is);
                  dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
      
              } catch (Exception e) {
                  e.printStackTrace();
              }
      
      
       	   }
      
      
      	    public static DruidDataSource getDataSource(){
      	        return dataSource;
      	    }
      	
      	
      		}
    

package com.qf.DBUtils;

import com.qf.druid.DruidUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.*;
import org.junit.Test;

import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;

/**

  • 2019/9/219:00

  • 未知的事情 永远充满变数
    */
    public class ResultHanlder {
    @Test
    public void testArrayHander()throws SQLException{
    //ArrayHandler:适合读取一条记录。把该记录的每列值封装到一个数组OBject中
    QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
    Object[] arr = qr.query(“select * from emp where empno=?”,new ArrayHandler(),7499);
    Object[] arr1 = qr.query("select * from emp ",new ArrayHandler());
    for (Object o : arr1) {
    System.out.println(o);
    }

    }

    @Test
    public void testArrayListHander() throws Exception{
    //ArrayListHandler 适合读取多tiao记录 然后把其封装到集合中
    QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());

     List<Object[]> query = qr.query("select * from emp",new ArrayListHandler());
    
     for (Object[] objects : query) {
         System.out.println(Arrays.toString(objects));
     }
    

    }
    @Test
    public void testColumnListHander()throws Exception{
    //ColumnListHandler 取某一列的数据 ,封装到List中
    QueryRunner runner = new QueryRunner(DruidUtils.getDataSource());
    List qu = runner.query(“select * from emp”,new ColumnListHandler() );
    for (Object o : qu) {
    System.out.println(o);
    }

    }

    @Test
    public void testScalarHandler()throws Exception{

         QueryRunner runner = new QueryRunner(DruidUtils.getDataSource());
    
         Object qery = runner.query("select count(*) from emp", new ScalarHandler<>());
      System.out.println(qery);
    
     }
    
    
    @Test
     public void testBeanListHandler() throws SQLException {
     	// BeanHandler:适合取多行多列数据
     	QueryRunner runner = new QueryRunner(DruidUtils.getDataSource());
     	List<Employee> query2 = runner.query("select * from emp", new BeanListHandler<Employee>(Employee.class));
     	for (Employee employee : query2) {
     		System.out.println(employee);
     	}
     }
    
    
    
     }
    
    总结

1 封装工具类

2 Dao设计模式: 把数据访问代码抽离出来。降低代码的耦合性和提高扩展性。

​ dao接口

​ dao实现

​ 实体类

​ 数据库工具类

3 连接池

​ dbcp

​ c3p0

​ druid重点

4 Dbutils工具

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值