调用JDBC执行sql操作

JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。简言之,JDBC就是Java用于执行SQL语句实现数据库操作的API。

使用JDBC的大体步骤是这样的:

1.注册数据库驱动

通常使用 Class.forName() 的方式进行注册.不同数据库驱动不同,本例采用的是 mysql 驱动.下面介绍了两种数据库对应的驱动样式.

RDBMS JDBC驱动名称 URL格式
MySQL com.mysql.jdbc.Driver jdbc:mysql://hostName/databaseName
ORACLE oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@hostName:portNumber:databaseName
Calss.forName("JDBC驱动名称")

2.获取数据库链接

Connection connection = DriverManager.getConnection();

方法参数可选,不过最终都是调用的此方法

 private static Connection getConnection(
        String url, java.util.Properties info, Class<?> caller) throws SQLException{
        ...
}

3.创建发送sql语句对象

可以根据需求选择创建三种对象:  Statement,PreparedStatement,CallableStatement,三者关系为

Statment 接口提供了执行语句和获取结果的基本方法,支持普通的不带参数的sql语句,批量更新、删除等操作。每次使用都需要重新载入sql语句。

PreparedStatement 为 Statment 子接口,添加了 IN 参数的处理方法,支持可变参数sql,采用预编译处理,编译一次,执行多次,较Statment 接口而言,效率大大提高,而且也可以有效的防止sql注入问题。

CallableStatement 为 PreparedStatement 子接口,添加了 OUT , INOUT 参数的处理方法,支持调用存储过程。

4.发送sql语句

发送sql语句方法以及设置动态参数方法很多,建议阅读源码.这里介绍三种发送sql语句方法:

executeQuery() 用于发送查询语句

executeUpdate() 用于发送增添,修改,删除语句

execute() 用于发送所有语句

5.释放资源


 

接下来进行详细的演示

一、配置文件 jdbc.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://192.168.20.103:3306/my_test
user=root
password=123456

编写配置文件的目的是数据库有修改时只需修改配置文件,编写的工具类不需要改动.也可以省略此步骤,在工具类内部直接使用数据库的基本配置.

二、JDBC工具类

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
 * @author YoonaLt
 * @date 2019/11/1
 * jdbc工具类
 */
public class JdbcUtils {

    /**
     * 获取数据库链接
     *
     * @return mysql链接对象
     */
    public static Connection getConnection() {
        // 获取此类的类加载器
        ClassLoader classLoader = JdbcUtils.class.getClassLoader();
        // 获取配置文件的输入流
        InputStream inputStream = classLoader.getResourceAsStream("jdbc.properties");
        // 配置工具
        Properties properties = new Properties();
        // 加载
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 从配置文件读取需要的配置属性
        String url = properties.getProperty("url");
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String driver = properties.getProperty("driver");
        // 加载数据库驱动
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        // 获取数据库链接
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(url, user, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }

    /**
     * 释放资源
     *
     * @param connection 链接对象
     * @param statement  发送sql语句对象
     * @param resultSet  返回对象集合
     */
    public static void release(Connection connection, Statement statement, ResultSet resultSet) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

三、测试

1.建表

public static void createTable() {
        // 获取数据库链接
        Connection connection = JdbcUtils.getConnection();
        PreparedStatement ps = null;
        String sql = "create table user(id int auto_increment primary key,name varchar(50) comment '姓名'," +
                "sex tinyint comment '0男,1女',birthday datetime comment '生日',profession varchar(20) comment '职业')" +
                "default charset=utf8;";
        try {
            // 创建向数据库发送sql语句对象
            ps = connection.prepareStatement(sql);
            // 发送sql语句
            ps.execute();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            JdbcUtils.release(connection, ps, null);
        }
    }

2.插入数据

    public static void insert() {

        LocalDateTime localDateTime = LocalDateTime.of(1990, 5, 30, 12, 50, 40);
        long l = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        Date dateYoona = new Date(l);
        Date dateIU = Date.valueOf("1993-05-16");

        Connection connection = JdbcUtils.getConnection();
        PreparedStatement ps = null;
        // 可以直接填写完整的sql语句,也可以使用占位符.
        String sql = " insert into user(name,sex,birthday,profession) values ('IU',1,?,'idol'),('Yoona',1,?,'idol')";
        try {
            ps = connection.prepareStatement(sql);
            // 使用占位符时,最好使用占位类型对应的设置方法.也可都使用setObject()方法,第一个参数为占位符位置,从 1 开始,第二个为替换值
            ps.setDate(1, dateIU);
            ps.setObject(2, dateYoona);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, ps, null);
        }
    }

3.查询数据

(1)返回的数据确定只有一条

public static void select() {

        Connection connection = JdbcUtils.getConnection();
        PreparedStatement ps = null;
        // 查询返回结果集
        ResultSet resultSet = null;
        String sql = "select * from user where name = ?";
        try {
            ps = connection.prepareStatement(sql);
            ps.setString(1, "Yoona");
            resultSet = ps.executeQuery();
            if (resultSet.next()) {
                System.out.println(resultSet.getString("name"));
                System.out.println(resultSet.getInt("sex"));
                System.out.println(resultSet.getDate("birthday"));
                System.out.println(resultSet.getString("profession"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, ps, resultSet);
        }
    }

(2) 返回的结果可能是多条

    public static void selectMany() {
        List<Map<String, String>> list = new ArrayList();
        Connection connection = JdbcUtils.getConnection();
        PreparedStatement cs = null;
        ResultSet resultSet = null;
        String sql = "select * from user";
        try {
            cs = connection.prepareStatement(sql);
            resultSet = cs.executeQuery();
            // 使用while
            while (resultSet.next()) {
                Map<String, String> m = new HashMap(16);
                m.put("name", resultSet.getString("name"));
                m.put("profession", resultSet.getString("profession"));
                list.add(m);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, cs, resultSet);
        }
        // 打印验证是否成功取出多条数据
        list.forEach(map -> System.out.println(map.get("name") + " 的职业是 " + map.get("profession")));
    }

使用 while 循环,将每一个返回集放入准备好的容器中

4.事务

在jdbc中处理事务,是通过使用同一个 Connection 来实现的.

setAutoCommit(boolean autoCommit),设置是否自动提交事务,默认为 true,如果设置为false,则代表开启事务

commit() ,提交事务

rollback(),回滚

 public static void commit() {
        Connection c = JdbcUtils.getConnection();
        PreparedStatement ps = null;
        try {
            // 开启事务
            c.setAutoCommit(false);
            // 设置主键冲突,触发事务
            String sqlOne = " insert into user(id,name,sex,profession) values (1,'Yoona',1,'idol')";
            ps = c.prepareStatement(sqlOne);
            ps.executeUpdate();
            String sqlTwo = " insert into user(id,name,sex,profession) values (1,'IU',1,'idol')";
            ps = c.prepareStatement(sqlTwo);
            ps.executeUpdate();
            // 提交事务
            c.commit();
        } catch (SQLException e) {
            try {
                // 发生异常即回滚
                c.rollback();
                System.out.println("----------回滚----------");
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            JdbcUtils.release(c, ps, null);
        }
    }

项目使用的框架对JDBC 已经封装的十分好了,不过适当的了解JDBC的工作步骤还是有助于对框架的理解的.由于本人水平有限,难免出现错误与遗漏,欢迎指正.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章