JDBC、连接池和DBUtil

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

    1.1)JDBC(Java 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工具开发,这样会极大的节省系统资源,提高开发效率!(重点)

---------------------

作者:langao_

来源:CSDN

原文:https://blog.csdn.net/langao_q/article/details/81052042

版权声明:本文为博主原创文章,转载请附上博文链接!

推荐阅读更多精彩内容