JDBC使用+数据库连接池+springJDBC

一、JDBC基本概念和下载

JDBC(Java DataBase Connectivity),通俗来讲就是用java语言操作数据库

  • 本质
    sun公司定义的一套操作所有关系型数据库的规则,即接口。
    各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
下载

去mysql官网下载其他版本

点击直接下载5.1.40
下载截图:

二、详细步骤

环境准备

在mysql中创建一个db3的数据库,并创建一个user表插入几条用户信息的数据

-- 创建一个编码为utf8 的数据库db3
create database db3 character set utf8;
use db3;

-- 创建user表
create table user (
id int primary key auto_increment,
name varchar(32), -- 用户名
password varchar(32) -- 密码
);

-- 添加一条数据
insert into user ( name, password ) values ( 'zhangsan', 123456 );
工程导入驱动jar包
  • 1、下载之后解压
  • 2、复制mysql的驱动包mysql-connector-java-5.1.40-bin.jar到工程上新建的lib目录下
  • 3、右键.jar文件,选择add As Library 添加成库

1、加载数据库驱动

//注册驱动
Class.forName("com.mysql.jdbc.Driver");

2、建立连接

String url = "jdbc:mysql://localhost:3306/db3";
String userName = "root";
String password = "root";
//获取与数据库的链接
Connection conn = DriverManager.getConnection(url, userName, password);

注意:如果是localhost:3306, mysql可以简写为jdbc:mysql:///db3

  • connection 对象常用方法:
方法 描述
createStatement() 创建可执行sql的statement对象(容易产生sql注入问题)
prepareStatement(sql) sql参数使用?作占位符,返回一个预编译后的prepareStatement对象(解决了sql注入问题)
setAutoCommit(boolean autoCommit) 设置事务是否自动提交:在执行sql之前开启事务
commit() 提交事务:当所有sql都执行完提交事务
rollback() 回滚事务:在catch中回滚事务

3、执行SQL语句

  • Statement 对象常用方法:
方法 描述
boolean execute(String sql) 可执行任意的sql语句,返回布尔值(一般不用)
int executeUpdate(String sql) 执行DML(insert、update、delete)语句、DDL(create,alter、drop)语句,返回影响的行数(常用)
ResultSet executeQuery(String sql) 执行DQL(select)语句,返回一个ResultSet对象(常用)
//使用statement 如:添加一条用户数据
//1、定义sql语句
String sql = "insert into user ( name, password ) values ( 'lisi', 1234 )";
//2、获取执行sql语句的对象
Statement st = conn.createStatement();
//3、定义sql语句并执行 如果count>0 则表示添加成功,否则添加失败
int count = st.executeUpdate(sql);

//推荐使用prepareStatement,如:查询登录用户是否匹配
//1、定义sql语句
String sql = "select * from user where name=? and password=?";
//2、获取执行sql语句的对象,需要传入sql,进行预编译
PrepareStatement pst = conn.prepareStatement(sql);
//3、设置值setXxx, Xxx代表获取字段的类型,如:setInt、setString
pst.setString(1, "lisi");
pst.setString(2, "1234");
//4、执行sql,不需要传递sql,直接返回结果对象
ResultSet rs = pst.executeQuery();

if(rs.next()){
  //登录成功
}

4、获取查询的结果集

  • ResultSet常用方法
//1、获取行,返回末尾是否有数据, 有则返回false,没有返回true
boolean next() //游标向下移动一行

//2.获取数据 Xxx 代表数据类型。 如:getInt(1) getString("name")
//根据列的编号获取值 从1开始
getXxx(int index);
//根据列的名称获取值
getXxx(String columName);

5、释放资源

1、需要释放的对象:ResultSet 结果集,Statement 语句,Connection 连接。
2、释放原则:先开的后关,后开的先关。ResultSet --> Statement --> Connection。
3、在finally中执行。

ResultSet rs = null;
Statement st = null;
Connection conn = null;
try{
  //JDBC操作数据库代码实现
}catch{
  //异常处理
}finally{
  if(rs != null){
    try {
      rs.close();
    } catch (SQLException throwables){
      throwables.printStackTrace();
    }
  }
  if(stm != null){
    try {
        stm.close();
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }
  }
  if(conn != null){
    try {
        conn.close();
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }
  }
}

三、JDBC实现工具类 jdbcUtils

1、在src问件下创建一个jdbc.properties文件,用于修改配置文件,而不用修改代码

加上?characterEncoding=utf8 可以解决中文乱码问题

url=jdbc:mysql://localhost:3306/db3?characterEncoding=utf8
username=root
password=root
driver=com.mysql.jdbc.Driver
2、创建一个utils包,在包下创建一个JdbcUtils类

主要实现的方法:

  • 1、得到数据库的连接对象 getConnection()

    • 使用配置文件代替传递的参数
  • 2、关闭所有打开的资源
    • close(PreparedStatement pst, Connection conn)、
    • close(ResultSet rs, PreparedStatement pst, Connection conn)
package com.yj.utils;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils {
    private static String url = null;
    private static String username = null;
    private static String password = null;
    private static String driver = null;

    //文件的读取,只需要读取一次即可拿到这些值。使用静态代码块
    static {
        try {
            //1、创建properties集合类
            Properties pro = new Properties();
            //2、获取src路径下的jdbc.properties文件的方式--->ClassLoader 类加载器
            InputStream rs = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
            //3、加载文件
            pro.load(rs);
            //4、获取值并赋值
            url = pro.getProperty("url");
            username = pro.getProperty("username");
            password = pro.getProperty("password");
            driver = pro.getProperty("driver");
            //5、注册驱动
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 得到数据库连接
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url,username,password);
    }

    //关闭所有打开的资源
    public static void close(PreparedStatement pst, Connection conn){
        if(pst != null){
            try {
                pst.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static void close(ResultSet rs, PreparedStatement pst, Connection conn){
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(pst != null){
            try {
                pst.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
3、使用工具类对db3数据库进行CRUD
package com.yj.jdbc;

import com.yj.utils.JdbcUtils;
import org.junit.Test;

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

public class Demo02 {
    //向数据库新增一条用户数据
    @Test
    public void insert(){
        Connection conn = null;
        PreparedStatement pst = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "insert into user (name, password) values (?, ?)";
            pst = conn.prepareStatement(sql);
            pst.setString(1,"王五");
            pst.setString(2,"123");
            int count = pst.executeUpdate();
            if(count > 0){
                System.out.println("添加成功");
            }else{
                System.out.println("添加失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(pst, conn);
        }
    }

    //修改数据 (修改id=2这条数据的密码为123456)
    @Test
    public void update (){
        Connection conn = null;
        PreparedStatement pst = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "update user set password = ? where id = 2";
            pst = conn.prepareStatement(sql);
            pst.setString(1,"123456");
            int count = pst.executeUpdate();
            if(count > 0){
                System.out.println("修改成功");
            }else{
                System.out.println("修改失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.close(pst, conn);
        }
    }

    //删除数据 (删掉id=2这条数据)
    @Test
    public void delete(){
        Connection conn = null;
        PreparedStatement pst = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "delete from user where id = 2";
            pst = conn.prepareStatement(sql);
            int count = pst.executeUpdate();
            if(count > 0){
                System.out.println("删除成功");
            }else{
                System.out.println("删除失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.close(pst, conn);
        }
    }

    //查询 (查询id=1这条数据并打印所有字段)
    @Test
    public void retrieve(){
        Connection conn = null;
        PreparedStatement pst = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "select * from user where id = ?";
            pst = conn.prepareStatement(sql);
            pst.setInt(1,1);
            rs = pst.executeQuery();
            if(rs.next()){
                System.out.println("id=" + rs.getInt("id"));
                System.out.println("name=" + rs.getString("name"));
                System.out.println("password=" + rs.getString("password"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.close(rs, pst, conn);
        }
    }
}

四、使用数据库连接池

概念

其实就是一个容器(集合),存放数据库连接的容器。

好处
  • 1、节约资源。
  • 2、用户访问高效。
如何实现
  • 1、接口:DataSource 下:

    • 获取连接:getConnection()
    • 归还连接:close()
  • 2、一般我们不去实现它,由数据库厂商来实现,常用的有:

1、C3P0的使用

  • 1、导入jar包(两个)c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar,不要忘记导入数据库驱动的jar包
  • 2、定义配置文件
    • 名称:c3p0.properties 或者 c3p0-config.xml
    • 位置:src文件目录下
<c3p0-config>
  <!-- 使用默认的配置读取连接池对象 -->
  <default-config>
  <!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/db3?characterEncoding=utf8</property>
    <property name="user">root</property>
    <property name="password">root</property>

    <!-- 连接池参数 -->
    <!--初始化申请的连接数量-->
    <property name="initialPoolSize">5</property>
    <!--最大的连接数量-->
    <property name="maxPoolSize">10</property>
    <!--超时时间-->
    <property name="checkoutTimeout">3000</property>
  </default-config>

  <!-- 使用name参数读取连接池对象 -->
  <named-config name="otherc3p0">
    <!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/db3?characterEncoding=utf8</property>
    <property name="user">root</property>
    <property name="password">root</property>

    <!-- 连接池参数 -->
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">8</property>
    <property name="checkoutTimeout">1000</property>
  </named-config>
</c3p0-config>
  • 3、创建数据库连接对象:comboPooleDataSource
//ComboPooledDataSource(String name)传入参数代表上面带有name属性的配置
//不传为默认
DataSource ds = new ComboPooledDataSource();
  • 4、获取连接
Connection conn = ds.getConnection();

2、Druid的使用

  • 1、导入jar包 druid-1.0.9.jar

  • 2、定义配置文件,properties形式,任意名称,任意目录
    如:druid.properties

url=jdbc:mysql://localhost:3306/db3?characterEncoding=utf8
username=root
password=root
driver=com.mysql.jdbc.Driver
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
# 最大等待时间
maxWait=3000
  • 3、加载配置文件
Properties pro = new Properties();
InputStrean is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
  • 4、获取数据库连接池对象:DruidDataSourceFactory
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
  • 5、获取连接
Connection conn = ds.getConnection();
  • 6、也可以定义工具类来提高代码的复用性:只要实现获取连接,归还连接

五、Spring JDBC

提供了一个JDBCTemplate对象简化JDBC的开发

1、使用步骤

//ds为数据库连接对象
JdbcTemplate template = new JdbcTemplate(ds);
  • 3、调用JdbcTemplate的方法来完成CRUD的操作,不需要调用close方法
方法 描述
update() 执行DML语句。增、删、改语句
queryForMap() 将查询1条结果集封装为map集合,将列名作为key,将值作为value
queryForList() 查询结果将结果集封装为list集合(注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中)
query() 查询结果,将结果封装为JavaBean对象(参数RowMapper,一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装)
queryForObject() 将结果封装为对象,一般用于聚合函数的查询

2、代码实现一个简单的例子

准备表的数据
-- 删除表的内容
truncate table user; 

-- 添加一些数据
insert into user values (null, "张三", "abcd"), (null, "李四", "bbb"), (null, "王五", "ccc");
代码实现例子
    1. 修改1号数据的 password 为 aaa
    1. 添加一条记录
    1. 删除刚才添加的记录
    1. 查询id为1的记录,将其封装为Map集合
    1. 查询所有记录,将其封装为List
    1. 查询所有记录,将其封装为Emp对象的List集合
    1. 查询总记录数
public class Demo04 {
  //使用c3p0来创建数据库连接对象
  private JdbcTemplate template = new JdbcTemplate(new ComboPooledDataSource());

  //1. 修改1号数据的 password 为 aaa
  @Test
  public void test1(){
      String sql = "update user set password = 'aaa' where id = 1";
      int count = template.update(sql);
      if(count>0){
          System.out.println("修改成功");
      }
  }
  //2. 添加一条记录
  @Test
  public void test2(){
      String sql = "insert into user values (null, ?, ?)";
      int count = template.update(sql, "小明", "ddd");
      if(count>0){
          System.out.println("添加成功");
      }
  }
  // 3. 删除刚才添加的记录
  @Test
  public void test3(){
      String sql = "delete from user where id = ?";
      int count = template.update(sql, 4);
      if(count>0){
          System.out.println("删除成功");
      }
  }
  // 4. 查询id为1的记录,将其封装为Map集合
  @Test
  public void test4(){
      String sql = "select * from user where id = 1";
      Map<String, Object> map = template.queryForMap(sql);
      System.out.println(map); //{id=1, name=张三, password=aaa}
  }
  // 5. 查询所有记录,将其封装为List
  @Test
  public void test5(){
      String sql = "select * from user";
      List<Map<String, Object>> list = template.queryForList(sql);
      System.out.println(list);
      //[{id=1, name=张三, password=aaa}, {id=2, name=李四, password=bbb}, {id=3, name=王五, password=ccc}]
  }
  // 6. 查询所有记录,将其封装为Emp对象的List集合
  @Test
  public void test6(){
      String sql = "select * from user";
      List<User> list = template.query(sql, new BeanPropertyRowMapper<User>(User.class));
      System.out.println(list);
      //[User{id=1, name='张三', password='aaa'}, User{id=2, name='李四', password='bbb'}, User{id=3, name='王五', password='ccc'}]
  }
  // 7. 查询总记录数
  @Test
  public void test7(){
      String sql = "select count(id) from user";
      Long total = template.queryForObject(sql, Long.class);
      System.out.println(total); //3
  }
}

(0)

相关推荐

  • JDBC

    今天对JDBC的内容又进行了一下复习,并学了一些新的知识如数据库连接池,Spring JDBC等. 主要内容 1. JDBC基本概念2. 快速入门3. 对JDBC中各个接口和类详解 4. 数据库连接池 ...

  • JDBC和数据库连接池

    JDBC是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成. ●  JDBC ●  C3P0 ●  DRUID JDBC 基本使用 ...

  • Java学习——119.JDBC数据库连接

    本篇简单介绍如何用Myeclipse连接数据库. 在连接数据库时遇到了不少问题,修改了好多地方,不知道最终成功是因为修改了哪里,我整理了一下,把所有修改过的地方都帖上来了. 1.数据库的配置 我所装的 ...

  • jdbc预编译对象,事务,数据库连接池

    jdbc预编译对象 原始的jdbc使用声明对象进行sql的执行,对于执行的sql参数使用字符串拼接的形式进行添加 Class.forName("com.mysql.jdbc.Driver&q ...

  • Data Source与数据库连接池简介 JDBC简介(八)

    DataSource是作为DriverManager的替代品而推出的,DataSource 对象是获取连接的首选方法. 原文地址: Data Source与数据库连接池简介 JDBC简介(八) 起源 ...

  • Hikari 数据库连接池配置详解

    <!-- Hikari Datasource --> <bean id="dataSourceHikari" class="com.zaxxer.hik ...

  • SpringBoot 2.0 中 HikariCP 数据库连接池原理解析

    作为后台服务开发,在日常工作中我们天天都在跟数据库打交道,一直在进行各种CRUD操作,都会使用到数据库连接池.按照发展历程,业界知名的数据库连接池有以下几种:c3p0.DBCP.Tomcat JDBC ...

  • Springboot 整合阿里数据库连接池 druid

    Spring boot 整合 druid druid的maven依赖 <!-- 阿里数据库连接池fhadmin.cn --> <dependency> <groupId& ...

  • 数据库连接池到底应该设多大?这篇文章可能会颠覆你的认知

    数据库连接池的配置是开发者们常常搞出坑的地方,在配置数据库连接池时,有几个可以说是和直觉背道而驰的原则需要明确. 1万并发用户访问 想象你有一个网站,压力虽然还没到Facebook那个级别,但也有个1 ...

  • 一个比 c3p0 快200倍的数据库连接池,这么牛?

    大家好,我是磊哥. 什么是数据库连接池 连接池是一种常用的技术,为什么需要连接池呢?这个需要从TCP说起.假如我们的服务器跟数据库没有部署在同一台机器,那么,服务器每次查询数据库都要先建立连接,一般都 ...

  • java学习——120.JDBC数据库连接(二)

    如果已经有了项目,可以直接在项目那里添加驱动包,不一定非得新建项目时才添加. 如图,我在已有的项目Lay_lunwenpinyue中添加JDBC驱动包. 首先,在项目处右键,在弹出来的快捷菜单中选中& ...