Java之数据库连接封装成工具类,三个核心(DBUtils,QueryRunner,ResultSetHandler8个结果集)的使用和数据源DataSource(数据库连接池)

一.数据库连接封装成工具类

1.数据库连接封装成工具类的方法
第一种:不用把加载驱动的字符串和数据库地址,用户,密码写在代码的形式(更改地址,用户,密码等需要从代码中更改,不太方便):
这里需要用到静态代码块,因为驱动是只加载一次就可以.

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

/*
 * 封装获取连接工具
 */
public class JDBCUtil1 {
	// 声明连接
	private static Connection connection;
	// 注册驱动
	static{		
		try {
			// 只注册一次
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			// 直接抛个运行时异常
			throw new RuntimeException("注册驱动失败");
		}
	}
	// 私有化构造方法
	private JDBCUtil1() {
	}
	// 获取连接方法
	public static Connection getConnection(){
		// 数据库地址
		String url = "jdbc:mysql://localhost:3306/klljdbc01";
		// 数据库账号
		String user = "root";
		// 数据库密码
		String password = "123456";
		// 获取连接
		try {
			connection = DriverManager.getConnection(url, user, password);
			
		} catch (SQLException e) {
			e.printStackTrace();
			// 直接抛个运行时异常
			throw new RuntimeException("数据库连接失败");
		}
		
		return connection;
	}
	// 关闭资源
	public static void myClose(Connection connection, ResultSet resultSet,Statement statement){
		// 关闭资源
		if (connection != null) {
			try {
				connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (statement != null) {
			try {
				connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (resultSet != null) {
			try {
				connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

第二种:使用从文本读入的方式,环境变了,更改地址用户密码等直接从文本更改.
注意:文本只能创建在src文件夹下
此处使用到了通过类加载器直接获取bin文件夹下的文件的字节流方法

本类类名.class.getClassLoader().getResourceAsStream("文件名");

文件(文件名:db.properties)内容:
在这里插入图片描述

/*
 * 读取文件的数据库连接工具类
 */
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JDBCUtil2 {
	private static Connection connection;
	private static String driverClass;
	private static String url;
	private static String user;
	private static String password;

	private JDBCUtil2() {
	}
	
	static{
		// 只读一次文件
		readFile();
		// 只注册驱动一次
		try {
			Class.forName(driverClass);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			// 运行时异常
			throw new RuntimeException("加载驱动异常");
		}
	}
	
	// 读文件方法
	public static void readFile() {
		// 通过类加载器直接获取bin文件夹下的文件的字节流
		// 获取类加载器
		InputStream ist = JDBCUtil2.class.getClassLoader().getResourceAsStream("db.properties");
		Properties properties = new Properties();
		try {
			properties.load(ist);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		driverClass = properties.getProperty("driverClass");
		url = properties.getProperty("url");
		user = properties.getProperty("user");
		password = properties.getProperty("password");
	}
	// 获取连接
	public static Connection getConnection() {
		
		try {
			// 获取连接
			connection = DriverManager.getConnection(url, user, password);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			// 抛出运行时异常
			throw new RuntimeException("连接失败");
		}
		return connection;
	}
	// 关闭方法
	public static void myClose(Connection connection, Statement statement, ResultSet resultSet) {
		if (connection != null) {
			try {
				connection.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (statement != null) {
			try {
				connection.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (resultSet != null) {
			try {
				connection.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

2.查询记录封装成方法
数据库sort表对应的实体类.

  • 表中字段 就是实体类中成员变量
  • 为了表示null值,一般把基本数据类型声明成包装类
    sort表:Java之数据库连接封装成工具类,三个核心(DBUtils,QueryRunner,ResultSetHandler8个结果集)的使用和数据源DataSource(数据库连接池)_第1张图片
    sort实体类:
public class Sort {
	
	private Integer sid;
	private String sname;
	private Double sprice;
	private String sdesc;
	// 构造方法
	public Sort() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Sort(Integer sid, String sname, Double sprice, String sdesc) {
		super();
		this.sid = sid;
		this.sname = sname;
		this.sprice = sprice;
		this.sdesc = sdesc;
	}
	// set/get方法
	public Integer getSid() {
		return sid;
	}
	public void setSid(Integer sid) {
		this.sid = sid;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public Double getSprice() {
		return sprice;
	}
	public void setSprice(Double sprice) {
		this.sprice = sprice;
	}
	public String getSdesc() {
		return sdesc;
	}
	public void setSdesc(String sdesc) {
		this.sdesc = sdesc;
	}
	// 重写tostring方法
	@Override
	public String toString() {
		return "[sid=" + sid + ", sname=" + sname + ", sprice=" + sprice + ", sdesc=" + sdesc + "]";
	}	
}

工具类的使用代码如下(打印全表信息):

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/*
 * 测试
 */
public class Demo01 {
	public static void main(String[] args) throws Exception {
		// 获取连接
		Connection connection = JDBCUtil2.getConnection();
		// 获取sql执行对象
		String sql = "select * from sort";
		PreparedStatement statement = connection.prepareStatement(sql);
		// 获取sql执行语句
		ResultSet resultSet = statement.executeQuery();
		while (resultSet.next()) {
			// 创建对象
			Sort sort = new Sort();
			sort.setSid(resultSet.getInt("sid"));
			sort.setSname(resultSet.getString("sname"));
			sort.setSdesc(resultSet.getString("sdesc"));
			sort.setSprice(resultSet.getDouble("sprice"));
			System.out.println(sort);
		}
		JDBCUtil2.myClose(connection, statement, resultSet);
	}
}

运行结果:
Java之数据库连接封装成工具类,三个核心(DBUtils,QueryRunner,ResultSetHandler8个结果集)的使用和数据源DataSource(数据库连接池)_第2张图片

二.三个核心

Commons-dbutils(提供快速操作的数据库方法)
1.DBUtils

  • 提供了 closeQuietly(Connection conn)方法
  • 安静的关闭 不用你来处理异常

2.DataSource

  • 查询方法
    • query(Connection conn, String sql, ResultSetHandler rsh, Object… params)
    • 参数1:数据库的连接对象
    • 参数2:sql语句(可以使用?占位符)
    • 参数3:查询后得到的结果集(可以选用不同类型的结果集)
    • 参数4:替换sql语句的占位符
  • 更新方法(插入 删除 修改)
    • pdate(Connection conn, String sql, Object… params)

DataSource的查询和更新方法使用如下:

import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;

/*
 * Commons-dbutils(提供快速操作的数据库方法)
 * 三个核心
 *   1.DBUtils
 *     提供了 closeQuietly(Connection conn)方法
 *     安静的关闭 不用你来处理异常
 *   2.QueryRunner
 *    查询方法
 *     query(Connection conn, String sql,
 *      ResultSetHandler rsh, Object... params)
 *     参数1:数据库的连接对象
 *     参数2:sql语句(可以使用?占位符)
 *     参数3:查询后得到的结果集(可以选用不同类型的结果集)
 *     参数4:替换sql语句的占位符
 *    更新方法(插入 删除 修改)
 *      update(Connection conn, String sql, Object... params)
 *      /
public class Kll {
	public static void main(String[] args) throws Exception {
		// 调用方法: 是插入数据
		fun1();
		// 调用方法 删除id=3的数据
		fun2();
		// 修改id=8 为 毛毯 200 还不错呀
		Connection connection = JDBCUtil2.getConnection();
		QueryRunner runner = new QueryRunner();
		String sql = "update sort set sname=?,sprice=?,sdesc=? where sid=?";
		Object[] param = {"毛毯", 200 , "还不错呀", 8};
		int update = runner.update(connection, sql, param);
		System.out.println(update);
		// 关闭资源
		DbUtils.closeQuietly(connection);
		
	}

	public static void fun2() throws SQLException {
		// 删除id = 3
		QueryRunner runner = new QueryRunner();
		Connection connection = JDBCUtil2.getConnection();
		String sql = "delete from sort where sid=? ";
		// 结束影响的行数
		int update = runner.update(connection, sql, 3);
		System.out.println(update);
		// 关闭资源
		DbUtils.closeQuietly(connection);
	}

	public static void fun1() throws SQLException {
		// 插入
		// 创建查询对象
		QueryRunner runner = new QueryRunner();
		Connection conn = JDBCUtil2.getConnection();
		String sql = "insert into sort values (null,?,?,?)";
		// 创建数组
		Object[] params = {"发卡",12.5,"包邮"};
		int i = runner.update(conn, sql, params);
		// 打印受影响的行数
		System.out.println(i);
		int update = runner.update(conn, sql, "水桶",23.5,"包邮");
		System.out.println(update);
		// 关闭资源
		DbUtils.closeQuietly(conn);
	}
}

3.ResultSetHandler(提供8个结果集供人使用)

  • ArrayHandler :默认返回查询的第一条数据,并且把该数据放入object数组中返回.
  • ArrayListHandler:可以返回多条记录,并且每一条记录放在object数组中, 然后把多条记录又放在list集合中返回.
  • BeanHandler:(查询的是多条数据,只返回第一条)
    • 注意:要封装的对象必须符合Javabean规范(有set,get方法,有参无参构造方法)
  • ** BeanListHandler:返回保存好对象的list集合.(常用)**
    * 注意和BeanHandler的要求一样.
  • ColumnListHandler:默认返回数据库中第一列数据的集合,也可以传入参数字段名或者列的顺序.
  • ScalarHandler:获取聚合函数返回的数据 返回的是long型.
  • MapHandler::默认返回查询的map集合,此集合是封装的第一条数据的字段名和对应的值;集合中,key值是字段名,value是字段对应的值.
  • MapListHandler:是把每一条记录的字段名和对应的值放在map集合中,然后再把map集合放在list集合中,返回list集合.

以下是8个结果集的应运:

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

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

/*
 * 查询的8个结果集
 		ArrayHandler
		ArrayListHandler
		BeanHandler
		BeanListHandler
		ColumnListHandler
		ScalarHandler
		MapHandler
		MapListHandler
 */
public class Kll {
	public static void main(String[] args) throws SQLException {
		
		String sql = "select * from sort";
		QueryRunner runner = new QueryRunner();
		Connection conn = JDBCUtil2.getConnection();
		//fun1(sql, runner, conn);
		//fun2(sql, runner, conn);
		//fun3(sql, runner, conn);
		//fun4(sql, runner, conn);
		//fun5(sql, runner, conn);
		//fun6(runner, conn);
		
		fun7(sql, runner, conn);
		// MapListHandler
		List> query2 = runner.query(conn, sql, new MapListHandler());
		for (Map map : query2) {
			for (String key : map.keySet()) {
				System.out.print(key + " " + map.get(key));
			}
			System.out.println();
		}
		
		// 关闭
		DbUtils.closeQuietly(conn);
	}
	public static void fun7(String sql, QueryRunner runner, Connection conn) throws SQLException {
		// MapHandler
		Map map = runner.query(conn, sql, new MapHandler());
		System.out.println(map);
	}
	public static void fun6(QueryRunner runner, Connection conn) throws SQLException {
		// ScalarHandler
		//获取聚合函数返回的数据 返回的是long型
		String sql1 = "select count(*) from sort";
		Number number = runner.query(conn, sql1, new ScalarHandler());
		System.out.println(number.longValue());
	}
	public static void fun5(String sql, QueryRunner runner, Connection conn) throws SQLException {
		// ColumnListHandler
		// 默认返回数据库中第一列数据的集合
		// 可以传入参数字段名或者列的顺序
		List list2 = runner.query(conn, sql, new ColumnListHandler<>());
		for (Object object : list2) {
			System.out.println(object);
		}
	}
	public static void fun4(String sql, QueryRunner runner, Connection conn) throws SQLException {
		// BeanListHandler(常用)
		// 返回保存好对象的list集合
		List list = runner.query(conn, sql, new BeanListHandler(Sort.class));
		for (Sort sort : list) {
			System.out.println(sort);
		}
	}
	public static void fun3(String sql, QueryRunner runner, Connection conn) throws SQLException {
		// BeanHandler(查询的是多条数据,只返回第一条)
		// 注意:要封装的对象必须符合Javabean规范(有set,get方法,有参无参构造方法)
		Sort query = runner.query(conn, sql, new BeanHandler(Sort.class));
		System.out.println(query);
	}
	public static void fun2(String sql, QueryRunner runner, Connection conn) throws SQLException {
		// ArrayListHandler
		// 可以返回多条记录,并且每一条记录放在object数组中
		// 然后把多条记录又放在list集合中返回
		List query = runner.query(conn, sql, new ArrayListHandler());
		for (Object[] objects : query) {
			for (Object object : objects) {
				System.out.print(object + " ");
			}
			System.out.println();
		}
	}
		// 测试ArrayHandler
		// 默认返回查询的第一条数据,并且把该数据放入object数组中返回
	public static void fun1(String sql, QueryRunner runner, Connection conn) throws SQLException {
		Object[] query = runner.query(conn, sql, new ArrayHandler());
		System.out.println(Arrays.toString(query));
	}
}
 
  

三.数据源DataSource(数据库连接池)

  • DataSource 数据源(数据库连接池)

  • 查询时 创建和销毁连接 耗费资源

  • 使用数据库连接池可以解决这个问题

  • 查询时 会从数据库连接池中 找一个空闲的连接 去查询数据库

  • 查询完毕后 不会销毁该连接 会重新放入连接池中 等待下一次使用

  • Java也提供一套规范来处理数据库连接池问题

  • javax.sql DataSource

  • 这套规范也是厂商来实现 我们只要使用实现好的方法就好

  • 连接池:DBCP C3P0

  • 使用DBCP需要导入两个jar包

  • commons-pool-1.5.6.jar

  • commons-dbcp-1.4.jar

1.直接使用代码如下:

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

import org.apache.commons.dbcp.BasicDataSource;
public class Kll {
	public static void main(String[] args) throws SQLException {
		// 创建数据库连接池
		BasicDataSource dataSource = new BasicDataSource();
		// 基础设置(地址 账号 密码)
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://localhost:3306/klljdbc01");
		dataSource.setUsername("root");
		dataSource.setPassword("123456");
		// 获取连接
		Connection connection = dataSource.getConnection();	
	}
}

封装成工具类的方法下章继续.

你可能感兴趣的:(java,数据库)