JDBC&连接池&DBUtil

1.jdbc简介(本文使用的数据库为MySQL)

    1.1)JDBCJava DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种数据库提供统一的访问(支持多种数据库)。即:用Java语言来操作数据库,JDBC是sun公司提供的的一套规范(mysql,sql server,oracle都需要遵循)

    

    2.1)jdbc原理

    应用程序    >JDBC    >数据库驱动    >数据库

    

    JDBC是接口,而JDBC驱动才是接口的实现,没有驱动就无法完成数据库连接,每个数据库厂商都使用自己的驱动 用来连接自己的驱动


    3.1)jdbc核心类(接口)

    JDBC中的核心类有:DriverManager、Connection、Statement,和ResultSet!使用时记得导入MySQL驱动包    

    1.1)DriverManager:驱动管理

    注册驱动:可以让JDBC知道要使用的是那个驱动

Class.forName(“com.mysql.jdbc.Driver”);

    

    1.2)Connection:数据库连接,数据库操作基于此对象,通过方法获取Statement对象

    获取Connection:可以获取到Connection,如果能获取Connection说明数据库连接成功

String url ="jdbc:mysql://127.0.0.1:3306/数据库名称?useUnicode=true&characterEncoding=utf8";
String username="root";
String password="123";
conn = DriverManager.getConnection(url,username,password);


    1.3)Statement:向数据库发送sql语句,在实际开发中使用的是PreparedStatement(预编译声明)

Statement stmt = con.createStatement();

    executeUpdate():更新操作(增,删,改)

    executeQuery():查询操作


    1.4)ResultSet:查询结果集,只有在sql语句执行后才会产生结果集,结果集是一个二位表格,有行有列

    next():使“行光标”移动到下一行,并返回移动后是否有数据,遍历结果集

    getInt(index):获取第index行的数据


    1.5)close:与io流一样使用后需要关闭,先创建的后关闭,后创建的先关闭

rs.close();
stmt.close();
con.close();

    

    1.6)一个用户登陆JDBC方法实例

public void login1(String username, String password) throws ClassNotFoundException, SQLException {
		// 1.注册驱动
		Class.forName("com.mysql.jdbc.Driver");
		// 2.获取连接
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web08", "root", "123");
		// 3.编写sql语句
		String sql = "select * from tbl_user where uname=? and upassword=?";
		// 4.创建预处理对象
		PreparedStatement pstmt = conn.prepareStatement(sql);
		// 5.设置参数(给占位符)
		pstmt.setString(1, username);
		pstmt.setString(2, password);
		// 6.执行查询操作
		ResultSet rs = pstmt.executeQuery();
		// 7.对结果集进行处理
		if (rs.next()) {
			System.out.println("恭喜您," + username + ",登录成功!");
			System.out.println(sql);
		} else {
			System.out.println("账号或密码错误!");
		}
		if (rs != null)
			rs.close();
		if (pstmt != null)
			pstmt.close();
		if (conn != null)
			conn.close();
	}

    

    1.7)JDBC工具类封装
public class JDBCUtil {
	private static String driver;
	private static String url;
	private static String username;
	private static String password;
	
	/**
	 * 静态代码块加载配置文件信息
	 */
	static {
		try {
			// 1.通过当前类获取类加载器
			ClassLoader classLoader = JDBCUtil.class.getClassLoader();
			// 2.通过类加载器的方法获得一个输入流
			InputStream is = classLoader.getResourceAsStream("db.properties");
			// 3.创建一个properties对象
			Properties props = new Properties();
			// 4.加载输入流
			props.load(is);
			// 5.获取相关参数的值
			driver = props.getProperty("driver");
			url = props.getProperty("url");
			username = props.getProperty("username");
			password = props.getProperty("password");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取连接方法
	 * 
	 * @return
	 */
	public static Connection getConnection() {
		Connection conn = null;
		try {
			Class.forName(driver);
			conn = DriverManager.getConnection(url, username, password);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}
	/**
	 * 释放资源方法
	 * 
	 * @param conn
	 * @param pstmt
	 * @param rs
	 */
	public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs) {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (pstmt != null) {
			try {
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

	}
}
    db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/web08?useUnicode=true&characterEncoding=utf8
username=root
password=123456
 

2.连接池

    包含自定义连接池c3p0连接池大多数使用),dcbp连接池(少数使用)!使用时需要导入相应到jar包,自定义不用

   连接池:用池来管理Connection,这样可以重复使用Connection。连接池会自己创建Connection,使用时通过池来获取Connection对象,当使用完后再将Connection归还到池中去。池就可以再利用这个Connection

    

    2.1)自定义连接池(通过JDBCUtil获取的连接)

    自定义类(implements DataSource)    >定义一个容器用于储存Connection对象    >创建5个连接对象放到容器中去    >获取连接的方法    >归还连接方法

/*
 * 连接池类
 */
public class MyDataSource implements DataSource{
	//1.定义一个容器用于储存Connection对象,list集合中LinkedList	比较适合插入和删除,ArrayList适合数据查询和更新
	private static LinkedList<Connection> pool = new LinkedList<Connection>();
	//2.创建5个连接对象放到容器中去
	static{
		for (int i = 0; i < 5; i++) {
			Connection conn = JDBCUtil.getConnection();
			pool.add(conn);
		}
	}
	//重写获取连接的方法
	@Override
	public Connection getConnection() throws SQLException {
		Connection conn = null;
		//3.先判断一下,conn里面是否有连接,没有就创建,有就直接使用
		if(pool==null){
			for (int i = 0; i < 5; i++) {
				conn = JDBCUtil.getConnection();//使用的时1.7)JDBCUtil获取连接
				pool.add(conn);
			}
		}
		//4.从池子中取出连接
		conn = pool.remove(0);
		return conn;
	}
	//归还连接到连接池中的方法(类似于close方法)
	public void backClose(Connection conn){
		pool.add(conn);
	}
    

    2.2)c3p0连接池:通过 c3p0-config.xml配置文件获取连接

    是一个免费开源的连接池!使用的开源项目有:Spring,Hibernate等

    导入jar包(c3p0-0.9.1.2.jar)    >c3p0-config.xml(必须此文件名)    >编写工具类    >使用

    

    c3p0-config.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<!-- 默认执行 -->
  <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
	<property name="jdbcUrl">jdbc:mysql:///web08</property>
	<property name="user">root</property>
	<property name="password">123456</property>
	<property name="initialPoolSize">5</property>
	<property name="maxPoolSize">20</property>
  </default-config>
  
  <!-- 指定名称执行 -->
  <named-config name="imwj"> 
    <property name="driverClass">com.mysql.jdbc.Driver</property>
	<property name="jdbcUrl">jdbc:mysql:///web08</property>
	<property name="user">root</property>
	<property name="password">123456</property>
  </named-config>

</c3p0-config>
<!-- 此文件的名称必须是 c3p0-config.xml-->

    编写工具类

package com.imwj.jdbc.utils;

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

import com.mchange.v2.c3p0.ComboPooledDataSource;
/*
 * c3p0工具类
 */
public class C3p0Util {
	//此处如果不写imwj就会执行默认的配置文件
	private static ComboPooledDataSource dataSource = new ComboPooledDataSource("imwj");
	
	//返回一个DataSource连接
	public static ComboPooledDataSource getDataSource(){
		return dataSource;
	}
	
	//返回一个Connection连接
	public static Connection getConnection() throws SQLException{
			return dataSource.getConnection();
	}
	
}


    使用

package com.imwj.jdbc.test;

import java.sql.Connection;
import java.sql.PreparedStatement;

import org.junit.Test;

import com.imwj.jdbc.utils.C3p0Util;
import com.imwj.jdbc.utils.JDBCUtil;

public class testC3p0 {
	@Test
	public void testC3p0Util(){
		 Connection conn =null;
		 PreparedStatement pstmt = null;
		 try{
			 String sql = "insert into tbl_user values(null,?,?)";
			 conn = C3p0Util.getConnection();
			 pstmt = conn.prepareStatement(sql);
			 pstmt.setString(1, "admin5");
			 pstmt.setString(2, "12345");
			 int rows = pstmt.executeUpdate();
			 if(rows!=0){
				 System.out.println("数据添加成功");
			 }else{
				 System.out.println("数据添加失败");
			 }
		 }catch(Exception e){
			 throw new RuntimeException(e);
		 }finally{
			 JDBCUtil.release(conn, pstmt, null);
		 }
	}
}


    2.3)dcbp连接池:通过db.properties配置文件获取连接

    也是一个开源连接池,是Apache Common成员之一,tomcat内置连接池

    导入jar包(commons-dbcp-1.4.jar,commons-pool-1.5.6.jar)    >配置文件    >编写工具类    >使用

    

    db.properties配置文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/web08?useUnicode=true&characterEncoding=utf8
username=root
password=123456


    编写工具类

package com.imwj.jdbc.utils;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;

public class dbcpUtil {
	private static DataSource dataSource;
	static{
		try {
			//1.加载db.properties文件输入流
			InputStream in = dbcpUtil.class.getClassLoader().getResourceAsStream("db.properties");
			
			//2.读取输入流
			Properties props = new Properties();
			props.load(in);
			
			//3.创建数据源
			dataSource = BasicDataSourceFactory.createDataSource(props);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static DataSource getDataSource(){
		return dataSource;
	}
	public static Connection getConnection() throws SQLException{
		return dataSource.getConnection();
	}
}


    使用

package com.imwj.jdbc.test;

import java.sql.Connection;
import java.sql.PreparedStatement;

import org.junit.Test;

import com.imwj.jdbc.utils.JDBCUtil;
import com.imwj.jdbc.utils.dbcpUtil;

public class testDbcp {
	@Test
	public void testC3p0Util(){
		 Connection conn =null;
		 PreparedStatement pstmt = null;
		 try{
			 String sql = "insert into tbl_user values(null,?,?)";
			 conn = dbcpUtil.getConnection();
			 pstmt = conn.prepareStatement(sql);
			 pstmt.setString(1, "admin5");
			 pstmt.setString(2, "12345");
			 int rows = pstmt.executeUpdate();
			 if(rows!=0){
				 System.out.println("数据添加成功");
			 }else{
				 System.out.println("数据添加失败");
			 }
		 }catch(Exception e){
			 throw new RuntimeException(e);
		 }finally{
			 JDBCUtil.release(conn, pstmt, null);
		 }
		
	}
}


3.DBUtil(划重点)

   如果只是使用JDBC开发,冗余代码过多,为了简化开发便使用DButil,也是Apache Common成员之一。DBUtil是用了连接池,SQL语句并没有减少

    导入jar包(commons-dbutils-1.4.jar)    >编写JavaBean    >创建QueryRunner对象(并传入dataSource)    >执行SQL语句后ResultSetHandler结果集接收

    3.1)JavaBean:数据库表的映射

    要求:JavaBean写在domian目录下属性是私有字段:private;有get/set方法 提供无参构造方法

package com.imwj.domain;

public class User {
	private int uid;
	private String uname;
	private String upassword;

	public User() {
		super();
		// TODO Auto-generated constructor stub
	}
	
	public int getUid() {
		return uid;
	}
	public void setUid(int uid) {
		this.uid = uid;
	}
	public String getUname() {
		return uname;
	}
	public void setUname(String uname) {
		this.uname = uname;
	}
	public String getUpassword() {
		return upassword;
	}
	public void setUpassword(String upassword) {
		this.upassword = upassword;
	}

}

    

    3.2)QueryRunner对象:通过c3p0获取数据源

    QueryRunner(DataSource ds):提供数据源(连接池)

//1.创建QueryRunner对象,并传入dataSource
QueryRunner qr = new QueryRunner(C3p0Util.getDataSource());

    update(String sql,Object parmas):执行增、删、改操作,parmas是一个数组,即占位符的内容

//2.编写sql语句
String sql = "insert into tbl_user values(null,?,?)";
//3.占位符数组
Object params[] = {"admin6","123456"};
//4.执行sql语句
int rows = qr.update(sql, params);//此处需抛出异常

    query(String sql,ResultSetHandler<T> rsh,Object parmas):执行查询类操作

List<User> users = qr.query(sql, new BeanListHandler<User>(User.class));


    3.3)ResultSetHandler对象

    BeanHandler:将结果集中的第一条记录封装到一个指定的JavaBean中,查询单条数据时使用

User user = qr.query(sql, new BeanHandler<User>(User.class), params);//查询单个用户select * from tbl_user where uid=?

    BeanListHandler:将结果集中的每一条记录封装到指定的JavaBean中,再将JavaBean封装到List中,查询多条或所有数据时使用

List<User> users = qr.query(sql, new BeanListHandler<User>(User.class));//查询所有用户select * from tbl_user

    ScalarHandler:用于单数据,栗子:select count(*) from tbl_user 时使用

Long count = (Long) qr.query(sql, new ScalarHandler());//查询数据总行数select count(*) from tbl_user

    以下几个作了解

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

    ArrayListHandler:将结果集的每一条数据都封装到一个Object[]数组中,再将数组封装到List集合中

    ColumnListHandler:指定查询列名,再将结果封装到一个List集合中

    MapHandler:将结果集的第一条数据封装到Map<String,Object>,key就是字段名称,value就是字段的值

    MapListHandler:将结果集的每一条都数据封装到Map<String,Object>,再将Map封装到List集合中


    3.4)DBUtil栗子:

//查询所有用户,BeanListHandler
	@Test
	public void selectAllUser(){
		try {
			//1.创建QueryRunner对象,并传入dataSource
			QueryRunner qr = new QueryRunner(C3p0Util.getDataSource());
			//2.编写sql语句
			String sql = "select * from tbl_user";//省略了3.占位符数组
			//4.执行sql语句
			List<User> users = qr.query(sql, new BeanListHandler<User>(User.class));
			//5.遍历结果集
			for (User user : users) {
				System.out.println(user.getUname()+":"+user.getUpassword());
			}
		} catch (SQLException e1) {
			// TODO Auto-generated catch block
			throw new RuntimeException(e);
		}
	}
    在不使用框架的前提下,绝大多数都是使用DBUtil工具开发,这样会极大的节省系统资源,提高开发效率!(重点)
    

猜你喜欢

转载自blog.csdn.net/langao_q/article/details/81052042