【Java笔记】(九):JDBC

JDBC简介

JDBC:Java Database Connectivity–>Java和数据库的连接技术

是Sun公司推出的程序访问数据库的规范(接口),各个数据库厂商实现接口,提供数据驱动jar包,我们可以通过这套接口编程,但是真正执行的是驱动jar包中的类

环境准备

maven项目可以直接导入依赖:

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.21</version>
</dependency>

普通工程的步骤:

  • 先下载MySQL的jar包点击下载

  • 将jar包复制到项目的lib文件夹下(随便一个就行)

  • 右键lib文件夹,点击Add as Library

快速入门

  • 导入jar包(MySQL5版本之后的jar包可以省略这一步)
  • 注册驱动
  • 获取数据库连接对象 Connection
  • 获取执行sql语句的对象 Statement
  • 定义sql
  • 执行sql,接受返回结果
  • 处理结果并释放资源
public class JDBCTest {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //注册驱动,MySQL5版本之后这句话可以不写了
        Class.forName("mysql.mysql.jdbc.Driver");
        //获取连接对象
        String url = "jdbc:mysql://loaclhost:3306/dbname";
        String username = "root";
        String password = "123456";
        Connection conn = DriverManager.getConnection(url,username,password);
        //获取执行sql的对象,statement
        Statement statement = conn.createStatement();
        //定义sql,别忘了加分号
        String sql = "update account set password=11111 where username=zhangsan;";
        //执行sql
        int count = statement.executeUpdate(sql);
        //处理结果
        System.out.println(count);
        //释放资源
        statement.close();
        conn.close();
    }
}

详解各个对象

DriverManager

驱动管理对象

  • registerDriver()方法注册驱动,加载时静态代码块自动调用(MySQL5版本之后不用写了)
  • getConnection()方法获取数据库连接,url、username、password

如果是本地的loaclhost还是3306端口号,这个url可以简化为jdbc:mysql:///dbname

Connection

数据库连接对象

  • 获取执行sql的对象
    • Statement createStatement(),执行静态sql
    • Statement prepareStatement(String sql),执行动态sql
  • 管理事务
    • 开启事务:setAutoCommit(boolean autoCommit),设置参数为false即开启事务
    • 提交事务:commit()
    • 回滚事务:rollback()

Statement

执行sql的对象

  • boolean execute(String sql):可以执行任意sql,但是用的不多

  • int executeUpdate(String sql):执行DML(insert、update、delete)语句和DDL(库、表)语句

    • 返回值是受影响的行数,如果小于零则执行失败
  • ResultSet executeQuery(String sql):指定DQL(select)语句

ResultSet

结果集对象,封装查询的结果

  • next():光标向下移动一行,有则获取下一行,没有则返回false
  • getxxx(yyy):获取数据,xxx是数据类型,yyy是int时第几个(从1开始),yyy是String时是找某一列
ResultSet resultSet = statement.executeQuery(sql);
//和迭代器类似
while (resultSet.next()) {
    
    
    int anInt = resultSet.getInt(1);
    String id = resultSet.getString("id");
}

PreparedStatement

执行sql的对象,有时候使用字符串拼接会因为字段的特殊符号导致sql注入

?表示,作为占位符即可

String sql = "update account set password=? where username=?;";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setString(0,"111");//表示第一个占位符
statement.setObject(1,2222);
statement.executeUpdate();

JDBC工具类

import java.sql.*;

public class JDBCUtils {
    
    
    static Connection conn = null;
    static String url;
    static String username;
    static String password;
    //初始化
    static {
    
    
        //加载类
        try {
    
    
            Class.forName("mysql.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
    
    
            e.printStackTrace();
        }
        //获取连接对象
        try {
    
    
            conn = DriverManager.getConnection(url,username,password);
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        }
    }

    public static Connection getConnection() throws Exception {
    
    
        return conn;
    };

    public static void close() {
    
    

    }

    public static void close(ResultSet resultSet, Connection conn, Statement statement) throws Exception {
    
    
        if (resultSet!=null) {
    
    
            conn.close();
        }
        if (conn!=null) {
    
    
            conn.close();
        }
        if (statement!=null) {
    
    
            statement.close();
        }
    }
}

使用事务

我这个例子不是很合适了,因为只有一条sql,但是演示了使用事务的三个步骤

Connection conn = DriverManager.getConnection(url,username,password);
PreparedStatement statement = null;
//获取执行sql的对象,statement
try {
    
    
    conn.setAutoCommit(false);
    statement = conn.prepareStatement("update account set password=? where username=?;");
    statement.setString(1,"xiaozhng");
    statement.setString(1,"zhang");
	//提交
    conn.commit();
}catch (Exception e) {
    
    
    //有问题回滚
    conn.rollback();
} finally {
    
    
    //释放资源
    statement.close();
    conn.close();
}

使用批处理

如果使用循环来做效率会很低

Connection conn = DriverManager.getConnection(url,username,password);
conn.setAutoCommit(false);
PreparedStatement statement = conn.prepareStatement("update account set password=? where username=?;");

for (int i = 0; i < 50000; i++) {
    
    
    statement.setString(1,"xiaozhng");
    statement.setString(1,"zhang");
    statement.addBatch();//添加批处理
    if (i%1000==0) {
    
    
        statement.executeBatch();
        statement.clearBatch();
    }
}

二进制类型数据的读写

写入:

Connection conn = DriverManager.getConnection(url,username,password);
conn.setAutoCommit(false);
PreparedStatement statement = conn.prepareStatement("update user set photo=? where id=1;");
statement.setBlob(1,new FileInputStream("path"));
statement.executeUpdate();

读取:

ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
    
    
    InputStream inputStream = resultSet.getBinaryStream("photo");
    FileOutputStream fos = new FileOutputStream("path");
    int len;
    byte[] bytes = new byte[1024];
    while ((len=inputStream.read(bytes))!=-1) {
    
    
        fos.write(bytes,0,len);
    }
}

DBUtils的使用

是apache的开源框架,简化了JDBC的开发步骤,使得我们可以用更少量的代码实现连接数据库的功能,最厉害的是返回值可以直接指定,单个值,列表,Bean,BeanList…,maven页

  • query可以增删查数据
  • update可以修改数据

ResultSetHandler结果集处理类:

  • ArrayHandler 将结果集中的第一条记录封装到一个Object[]数组中:new ArrayHandler()
  • ArrayListHandler 将结果集中的每一条记录都封装到一个Object[]数组中:new ArrayListHandler()
  • BeanHandler 将结果集中第一条记录封装到一个指定的类中:new BeanHandler(Sort.class)
  • BeanListHandler 将结果集中每一条记录封装到指定的自定义类中,将这些类在封装到List集合中:new BeanListHandler<自定义类>(类名.class)
  • ColumnListHandler 将结果集中指定的列的字段值,封装到一个List集合中:new ColumnListHandler(“字段名”)
  • ScalarHandler 它是用于单数据。例如select count(*) from 表操作。:new ScalarHandler()
  • MapHandler 将结果集第一行封装到Map<String,Object>集合中,Key 列名, Value 该列数据
  • MapListHandler 将结果集每一行封装到List<Map<String,Object>>集合中,Key 列名, Value 该列数据,Map集合存储到List集合
public class DBUtilsTest {
    
    
    public static void main(String[] args) throws Exception {
    
    
        Connection connection = JDBCUtils.getConnection();
        QueryRunner qr = new QueryRunner();
        //查询单个值
        Object query = qr.query(connection, "select count(*) from user;", new ScalarHandler<>());
        //查询一个Bean,BeanListHandler<>()是Bean列表
        Map query1 = qr.query(connection,"select * from admin where id=?", new BeanHandler<>(Map.class), 1);
        //修改数据
        int result = qr.update(connection,"update from user set password=? where id=?","123");
    }
}

druid(德鲁伊)连接池技术

用户每次来不会向系统申请,而是去连接池中使用访问对象,用完再还回来,能节约时间还提高利用率

在这里插入图片描述

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/test_go?characterEncoding=UTF-8&useSSL=false
    username: xxx
    password: xxxxxx
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 5
      min-idle: 5
      max-active: 20
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      pool-prepared-statements: true
      max-pool-prepared-statement-per-connection-size: 20
      max-wait: 60000
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 30000
      filters: stat
      async-init: true
public ResultResponse testDruid() {
    
    
    String sql = "SELECT mobile FROM user WHERE id = ?";
    String mobile = jdbcTemplate.queryForObject(sql, new Object[]{
    
    1}, String.class);
    return new ResultResponse(201, "hey" + mobile);
}

唉就到这吧,,,等后面直接学Spring Boot整合得了

猜你喜欢

转载自blog.csdn.net/m0_46521785/article/details/114718545