iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >详细说明关于Java的数据库连接(JDBC)
  • 557
分享到

详细说明关于Java的数据库连接(JDBC)

2024-04-02 19:04:59 557人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录Java的数据库连接(JDBC)1、什么是JDBC2、JDBC的原理3、演示JDBC的使用4、数据库连接方式5、JDBC的查询6、sql注入7、预处理查询7.1 查询 已解决注入

Java的数据库连接(JDBC)

1、什么是JDBC

JDBC(JavaDataBase Connectivity) 就是Java数据库连接,说白了就是用Java语言来操作数据库。原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句。

2、JDBC的原理

早期SUN公司的天才们想编写一套可以连接天下所有数据库的api,但是当他们刚刚开始时就发现这是不可完成的任务,因为各个厂商的数据库服务器差异太大了。后来SUN开始与数据库厂商们讨论,最终得出的结论是,由SUN提供一套访问数据库的规范(就是一组接口),并提供连接数据库的协议标准,然后各个数据库厂商会遵循SUN的规范提供一套访问自己公司的数据库服务器的API出现。SUN提供的规范命名为JDBC,而各个厂商提供的,遵循了JDBC规范的,可以访问自己数据库的API被称之为驱动!JDBC是接口,而JDBC驱动才是接口的实现,没有驱动无法完成数据库连接!每个数据库厂商都有自己的驱动,用来连接自己公司的数据库。

3、演示JDBC的使用

通过下载Mysql的驱动jar文件,将其添加到项目中间,在注册驱动时要指定为已经下载好的驱动。


package jdbc;

import com.mysql.jdbc.Driver;  //这是我们驱动的路径

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class Jdbc01 {
    public static void main(String[] args) throws SQLException {

        //1.注册驱动
        Driver driver = new Driver();

        //2.得到连接
        //jdbc:mysql:// 规定好的协议  localhost 连接的地址  3306 监听的端口 test_table 连接的数据库
        String url = "jdbc:mysql://localhost:3306/test_table";
        Properties properties = new Properties();
        //user和passWord 规定好的不能随意改
        properties.setProperty("user", "root");//
        properties.setProperty("password", "161142");
        Connection connect = driver.connect(url, properties); //相当于网络连接

        //3.执行sql语句
        //String sql = "insert into actor values(null,'syj','女','2000-05-26','110')";
        String sql = "update actor set name = 'xhj' where id =  2";
        Statement statement = connect.createStatement();
        int rows = statement.executeUpdate(sql);    //返回影响的行数
        if (rows > 0) System.out.println("添加成功");
        else System.out.println("添加失败");

        //4.关闭连接资源
        statement.close();
        connect.close();
    }
}

4、数据库连接方式


public class JdbcConn {
    @Test    
    public void testConn01() throws SQLException {
        //获取Driver实现类对象
        Driver driver = new Driver();

        String url = "jdbc:mysql://localhost:3306/test_table";
        Properties properties = new Properties();
        properties.setProperty("user", "root");
        properties.setProperty("password", "161142");
        Connection connect = driver.connect(url, properties);
        System.out.println(connect);
    }
    
    @Test    
    public void testConn02() throws Exception{
        //使用反射加载Driver类,动态加载,可以通过配置文件灵活使用各种数据库
        Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
        Driver driver = (Driver) aClass.getDeclaredConstructor().newInstance();

        String url = "jdbc:mysql://localhost:3306/test_table";
        Properties properties = new Properties();
        properties.setProperty("user", "root");
        properties.setProperty("password", "161142");
        Connection connect = driver.connect(url, properties);
        System.out.println(connect);
    }
    
    @Test    
    //DriverManager统一来管理Driver
    public void testConn03() throws Exception{
        //使用反射加载Driver类
        Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
        Driver driver = (Driver) aClass.getDeclaredConstructor().newInstance();

        //创建url和user和password
        String url = "jdbc:mysql://localhost:3306/test_table";
        String user = "root";
        String password = "161142";

        DriverManager.reGISterDriver(driver);   //注册Driver驱动

        Connection connection = DriverManager.getConnection(url, user, password);
        System.out.println(connection);
    }
    
    @Test    
    public void testConn04() throws Exception{
        //使用反射加载Driver类
        Class.forName("com.mysql.jdbc.Driver");
        
        //Class.forName("com.mysql.jdbc.Driver");
        
        //创建url和user和password
        String url = "jdbc:mysql://localhost:3306/test_table";
        String user = "root";
        String password = "161142";

        Connection connection = DriverManager.getConnection(url, user, password);
        System.out.println(connection);
    }
    
    @Test    
    public void testConn05() throws Exception{
        //在方式4的情况下,将信息放到配置文件里,利于后续可持续操作
        //获取配置文件信息
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\mysql.properties"));
        //获取相关信息
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String url = properties.getProperty("url");
        String driver = properties.getProperty("driver");

        Class.forName(driver);  //加载Driver类,建议加上

        Connection connection = DriverManager.getConnection(url, user, password);
        System.out.println(connection);
    }
}

5、JDBC的查询

使用ResultSet 记录查询结果
ResultSet: 底层使用ArrayList 存放每一行数据(二维字节数组,每一维表示一行中的一个数据)
Resultment: 用于执行静态SQL语句并返回其生成的结果的对象,是一个接口,需要各个数据库厂家来实现。(实际中我们一般不用这个)


public class jdbc03 {
    public static void main(String[] args) throws Exception {
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\mysql.properties"));
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String url = properties.getProperty("url");
        String driver = properties.getProperty("driver");
        Class.forName(driver);
        Connection connection = DriverManager.getConnection(url, user, password);
        Statement statement = connection.createStatement();

        ResultSet resultSet = statement.executeQuery("select id,`name`,sex,borndate from actor;");

        while (resultSet.next()){ //resultSet.previous();//向上移动一行
            int id = resultSet.getInt(1);
            //int id = resultSet.getInt("id"); //也可以按照列明来获取
            String name = resultSet.getString(2);
            String sex = resultSet.getString(3);
            Date date = resultSet.getDate(4);
            //Object object = resultSet.getObject(索引|列明); //对象形式操作(分情况考虑)
            System.out.println(id + "\t" + name + "\t" + sex + "\t" + date);
        }

        statement.close();
        connection.close();
    }
}

6、SQL注入

SQL注入: 是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的SQL语句段或命令,恶意攻击数据库。
例如下列代码实现了注入问题(而Statement就存在这个问题,所以实际开发过程中不用它)


create table admit(name varchar(32),password varchar(32));
insert into admit values('tom','1234');
select * from admit where name = 'tom' and password = '1234'; # 输出 tom 1234
# 如果有人输入 name 为 1' or   password 为  or '1' = '1
# 那么select 就变成
select * from admit where name = '1' or ' and password = ' or '1' = '1'; # 其中'1' = '1'永远成立

7、预处理查询

使用PreparedStatement代替Statement就避免了注入问题,通过传入**?** 代替拼接 (PreparedStatement接口继承了Statement接口)

PreparedStatement的好处

  • 不再使用+拼接sql语句,减少语法错误
  • 有效的解决了sql注入问题!
  • 大大减少了编译次数,效率较高

7.1 查询 已解决注入问题


public class jdbc04 {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入用户名:");
        String name = scanner.nextLine();
        System.out.print("请输入密码:");
        String pwd = scanner.nextLine();

        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\mysql.properties"));
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String url = properties.getProperty("url");
        String driver = properties.getProperty("driver");
        Class.forName(driver);
        Connection connection = DriverManager.getConnection(url, user, password);

        //Statement statement = connection.createStatement();
        //preparedStatement是PreparedStatement实现类的对象
        PreparedStatement preparedStatement = connection.prepareStatement("select `name` ,`password` " +
                "from admit where name = ? and password = ?");
        preparedStatement.setString(1,name);    //?号下标从1开始
        preparedStatement.setString(2,pwd);

        ResultSet resultSet = preparedStatement.executeQuery();
        if (resultSet.next()) System.out.println("登录成功");
        else System.out.println("登陆失败");

        preparedStatement.close();
        connection.close();
    }
}

7.2 插入,更新,删除


public class jdbc05 {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入用户名:");
        String name = scanner.nextLine();
        System.out.print("请输入密码:");
        String pwd = scanner.nextLine();

        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\mysql.properties"));
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String url = properties.getProperty("url");
        String driver = properties.getProperty("driver");
        Class.forName(driver);
        Connection connection = DriverManager.getConnection(url, user, password);

        //添加
        String sql1 = "insert into admit values(?,?)";
        //修改
        String sql2 = "update admit set name = ? where name = ? and password = ?";
        //删除
        String sql3 = "delete from admit where name = ? and password = ?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql3);
        //preparedStatement.setString(1,name+"plas");    //?号下标从1开始
        //preparedStatement.setString(2,name);
        //preparedStatement.setString(3,pwd);

        preparedStatement.setString(1,name);
        preparedStatement.setString(2,pwd);

        int rows = preparedStatement.executeUpdate();
        if (rows > 0) System.out.println("操作成功");
        else System.out.println("操作失败");

        preparedStatement.close();
        connection.close();
    }
}

8、工具类开发

由于在进行数据库操作时,有些步骤是重复的,如连接,关闭资源等操作。
工具类


package utils;
import java.sql.*;
import java.io.FileInputStream;
import java.util.Properties;
public class JDBCUtils {
    private static String user;     //用户名
    private static String password; //密码
    private static String url;      //连接数据库的url
    private static String driver;   //驱动
    
    //静态代码块进行行初始化
    static {
        try {
            Properties properties = new Properties();
            properties.load(new FileInputStream("src\\mysql.properties"));
            user = properties.getProperty("user");
            password = properties.getProperty("password");
            url = properties.getProperty("url");
            driver = properties.getProperty("driver");
        } catch (Exception e) {
            //实际开发过程中(将编译异常,改成运行异常,用户可以捕获异常,也可以默认处理该异常)
            throw new RuntimeException(e);
        }
    }
    //连接
    public static Connection getConnection(){
        try {
            return DriverManager.getConnection(url,user,password);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    //关闭资源
    public static void close(ResultSet set, Statement statement,Connection connection){
        try {
            if (set != null) set.close();
            if (statement != null)statement.close();
            if (connection != null)connection.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

应用:


public class JdbcUtilsTest {
    @Test  //测试select操作
    public void testSelect() {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            //得到连接
            connection = JDBCUtils.getConnection();

            //设置sql
            String sql = "select * from actor where id = ?";

            //创建PreparedStatement
            preparedStatement = connection.prepareStatement(sql);

            //占位赋值
            preparedStatement.setInt(1,2);

            //执行
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                
                int id = resultSet.getInt(1);
                String name = resultSet.getString(2);
                String sex = resultSet.getString(3);
                Date date = resultSet.getDate(4);
                String phone = resultSet.getString(5);
                System.out.println(id + "\t" + name + "\t" + sex + "\t" + date + "\t" + phone);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(resultSet, preparedStatement, connection);
        }
    }

    @Test  //测试DML操作
    public void testDML() {
        Connection connection = null;
        PreparedStatement preparedStatement = null;

        try {
            //得到连接
            connection = JDBCUtils.getConnection();

            //设置sql
            String sql = "update actor set name = ?,sex = ? where id = ?";

            //创建PreparedStatement
            preparedStatement = connection.prepareStatement(sql);

            //占位符赋值
            preparedStatement.setString(1, "sxy");
            preparedStatement.setString(2, "男");
            preparedStatement.setInt(3, 2);

            //执行
            preparedStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(null, preparedStatement, connection);
        }
    }
}

9、JDBC事务


public class Jdbc06 {
    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = JDBCUtils.getConnection();
            connection.setAutoCommit(false);//关闭自动提交(开启事务)

            //第一个动作
            String sql = "update actor set phone = phone - 10 where id = 2";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.executeUpdate();

            //int i = 1/0;  异常

            //第二个动作
            sql = "update actor set phone = phone + 10 where id = 1";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.executeUpdate();

            //提交事务
            connection.commit();

        } catch (Exception e) {
            System.out.println("有异常存在,撤销sql服务");
            try {
                connection.rollback();  //回滚到事务开始的地方
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            JDBCUtils.close(null, preparedStatement, connection);
        }

    }
}

10、批处理


public class Jdbc07 {
    @Test   //普通处理5000条插入数据   执行时间169839
    public void test01() {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = JDBCUtils.getConnection();
            String sql = "insert into actor(id,`name`,sex) values (?,?,'男')";
            preparedStatement = connection.prepareStatement(sql);
            long begin = System.currentTimeMillis();
            for (int i = 0; i < 5000; i++) {
                preparedStatement.setString(1, 3 + i + "");
                preparedStatement.setString(2, "sxy" + (i + 1));
                preparedStatement.executeUpdate();
            }
            long end = System.currentTimeMillis();
            System.out.println(end - begin);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(null, preparedStatement, connection);
        }
    }

    @Test   //批处理   执行时间429
    public void test02() {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = JDBCUtils.getConnection();
            String sql = "insert into actor(id,`name`,sex) values (?,?,'男')";
            preparedStatement = connection.prepareStatement(sql);
            long begin = System.currentTimeMillis();
            for (int i = 0; i < 5000; i++) {
                preparedStatement.setString(1, 3 + i + "");
                preparedStatement.setString(2, "sxy" + (i + 1));
                
                //将sql语句加入批处理包中
                preparedStatement.addBatch();
                
                
                //当有1000条时,在进行处理
                if ((i + 1) % 1000 == 0) {
                    preparedStatement.executeBatch();
                    //清空批处理包
                    preparedStatement.clearBatch();
                }
            }
            long end = System.currentTimeMillis();
            System.out.println(end - begin);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(null, preparedStatement, connection);
        }
    }
}

11、数据库连接池

由于有很多用户连接数据库,而数据库连接数量又是有限制的,而且就算连接并且关闭也是很耗时,所以就有了引入了数据库连接池可以很好的来解决这个问题。下面是普通连接数据库连接并且关闭5000次所耗时间6249毫秒,可以发下时间相对很长。


public class ConQuestion {
    public static void main(String[] args) {
        //看看连接-关闭 connection 会耗用多久
        long start = System.currentTimeMillis();
        System.out.println("开始连接.....");
        for (int i = 0; i < 5000; i++) {
            //使用传统的jdbc方式,得到连接
            Connection connection = JDBCUtils.getConnection();
            //做一些工作,比如得到PreparedStatement ,发送sql
            //..........
            //关闭
            JDBCUtils.close(null, null, connection);

        }
        long end = System.currentTimeMillis();
        System.out.println("传统方式5000次 耗时=" + (end - start));//传统方式5000次 耗时=6249
    }
}

11.1 数据库连接池基本介绍

  • 预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。
  • 数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。
  • 当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。

11.2 JDBC的数据库连接池使用

JDBC的数据库连接池使用javax.sql.DataSource来表示,DataSource只是一个接口,该接口通常由第三方提供实现。

11.3 数据库连接池的种类

  • C3P0 数据库连接池,速度相对较慢,稳定性不错(hibernate,spring)。(用的较多)
  • DBCP数据库连接池,速度相对c3p0较快,但不稳定。
  • Proxool数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一点。
  • BoneCP 数据库连接池,速度快。
  • Druid (德鲁伊)是阿里提供的数据库连接池,集DBCP,C3P0,Proxool优点于身的数据库连接池。(应用最广)

11.4 C3P0连接池

利用C3P0连接池再次尝试连接5000次数据库 可以发现耗时方式一仅仅花了456毫秒,第二种通过配置文件操作也是花了419毫秒差不多的时间,值得说的是这个连接池连接配置文件不能是我们自己写,官方有给定的模板(c3p0.config.xml)。


public class C3P0_ {
    @Test   //方式一: 相关参数,在程序中指定user,url,password等
    public void testC3P0_1() throws Exception {
        //创建一个数据源对象
        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();

        //通过配合文件获取相关连接信息
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\mysql.properties"));
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String url = properties.getProperty("url");
        String driver = properties.getProperty("driver");

        //给数据源(comboPooledDataSource)设置相关参数
        //连接管理是由comboPooledDataSource(连接池)来管理的
        comboPooledDataSource.setDriverClass(driver);   //设置驱动
        comboPooledDataSource.setJdbcUrl(url);
        comboPooledDataSource.setUser(user);
        comboPooledDataSource.setPassword(password);

        //初始化数据源的连接数
        comboPooledDataSource.setInitialPoolSize(10);
        //数据库连接池最大容量,如果还有连接请求,那么就会将该请求放入等待队列中
        comboPooledDataSource.setMaxPoolSize(50);

        //测试连接池的效率, 测试对mysql 5000次操作
        long start = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++) {
            //getConnection()这个方法就是重写了DataSource接口的方法
            Connection connection = comboPooledDataSource.getConnection();
            connection.close();
        }
        long end = System.currentTimeMillis();
        //c3p0 5000连接mysql 耗时=456
        System.out.println("c3p0 5000连接mysql 耗时=" + (end - start));
        comboPooledDataSource.close();
    }
    
    
    //第二种方式 使用配置文件模板来完成
    //将C3P0 提供的 c3p0.config.xml 拷贝到 src目录下
    //该文件指定了连接数据库和连接池的相关参数
    @Test
    public void testC3P0_02() throws SQLException {
        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("sxy");
        //测试5000次连接mysql
        long start = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++) {
            Connection connection = comboPooledDataSource.getConnection();
            connection.close();
        }
        long end = System.currentTimeMillis();
        //c3p0的第二种方式(5000) 耗时=419
        System.out.println("c3p0的第二种方式(5000) 耗时=" + (end - start));

    }
}

11.5 Druid连接池

在使用Druid连接池连接数据库500000次耗时643毫秒,而C3P0500000次连接耗时2373毫秒,很显然Druid连接速度更快。


public class Druid_ {
    @Test
    public void testDruid() throws Exception {
        //1.加入Druid jar包
        //2.加入 配置文件 druid.properties 放到src目录下
        //3.创建Properties对象
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\druid.properties"));

        //4.创建一个指定参数的数据库连接池
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);

        long start = System.currentTimeMillis();
        for (int i = 0; i < 500000; i++) {
            Connection connection = dataSource.getConnection();
            connection.close();
        }
        long end = System.currentTimeMillis();
        //Druid的500000次创建 耗时=643
        System.out.println("Druid的500000次创建 耗时=" + (end - start));
    }
}

对应的工具类


public class JDBCUtilsByDruid {
    private static DataSource ds;

    //在静态代码块完成 ds初始化
    static {
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("src\\druid.properties"));
            ds = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //编写getConnection方法
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    //关闭连接:在数据库连接池技术中,close不是真的断掉连接,而是把使用的Connection对象放回连接池
    public static void close(ResultSet resultSet, Statement statement, Connection connection) {
        try {
            if (resultSet != null) resultSet.close();
            if (statement != null) statement.close();
            if (connection != null) connection.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

使用工具类:


public class TestUtilsByDruid {
    @Test
    public void testSelect() {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            //得到连接
            connection = JDBCUtilsByDruid.getConnection();
            System.out.println(connection.getClass());
            //connection 的运行类型 class com.alibaba.druid.pool.DruidPooledConnection
            //设置sql
            String sql = "select * from actor where id = ?";
            //创建PreparedStatement
            preparedStatement = connection.prepareStatement(sql);
            //占位赋值
            preparedStatement.setInt(1, 2);
            //执行
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                int id = resultSet.getInt(1);
                String name = resultSet.getString(2);
                String sex = resultSet.getString(3);
                Date date = resultSet.getDate(4);
                String phone = resultSet.getString(5);
                System.out.println(id + "\t" + name + "\t" + sex + "\t" + date + "\t" + phone);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtilsByDruid.close(resultSet, preparedStatement, connection);
        }
    }
}

12、Apache-DBUtils

由于resultSet存放数据集合,在connection关闭时,resultSet结果集无法使用。所以为了使用这些数据,也有JDBC官方提供的文件Apache-DBUtils来存放数据。

12.1 ArrayList模拟

ArrayList模拟Apache-DBUtils

Actor类 用来保存Actor表中的数据用的。


public class Actor { //Javabean, POJO, Domain对象
    private Integer id;
    private String name;
    private String sex;
    private Date borndate;
    private String phone;
    public Actor() { //一定要给一个无参构造器[反射需要]
    }

    public Actor(Integer id, String name, String sex, Date borndate, String phone) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.borndate = borndate;
        this.phone = phone;
    }

    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getSex() { return sex; }
    public void setSex(String sex) { this.sex = sex; }
    public Date getBorndate() { return borndate; }
    public void setBorndate(Date borndate) { this.borndate = borndate; }
    public String getPhone() { return phone; }
    public void setPhone(String phone) { this.phone = phone; }

    @Override
    public String toString() {
        return "\nActor{" + "id=" + id + ", name='" + name + '\'' +
                ", sex='" + sex + '\'' + ", borndate=" + borndate +
                ", phone='" + phone + '\'' + '}';
    }
}

用ArrayList来存放数据


public class LikeApDB {

    @Test
    public void testSelectToArrayList() {
        Connection connection = null;
        String sql = "select * from actor where id >= ?";
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        ArrayList<Actor> list = new ArrayList<>();
        try {
            connection = JDBCUtilsByDruid.getConnection();
            System.out.println(connection.getClass());
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1, 1);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");//getName()
                String sex = resultSet.getString("sex");//getSex()
                Date borndate = resultSet.getDate("borndate");
                String phone = resultSet.getString("phone");
                //把得到的 resultSet 的记录,封装到 Actor对象,放入到list集合
                list.add(new Actor(id, name, sex, borndate, phone));
            }

            System.out.println("list集合数据=" + list);
            for(Actor actor : list) {
                System.out.println("id=" + actor.getId() + "\t" + actor.getName());
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            JDBCUtilsByDruid.close(resultSet, preparedStatement, connection);
        }
        //因为ArrayList 和 connection 没有任何关联,所以该集合可以复用.
        //return  list;
    }
}

12.2 Apache-DBUtils 

 基本介绍

commons-dbutils是 Apache组织提供的一个开源JDBC工具类库,它是对JDBC的封装,使用dbutils能极大简化jdbc编码的工作量。

DbUtils类

  • QueryRunner类:该类封装了SQL的执行,是线程安全的。可以实现增,删,改,查,批处理
  • 使用QueryRunner类实现查询。
  • ResultSetHandler接口:该接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式

应用实例

使用Apache-DBUtils工具+数据库连接池(Druid)方式,完成对一个表的增删改查。


package datasourse;

import ApDB.Actor;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
public class DBUtils_Use {
    @Test       //查询多条数据
    public void testQueryMany() throws Exception {
        //1.得到连接(Druid)
        Connection connection = JDBCUtilsByDruid.getConnection();
        //2.使用 DBUtils 类和接口,先引入 DBUtils jar文件 ,放到src目录下
        //3.创建QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        //4.执行相应的方法,返回ArrayList结果集
        String sql = "select * from actor where id >= ?";
        //String sql = "select id,`name` from actor where id >= ?";
        
        List<Actor> query =
                queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);
        
        for (Actor actor : query) {
            System.out.print(actor);
        }
        JDBCUtilsByDruid.close(null,null,connection);
    }

    @Test               //查询单条记录
    public void testQuerySingle() throws SQLException {
        Connection connection = JDBCUtilsByDruid.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        String sql = "select * from actor where id = ?";
        //已知查询的是单行,所以就用BeanHandler,返回一个对应的对象
        Actor query = queryRunner.query(connection, sql, new BeanHandler<>(Actor.class), 2);
        System.out.print(query);
        JDBCUtilsByDruid.close(null,null,connection);
    }

    @Test               //查询单行单列(某个信息)  返回一个Object对象
    public void testQuerySingleObject() throws SQLException {
        Connection connection = JDBCUtilsByDruid.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        String sql = "select `name` from actor where id = ?";
        //已知查询的是单行单列,所以就用BeanHandler,返回一个Object
        Object query = queryRunner.query(connection, sql, new ScalarHandler(), 1);
        System.out.println(query);
        JDBCUtilsByDruid.close(null,null,connection);
    }

    @Test       //演示DML操作(insert,update,delete)
    public void testDML() throws SQLException {
        Connection connection = JDBCUtilsByDruid.getConnection();
        QueryRunner queryRunner = new QueryRunner();

        //String sql = "update actor set phone = ? where id = ?";
        //int affectedRow = queryRunner.update(connection, sql, "110", 2);

        String sql = "insert into actor values(?,?,?,?,?)";
        int affectedRow = queryRunner.update(connection, sql, 3, "xhj", "女", "2000-05-26", "110");

        //String sql = "delete from actor where id = ?";
        //int affectedRow = queryRunner.update(connection, sql, 5004);

        System.out.println(affectedRow > 0 ? "OK" : "NO");
        JDBCUtilsByDruid.close(null,null,connection);
    }
}

13、BasicDao

引入问题

  • SQL语句是固定,不能通过参数传入,通用性不好,需要进行改进,更方便执行增删改查
  • 对于select 操作,如果有返回值,返回类型不能固定,需要使用泛型
  • 将来的表很多,业务需求复杂,不可能只靠一个JAVA类完成。

所以在实际开发中,也有解决办法 —BasicDao

13.1 BasicDAO类


public class BasicDAO<T> {  //泛型指定具体的类型
    private QueryRunner queryRunner = new QueryRunner();

    //开发通用的DML,针对任意表
    public int update(String sql,Object... parameter){
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return queryRunner.update(connection, sql, parameter);
        } catch (SQLException e) {
            throw new RuntimeException(e);//将编译异常转化成运行异常,可以被捕获,也可以被抛出
        }finally {
            JDBCUtilsByDruid.close(null,null,connection);
        }
    }

    
    public List<T> QueryMultiply(String sql,Class<T> clazz, Object... parameter){
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return queryRunner.query(connection,sql,new BeanListHandler<T>(clazz),parameter);
        } catch (SQLException e) {
            throw new RuntimeException(e);//将编译异常转化成运行异常,可以被捕获,也可以被抛出
        }finally {
            JDBCUtilsByDruid.close(null,null,connection);
        }
    }
    //返回单个对象(单行数据)
    public T querySingle(String sql,Class<T> clazz,Object... parameter){
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return queryRunner.query(connection,sql,new BeanHandler<T>(clazz),parameter);
        } catch (SQLException e) {
            throw new RuntimeException(e);//将编译异常转化成运行异常,可以被捕获,也可以被抛出
        }finally {
            JDBCUtilsByDruid.close(null,null,connection);
        }
    }
    //返回单个对象的单个属性(单行中的单列)
    public Object queryScalar(String sql,Object... parameter){
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return queryRunner.query(connection,sql,new ScalarHandler(),parameter);
        } catch (SQLException e) {
            throw new RuntimeException(e);//将编译异常转化成运行异常,可以被捕获,也可以被抛出
        }finally {
            JDBCUtilsByDruid.close(null,null,connection);
        }
    }
}

13.2 domain中的类


public class Actor { //Javabean, POJO, Domain对象
    private Integer id;
    private String name;
    private String sex;
    private Date borndate;
    private String phone;
    public Actor() { //一定要给一个无参构造器[反射需要]
    }

    public Actor(Integer id, String name, String sex, Date borndate, String phone) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.borndate = borndate;
        this.phone = phone;
    }

    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getSex() { return sex; }
    public void setSex(String sex) { this.sex = sex; }
    public Date getBorndate() { return borndate; }
    public void setBorndate(Date borndate) { this.borndate = borndate; }
    public String getPhone() { return phone; }
    public void setPhone(String phone) { this.phone = phone; }

    @Override
    public String toString() {
        return "\nActor{" + "id=" + id + ", name='" + name + '\'' +
                ", sex='" + sex + '\'' + ", borndate=" + borndate +
                ", phone='" + phone + '\'' + '}';
    }
}

ActorDAO类继承BasicDAO类,这样的类可以有很多。


public class ActorDAO extends BasicDAO<Actor> {
}

13.3 测试类


public class TestDAO {
    @Test//测试ActorDAO对actor表的操作
    public void testActorDAO() {
        ActorDAO actorDAO = new ActorDAO();
        //1.查询多行
        List<Actor> actors = actorDAO.QueryMultiply("select * from actor where id >= ?", Actor.class, 1);
        System.out.println(actors);

        //2.查询单行
        Actor actor = actorDAO.querySingle("select * from actor where id = ?", Actor.class, 1);
        System.out.println(actor);

        //3.查询单行单个数据
        Object o = actorDAO.queryScalar("select name from actor where id = ?", 1);
        System.out.println(o);

        //4.DML操作   当前演示update
        int affectedRow = actorDAO.update("update actor set phone = ? where id = ?", "120", 3);
        System.out.println(affectedRow > 0 ? "OK" : "NO");
    }
}

到此这篇关于详细说明关于Java的数据库连接(JDBC)的文章就介绍到这了,更多相关Java的数据库连接(JDBC)内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 详细说明关于Java的数据库连接(JDBC)

本文链接: https://www.lsjlt.com/news/134785.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详细说明关于Java的数据库连接(JDBC)
    目录Java的数据库连接(JDBC)1、什么是JDBC2、JDBC的原理3、演示JDBC的使用4、数据库连接方式5、JDBC的查询6、SQL注入7、预处理查询7.1 查询 已解决注入...
    99+
    2024-04-02
  • Java使用JDBC连接数据库的详细步骤
    目录一、JDBC是什么?二、使用步骤1.注册驱动2.获取连接3.获取数据库操作对象4.执行sql语句5.处理查询结果集6.释放资源上述六步连贯:第一次优化:(比较两种注册驱动的方法)...
    99+
    2024-04-02
  • Java数据库连接(JDBC)
    JDBC(Java DataBase Connectivity) JDBC概念 JDBC 就是使用Java语言操作关系型数据库的一套API全称:( Java DataBase Connectivi...
    99+
    2023-09-22
    数据库 java mysql
  • JDBC---Java连接数据库
    第一章 JDBC概述 1.1 JDBC概述 jdbc是(Java Database Connectivity)单词的缩写,翻译为java连接数据库。是Java程序连接数据库的技术总称。 JDBC由两个...
    99+
    2023-10-20
    java 数据库 mysql
  • Java 数据库连接(JDBC)的相关总结
    目录一、JDBC API 概述 二、JDBC 和 数据库建立连接的过程 2.1、装载驱动程序 2.2、获取数据库连接 2.2.1、Connection:数据库连接对象介绍 2.3、创...
    99+
    2024-04-02
  • java基于jdbc连接mysql数据库功能实例详解
    本文实例讲述了java基于jdbc连接mysql数据库的方法。分享给大家供大家参考,具体如下:一、JDBC简介Java 数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何...
    99+
    2023-05-30
    java jdbc mysql
  • 详解Java使用JDBC连接MySQL数据库
    一:什么是数据库,为什么要有数据库? 数据,数据库,数据库管理系统和数据库系统是与数据库技术密切相关的四个基本概念。 数据库相信大家都耳熟能详了,其实数据库顾名思义就是存放数据的仓库...
    99+
    2024-04-02
  • JDBC | JDBC API详解及数据库连接池
    👑 博主简介:    🥇 Java领域新星创作者    🥇 阿里云开发者社区专家博主、星级博主、技术博主 🤝 交流社区:BoBooY(优质编程学习笔记社区) 前言:...
    99+
    2023-08-20
    java 数据库 mysql
  • Java使用JDBC连接数据库
    目录一、JDBC简介二、JDBC中常用类和接口1、驱动程序管理类(DriverManager)2、声明类(Statement)3、数据库连接类 (Connection)4、结果集合类...
    99+
    2024-04-02
  • MySQL | JDBC连接数据库详细教程【全程干货】
    文章目录 一、什么是JDBC?二、JDBC工作原理三、使用JDBC连接MySQL数据库【✔】1、安装对应数据驱动包2、将jar包导入项目中3、编写代码连接数据库【⭐】1️⃣ 创建数据源2️⃣ 和数据库建立网络连接3️⃣ 构造SQL...
    99+
    2023-08-20
    数据库 mysql java
  • java中jdbc怎么连接数据库
    在Java中使用JDBC连接数据库的步骤如下:1. 下载并安装数据库驱动程序:首先需要从数据库官方网站下载相应的JDBC驱动程序,并...
    99+
    2023-09-15
    java jdbc 数据库
  • Java编程 JDBC连接Oracle数据库
    Part1 JDBC         JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口...
    99+
    2023-09-27
    数据库 java oracle
  • openGauss数据库JDBC环境连接配置的详细过程(Eclipse)
    目录1.测试环境2.准备2.1 PC端安装配置JDK112.2下载JDBC驱动并解压3 进行eclipse配置1.测试环境 客户端系统:Windows 10 客户端软件:eclips...
    99+
    2024-04-02
  • 关于Java中使用jdbc连接数据库中文出现乱码的问题
    目录一、使用jdbc连接数据库,插入数据库时,数据里的数据显示乱码,为 " "二、为什么配置了character_set_server = utf8,jdbc连...
    99+
    2023-05-15
    jdbc连接 jdbc连接数据库 数据库中文乱码
  • Oracle数据库自带表空间的详细说明
    需求: 需要整理现场用户创建的表空间以及其存储数据,进行规范化管理。在整理用户现场建立的表空间时,需要排除掉非用户创建的表空间,所有首先需要那些表空间是用户创建的,那些是Oracle自带的。 本机测试建立一...
    99+
    2024-04-02
  • MySQL数据库 JDBC 编程(Java 连接 MySQL)
    目录1. 数据库编程的基础条件2. Java 的数据库编程:JDBC3. JDBC 访问数据库的层次结构4. MySQL 数据库操作介绍5. MySQL 驱动包的下载及添加到项目6....
    99+
    2024-04-02
  • Java详细分析连接数据库的流程
    目录注册驱动程序创建连接创建 SQL 语句执行 SQL 语句关闭连接以下 5 个步骤是使用 JDBC 将 Java 应用程序与数据库连接所涉及的基本步骤。 注册驱动程序创建连接创建 ...
    99+
    2024-04-02
  • pytorch关于Tensor的数据类型说明
    目录关于Tensor的数据类型说明pytorch Tensor变形函数Tensor的排序与取极值Tensor与NumPy转换关于Tensor的数据类型说明 1. 32位浮点型:tor...
    99+
    2024-04-02
  • jdbc 数据库的连接方法
    这篇文章主要介绍“jdbc 数据库的连接方法”,在日常操作中,相信很多人在jdbc 数据库的连接方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”jdbc 数据库的连接方法”...
    99+
    2024-04-02
  • 关于node+mysql数据库连接池连接
     mysql有两种连接方式:一种是直接连接 另一种是池化连接,我们这篇讲的是池化连接。 为了让解惑,我简答的写份直接连接的代码,如下: var mysql = requi...
    99+
    2023-05-16
    node+mysql node连接mysql
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作