JAVA之JDBC的使用

初识JDBC

JDBC(Java Database )是java提供的访问数据库的解决方案

提供这种方案是希望用相同的方式访问不同的数据库,以实现与具体数据库无关的java操作界面

JDBC定义了一套标准接口,即访问数据库的通用API ,不同的数据库厂商根据各自数据库的特点实现这些接口,然而在JDBC这些接口的实现类不叫实现类,叫驱动

接口里的内容

DriverManager 驱动管理

Connection DatabaseMataData 连接接口

Statment PreparedStatement 语句对象接口 CallableStatement

ResultSet 结果集接口 ResultSetMetaData

JDBC的工作原理

1.通过Connection进行连接数据库
 2.通过Statement进行传输sql语句
 3.数据库将结果返回给ResultSet

 加载驱动,建立连接
 创建语句对象
 执行sql语句
 处理结果集
 关闭连接

操作

使用JDBC必须需要导入JDBC驱动可以手动导入也可以通过MAVEN进行导入

放入对应数据库的驱动程序

使用java代码进行数据库操作

       1.注册驱动类
       2.创建数据库连接
       3.创建Statement对象
       4.执行sql语句
       5.处理结果
       6.关闭连接

```java /*注册驱动 */ //通过反射注册驱动 Class.froName(驱动包); /***注意区分驱动包

驱动如果是8.0以后的版本使用 8.0版本的jdk必须是1.8以上的版本 com.mysql.cj.jdbc.Driver 5.0 版本使用这个 com.mysql.jdbc.Driver / /*创建连接* */ Connection connection=DriverManager.getConnection("jdbc:mysql://HOST:PORT/数据库名","用户名", "密码"); /创建Statement对象(数据和sql的搬运工)* */ Statement statement= connection.createStatement();

/***执行sql语句 */ String sql= "SELECT * FROM 表名";

//execute方法如果是查询语句返回ture否则false; statement.execute(sql);

//执行增删改语句,返回值是int(表示影响几行数据) int i =statemenct.executeUpdate(sql);

//excuteUpdate执行修改语句,就是增删改

//excuteQuery执行查询语句

/处理结果 */

ResultSet

/*关闭连接,释放资源 */ statement.close(); connection.close(); ```

管理数据库连接

在软件中数据库来凝结使用非常频繁,如果每次都创建连接会造成大量的数据冗余常规的做法是建立数据库连接工具类,封装数据库连接过程

实现步骤:
            1.创建数据库连接参数文件 db.properties
            2.创建DcUtils,java封装数据库连接
                   利用Propertiew读取配置文件夹中的数据库连接参数

PrepareStatement

java里提供了PrepareStatement解决拼接字符串造成的sql注入

```java /** 创建数据连接省略 */

//获取prepareStatement String sql="SELECT * FROM users WHERE username=? AND password=?" PrepareStatement p=connection.prepareStatement(sql);

//给?赋值 p.setString(?下标(从1开始),value) || p.setObject(?下标(从1开始),value)

//执行sql语句(调用无参方法) p.excuteQuery();

//Util类 package com.yh.util;

import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.sql.; import java.util.;

public class JdbcUtil { private static String url; private static String userName; private static String passWord; private Connection connection; //连接 private PreparedStatement preparedStatement; //执行sql private ResultSet resultSet;//数据 static { try { /** * * 注册驱动,使用配置文件 */ Properties properties=new Properties(); properties.load(new FileReader("src/main/java/jdbc.properties")); String className=properties.getProperty("driverClass"); url= properties.getProperty("url"); userName= properties.getProperty("userName"); passWord=properties.getProperty("passWord"); Class.forName(className); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } }

/**
 * 创建连接
 * @param sql sql语句
 * @param values 值
 */
public void getConnection(String sql ,Object[] values){
    try {
        this.connection= DriverManager.getConnection(url,userName,passWord);
        this.preparedStatement=connection.prepareStatement(sql);
        if(values != null){
            for(int i=0;i<values.length;i++){
                this.preparedStatement.setObject(i+1,values[i]);
            }
        }
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}

/**
 * 查询
 * @param sql
 * @param values
 * @return
 */
public List<Map<String,Object>> Search(String sql,Object [] values){
     //创建连接
    getConnection(sql,values);
    List<Map<String,Object>> list=new ArrayList<>();
    //执行sql
    try {
        resultSet=preparedStatement.executeQuery();
        //遍历结果
        while(resultSet.next()){
            //获取当前行
            ResultSetMetaData resultSetMetaData=resultSet.getMetaData();

            //获取当前行的总字段数
            int num=resultSetMetaData.getColumnCount();
            HashMap<String,Object> column=new HashMap<>();
            for(int i=0;i<num;i++){
                //创建Map保存结果
                String columnName=resultSetMetaData.getColumnName(i+1);
                Object obj=resultSet.getObject(columnName);
                column.put(columnName,obj);
            }
          list.add(column);
        }
        return list;
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }

}

/**
 * 删除,修改,增加
 * @param sql
 * @param values
 * @return
 */
public int update(String sql,Object[] values){
    //创建连接
    getConnection(sql,values);
    try {
        //执行
        return  preparedStatement.executeUpdate();
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}

public void close(){
        try {
            if(resultSet != null){
            resultSet.close();
            }
            if(preparedStatement != null){
                preparedStatement.close();
            }
            if(connection != null){
                connection.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

}

}

```

连接池技术

### 为社么要使用连接池 数据库连接的建立及关闭资源消耗巨大 传统数据库访问方式:一次数据库访问对应一个物理连接,每次操作数据库都要打开,关闭该物理连接,系统性能严重受损。

解决方案: 数据库连接池(DataBase Connection) 系统初始化运行时,主动建立足够的连接,组成一个池,每次应用程序请求数据库连接时,无需重新打开连接,而是从池中取已有的连接,使用完后不再关闭u,而是归还

常见的连接池

常见的连接池有两种 C3p0数据库连接池,德鲁伊数据库连接池

c3p0连接池使用

首先需要写配置文件普通项目写sqc下,maven放在resources下
 配置文件指定名称 c3p0-config.xml 或者 c3p0.properties

xml <!-- characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=UTC&amp;rewriteBatchedStatements=true mysql8.0版本需要写 --> <?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-config> <property name="driverClass">com.mysql.cj.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://127.0.0.1:12315/yh?characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=UTC&amp;rewriteBatchedStatements=true</property> <property name="user">root</property> <property name="password">root</property> <property name="initIalPoolSize">2</property> <property name="maxPoolSize">5</property> <property name="checkoutTimeout">2000</property> </default-config> </c3p0-config> java //创建连接池 ComboPooledDataSource dataSource=new ComboPooledDataSource(); //获取连接 Connection conn=dataSource.getConnection(); //写sql String sql="SELECT * FROM books"; //创建Statement PreparedStatement statement= conn.prepareStatement(sql); //执行sql ResultSet rs=statement.executeQuery(); while(rs.next()){ System.out.println(rs.getString(1)); }

C3p0连接池工具类 ```java package util;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import java.sql.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;

public class C3p0util { //连接池对象 private static ComboPooledDataSource dataSource; //连接池对象 private static Connection connection; //连接 private PreparedStatement statement;//数据对象 private ResultSet resultSet;//结果集 static { //创建连接池对象 dataSource=new ComboPooledDataSource(); }

/**
 * 获取连接
 * @param sql
 * @param values
 */
public void getConnection(String sql,Object [] values){
    try {
        //创建连接
        connection=dataSource.getConnection();
        this.statement=connection.prepareStatement(sql);
       if(values !=null){
           for(int i=0;i<values.length;i++){
               statement.setObject(i+1,values[i]);
           }
       }
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }

}

/**
 * 查询方法
 * @param sql
 * @param values
 * @return
 */
public List<Map<String,Object>> search(String sql, Object[] values){
    //创建连接
    getConnection(sql,values);
    List<Map<String,Object>> list=new ArrayList<>();
    try {
        //执行sql
        this.resultSet=statement.executeQuery();
        while(resultSet.next()){
          ResultSetMetaData metaData=statement.getMetaData();
          int count= metaData.getColumnCount();
          Map<String,Object> map=new HashMap<>();
          for(int i=0;i<count;i++){

              String name=metaData.getColumnName(i+1);
              Object obj=resultSet.getObject(name);
              map.put(name,obj);
          }
          list.add(map);
        }
        return list;
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }finally {
        try {
            resultSet.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

/**
 * 增,删,改
 * @param sql
 * @param values
 * @return
 */
public int update(String sql,Object[] values){
    getConnection(sql,values);
    try {
        int res=statement.executeUpdate();
        return res;
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}

public void close(){
    try {
        if(resultSet != null){
            resultSet.close();
        }
        if(statement != null){
            statement.close();
        }
        if(connection != null){
            connection.close();
        }
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}

}

```

德鲁伊(Druid)连接池使用

依旧需要写配置文件,文件名不指定

使用时手动读取配置文件

Druid连接池工具类 ```java package util;

import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSourceFactory; import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource; import java.io.FileReader; import java.io.IOException; import java.sql.; import java.util.;

public class Druidutil { public static String path; //配置文件路径 private static DataSource dataSource; //连接池 private Connection connection; //连接 private PreparedStatement statement; //数据 private ResultSet resultSet; //数据集

/**
 * 创建连接池
 */
private void createDatasource(){
    Properties properties=new Properties();
    try {
        properties.load(new FileReader(path));
        dataSource= DruidDataSourceFactory.createDataSource(properties);
    } catch (IOException e) {
        throw new RuntimeException(e);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

/**
 * 获取连接
 * @param sql
 * @param values
 */
private void getConnection(String sql,Object [] values) {
    if(dataSource == null){
        createDatasource();
    }
    try {
        connection=dataSource.getConnection(); //获取连接
        statement=connection.prepareStatement(sql);
        if(values != null){
            for(int i=0;i< values.length;i++){
                statement.setObject(i+1,values[i]);
            }
        }
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}

/**
 * 查询
 * @param sql
 * @param values
 * @return
 */
public List<Map<String,Object>> search(String sql, Object [] values){
    getConnection(sql,values);
    try {
        resultSet=statement.executeQuery();
        List<Map<String,Object>> list=new ArrayList<>();
        while(resultSet.next()){
           ResultSetMetaData columnInfo=statement.getMetaData();
           int count=columnInfo.getColumnCount();
           Map<String,Object> map=new HashMap<>();
           for(int i=0;i<count;i++){
               String name=columnInfo.getColumnName(i+1);
               Object  obj=resultSet.getObject(name);
               map.put(name,obj);
           }
           list.add(map);
        }
        return list;
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }finally {
        try {
            resultSet.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

/**
 * 增,删,改
 * @param sql
 * @param values
 * @return
 */
public int update(String sql,Object[] values){
     getConnection(sql,values);
    try {
       int res=statement.executeUpdate();
      return res;
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}

/**
 * 关闭连接
 */
public void close(){
    try {
        if(resultSet != null){
            resultSet.close();
        }
        if(statement != null){
            statement.close();
        }
        if(connection != null){
            connection.close();
        }
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}

}

```

使用Apace DBCP连接池

DBCP :数据库连接池是Apache的一个java连接池开源技术,同时也是Tommcat使用的连接池组件。

使用DBCP需要去进行导包,这里是使用Maven导入的包 !!!! 注意使用DBCP 同样要导入JDBC的包

#### BasicDataSource类 BasicDataSource是DBCP提供给我们的管理数据库连接的类

设置参数的方法

 管理策略参数  
   getConnection() 获取连接 (这个连接用完之后一定要关闭,关闭并不是真的关闭而是还回去了)

   setInitalSize(int)  设置连接数(默认是10个) 这个默认连接数需要根据生产环境测试之后去进行设置

   setMaxActive(int)  设置最大活动数 (新版本为setMaxTotal)

   setMaxIdle(int) 设置最大空闲数

  必须设置的参数

     setDriverClassName 设置驱动

     setUrl()       

     setUsername()

     setPassword()
简单使用Demo

```java public static void main(String[] args) throws SQLException { BasicDataSource bs=new BasicDataSource(); //设置必须设置的参数

bs.setDriverClassName("com.mysql.cj.jdbc.Driver");
    bs.setUsername("root");
    bs.setPassword("root");
    bs.setUrl("jdbc:mysql://127.0.0.1:12315/yh");
    //设置管理策略参数
    bs.setInitialSize(2); //连接数
    bs.setMaxTotal(100); //最大活动数

    Connection connection=bs.getConnection(); //获取连接
     //执行sql
    Statement statement=connection.createStatement();
    String sql="SELECT 'hello' AS a" +"FROM dual";

    ResultSet resultSet=statement.executeQuery(sql);
    while (resultSet.next()){
        System.out.println(resultSet.getString("a"));
    }
    connection.close(); //归还连接
}

```

并发连接数据库连接池demo

```java

import org.apache.commons.dbcp2.BasicDataSource;

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

public class test { public static void main(String[] args) throws SQLException { Th t1=new Th(5000); t1.setName("t1"); Th t2=new Th(6000); t2.setName("t2"); Th t3=new Th(1000); t3.setName("t3"); t1.start();t2.start();t3.start(); } } class Conn{ public static BasicDataSource bs=new BasicDataSource(); static{ bs.setDriverClassName("com.mysql.cj.jdbc.Driver"); bs.setUsername("root"); bs.setPassword("root"); bs.setUrl("jdbc:mysql://127.0.0.1:12315/yh"); //设置管理策略参数 bs.setInitialSize(2); //连接数 bs.setMaxTotal(100); //最大活动数 } public static Connection get_conn() throws SQLException { Connection connection=bs.getConnection(); //获取连接 return connection; } } class Th extends Thread{ public int wait; public Th(int wait) { this.wait=wait; }

@Override
public void run() {
    Connection conn=null;
    try {
        conn=Conn.get_conn();
        System.out.println("获取到了连接" +getName());
        Statement statement=conn.createStatement();
    String sql="SELECT * FROM books";
    ResultSet resultSet=statement.executeQuery(sql);
        Thread.sleep(wait);
        System.out.println(wait+"结束");
        conn.close();
    } catch (SQLException e) {
        throw new RuntimeException(e);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    } finally {
        if(conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

}

```

JDBC-template使用

JDBC-template是Spring里边使用的JDBC工具类,如果单独使用的话需要导入很多包

```java

/**********************************添加*******************************/
   String sql = "insert into users values(null,?,?,?,?)";
  /* Object[] objects={"wukong","wk123","悟空",2};

   int i = template.update(sql,objects);

    System.out.println(i);*/


   /* sql = "insert into users values (null,'bajie','bj','八戒',5000)";
    int i = template.update(sql);

    System.out.println(i);*/


    /*******************************删除,修改***************************/
   /* sql = "delete from users where id=9";
    template.update(sql);*/


    /*sql = "delete from users where id=?";
    template.update(sql,10);*/


    /*sql = "delete from users where id between ? and ?";

    template.update(sql,1,5);*/


    //修改同上


    /********************************查询**************************/


    //查询单行数据 queryForMap
   /* try {

        sql = "select * from users where id=?";
        Map<String,Object> map = template.queryForMap(sql,10);
        System.out.println(map);
    }catch (EmptyResultDataAccessException e){

        System.out.println("查无此人");

    }*/


    //查询多行数据
   /* sql = "select * from users where id between ? and ?";

    Object[] objects = {1,15};

    List<Map<String,Object>> users = template.queryForList(sql,objects);


    for (Map<String, Object> map : users) {

        Users user = new Users();
        user.setId((Integer) map.get("id"));
        user.setUsername((String) map.get("username"));
        user.setPassword((String) map.get("password"));
        user.setRealname((String)map.get("realname"));
        user.setBalance((Double)map.get("balance"));


        System.out.println(user.getPassword());



    }*/


    /***************************把查询结果转换为实体类对象形式************************/

    //单行查询(把结果封装为对应的实体类对象)
   /* sql = "select balance,id,username,password,realname  from users where id=?";
    使用queryForObject必须使用try catch包裹
    Users user = template.queryForObject(sql,new BeanPropertyRowMapper<>(Users.class),6);
    System.out.println(user.getId()+" "+user.getUsername()+" "+user.getPassword()+" "+user.getRealname());*/



    //多行查询(每行结果都映射为一个实体类对象)
    sql = "select * from users";

    List<Users> list = template.query(sql, new BeanPropertyRowMapper<>(Users.class));
    for (Users user : list) {

        System.out.println(user.getBalance()+" "+user.getUsername());

    }

```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值