栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JDBC 基础学习详情笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JDBC 基础学习详情笔记

JDBC2 基础学习笔记
  • JDBC简介
  • 操作步骤
      • 数据库 URL 制定
      • 使用Properties对象
  • JDBC工具类示例
  • JDBC Statements
    • Connection:
    • Statements
    • PreparedStatement
    • CallableStatement
    • ResultSet
        • 查看结果集
        • 数据类型
        • 结果集类型
        • 结果集并发性
    • 事务
    • 批处理

JDBC简介

JDBC增删改查的通过操作代码示例
JDBC 指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库。

主要用于执行 SQL 查询,并查看查询的记录。

使用 JDBC 需要先下载驱动。

驱动下载地址

mysql8需要设置时区,有cj目录,mysql5没有

操作步骤

前期准备

1、在 mysql 中创建一个库,并创建相应测试表和插入一些测试数据。 	
2、新建一个 Java 工程,并导入 MySQL 数据库驱动包,将 mysql 驱动拷入项目根目录并右键添加到项目依赖(Add As Library)。        

JDBC 操作数据步骤一般分为如下五个步骤:

一、加载数据库驱动类

JDBC 操作数据步骤一般分为如下五个步骤:

二、建立连接(Connection)

Connection connection = DriverManager.getConnection(url,user,password); 

三、创建用于向数据库发送 SQL 的 Statement 对象,并发送 sql

Statement statement = connection.createStatement(); 

四、从结果集的 ResultSet 中取出返回数据。

ResultSet resultSet = statement.excuteQuery(sql);     

五、关闭相关资源,并释放内存

*.close()
数据库 URL 制定

当加载了驱动程序之后,可以通过 DriverManager.getConnection() 方法建立一个连接。

  • getConnection(String url)
  • getConnection(String url, Properties prop)
  • getConnection(String url, String user, String password)

在这里,每个格式需要一个数据库 URL ,数据库 URL 指向数据库的地址。

下表列出了常用的 JDBC 驱动程序名和数据库URL。

RDBMSJDBC 驱动程序名称URL 格式
MySQLcom.mysql.jdbc.Driverjdbc:mysql://localhost:3306/databaseName/database?severTimezone=Asia/Shanghai&characterEncoding=utf-8&useSSL=fasle
ORACLEoracle.jdbc.driver.OracleDriverjdbc:oracle:thin:@localhost:1521:实例ID
DB2COM.ibm.db2.jdbc.net.DB2Driver**jdbc:db2:**hostname:port Number/databaseName
Sybasecom.sybase.jdbc.SybDriver**jdbc:sybase:Tds:**hostname: port Number/databaseName
sqlserveom.microsoft.jdbc.sqlserver.SQLServerDriverjdbc:microsoft:sqlserver://localhost:1433;DatabaseName=databaseName

getConnection() 最常用的方式是需要你提供一个数据库 URL,用户名和密码:

调用适当的用户名和密码以及 getConnection() 方法来获得一个 Connection 对象,如下所示:

String URL = "jdbc:mysql://localhost/mydb?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8";
String USER = "username";
String PASS = "password"
Connection conn = DriverManager.getConnection(URL, USER, PASS);
使用Properties对象

Properties 对象可以保存了一组关键数值。它通过调用 getConnection() 方法,将驱动程序属性传递给驱动程序。

在根目录(位置可以任意)新建一个jdbc.properties文件

url=jdbc:mysql://58.42.239.163:3306/jdbc?serverTimezone=Asia/Shanghai&characterEncoding=UTF8&useSSL=false
user=star
password=Star@123456
JDBC工具类示例
public static Connection getConnection() {
        Properties properties = new Properties();
        try (
                FileInputStream fis = new FileInputStream("jdbc.properties")
        ) {
            properties.load(fis);
//            properties.load(JDBCUtility01.class.getResourceAsStream("dbc.properties"));
            return DriverManager.getConnection(properties.getProperty("url"), properties);
        } catch (IOException | SQLException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    public static void Close(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    public static void Close(PreparedStatement statement){
        if (statement!=null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    public static void Close(PreparedStatement statement,Connection connection){
        Close(statement);
        Close(connection);
    }
}
JDBC Statements

JDBC中 Statement,CallableStatement和PreparedStatement接口定义了用于发送SQL命令的方法。创常见的有3中Statement:

接口推荐使用
Statement用于对数据库进行通用访问,在运行时使用静态SQL语句时很有用。 Statement接口不能接受参数。
PreparedStatement当计划要多次使用SQL语句时使用。PreparedStatement接口在运行时接受输入参数。
CallableStatement当想要访问数据库存储过程时使用。CallableStatement接口也可以接受运行时输入参数。

3中Statement中具有相同的3个方法,用于不同需求的SQL查询,并且返回结果也不一样:

  1. boolean execute (String SQL) :

    如果可以检索到ResultSet对象,则返回一个布尔值true; 否则返回false。使用此方法执行SQLDDL语句或需要使用真正的动态SQL,可使用于执行创建数据库、创建表的SQL语句等等。

  2. int executeUpdate (String SQL):

    返回受SQL语句执行影响的行数。使用此方法执行预期会影响多行的SQL语句,例如:INSERT,UPDATE或DELETE语句。

  3. ResultSet executeQuery(String SQL):

    返回一个ResultSet对象。 当您希望获得结果集时,请使用此方法,就像使用SELECT语句一样。

  4. void close() throws SQLException;

    关闭 Statement

Connection:
Jdbc 程序中的 Connection,它用于代表数据库的连接,Collection 是数据库编程中最重要的一个对象,客户端与数据库所有交互都是通过 Connection 对象完成的,这个对象的常用方法:
 createStatement():创建向数据库发送 sql 的 Statement 对象。
 prepareStatement(sql) :创建向数据库发送预编译 sql 的 PrepareSatement 对象。
 prepareCall(sql):创建执行存储过程的 callableStatement 对象。
 setAutoCommit(boolean autoCommit):设置事务是否自动提交。
 commit() :在链接上提交事务。
 rollback() :在此链接上回滚事务。 
Statements

在使用Statement对象执行SQL语句之前,需要使用Connection对象的createStatement()方法创建一个Statement对象

执行完毕后需要关闭Statement对象,顺序应该是:先关闭Statement对象,再关闭Connection对象。PreparedStatement

Jdbc 程序中的 Statement 对象用于向数据库发送 SQL 语句, Statement 对象常用方法: 
executeQuery(String sql) :用于向数据发送查询语句。 
executeUpdate(String sql):用于向数据库发送 insert、update 或 delete 语句 
execute(String sql):用于向数据库发送任意 sql 语句 
addBatch(String sql) :把多条 sql 语句放到一个批处理中。 
executeBatch():向数据库发送一批 sql 语句执行。  
PreparedStatement

是用户利用某些系统没有对输入数据进行充分的检查,从而进行恶意破坏的行为。statement 存在 sql 注入攻击问题,例如登陆用户名采用’ or 1=1 # or 时无论密码是否正确都将登录成功。

SQL 注入的根本原因是 SQL 字符串的原始拼接。它可能会导致数据库被恶意破坏,这是任何开发都需要注意的问题。随着 jdbc 的发展,为防范 SQL 注入,可以采用 PreparedStatement 取代 Statement。

PreparedStatement接口扩展了Statement接口,添加了比Statement对象更好一些优点的功能。此语句可以动态地提供/接受参数。

JDBC中的所有参数都由 ? 符号作为占位符,这被称为参数标记。 在执行SQL语句之前,必须为每个参数(占位符)提供值。

可以使用setXXX()方法将值绑定到参数,其中XXX表示要绑定到输入参数的值的Java数据类型。 如果忘记提供绑定值,则将会抛出一个SQLException。

每个参数标记是它其顺序位置引用。第一个标记表示位置1,下一个位置2等等。 该方法与Java数组索引不同(它不从0开始)。

PreperedStatement 是 Statement 的子类,它的实例对象可以通过调用 connection.preparedStatement() 方法获得,相对于 Statement 对象而言: PreperedStatement 可以避免 SQL 注入的问题。 Statement 会使数据库频繁编译 SQL,可能造成数据库缓冲区溢出。PreparedStatement 可对 SQL 进行预编译,从而提高数据库的执行效率。 并且 PreperedStatement 对于 SQL 中的参数,允许使用占位符的形式进行替换,简化 SQL 语句的编写。 

CallableStatement

CallableStatement 对象被用来执行调用数据库存储过程的 。

三种类型的参数有:IN,OUT 和 INOUT。

PreparedStatement 对象只使用 IN 参数。CallableStatement 对象可以使用所有的三个参数。

参数描述
IN在 SQL 语句创建的时候该参数是未知的。你可以用 setXXX() 方法将值绑定到IN参数中。
OUT该参数由 SQL 语句的返回值提供。你可以用 getXXX() 方法获取 OUT 参数的值。
INOUT该参数同时提供输入输出的值。你可以用 setXXX() 方法将值绑定参数,并且用 getXXX() 方法获取值。

使用 CallableStatement 对象就像使用 PreparedStatement 对象一样。

  • 如果有 IN 参数,使用 setXXX() 方法绑定对应的 Java 数据类型。
  • 当使用 OUT 和 INOUT 参数时,必须使用 CallableStatement 的 -registerOutParameter() 方法来注册参数
  • registerOutParameter() 注册后,可以用适当的 getXXX() 方法来获取 OUT 参数的值。

示例:

存储过程:

create procedure test1(inout `max_age` int)
begin
    declare age int;
    select max(extract(year from now())-extract(year from birthday)) age from `user1` as max;
    set `max_age`=99;
end;
ResultSet 查看结果集

ResultSet接口中含有几十种从当前行获取数据的方法。

每个可能的数据类型都有一个 get 方法,并且每个 get 方法有两个版本-

  • 通过列名。
  • 通过列的索引。

例如,如果你想查看的列包含一个 int 类型,你需要在 ResultSet 中调用 getInt()方法-

同样的,在 ResultSet 接口中还有获取八个 Java 原始类型的 get 方法,以及常见的类型,比如 java.lang.String,

Jdbc 程序中的 ResultSet 用于代表 Sql 语句的执行结果。Resultset 封装执行结果时,采用的类似于表格的方式。ResultSet 对象维护了一个指向表格数据行的游标,初始的时候,游标在第一行之前,调用 resultSet.next() 方法,可以使游标指向具体的数据行,进行调用方法获取该行的数据。
ResultSet 提供检索不同类型字段的方法,常用的有: 
getString(int index)、getString(String columnName):通过索引或者字段名获得在数据库里是 varchar、char 等类型的数据对象。 
getFloat(int index)、getFloat(String columnName):通过索引或者字段名获得在数据库里是 Float 类型的数据对象。 
getDate(int index)、getDate(String columnName):通过索引或者字段名获得在数据库里是 Date 类型的数据。 
getBoolean(int index)、getBoolean(String columnName):通过索引或者字段名获得在数据库里是 Boolean 类型的数据。 
getObject(int index)、getObject(String columnName):通过索引或者字段名获取在数据库里任意类型的数据。
注意:
ResultSet 的 index 是从 1 开始的,这与我们平时所写代码注意区分。
ResultSet 还提供了对结果集进行滚动的方法: 
previous():移动到前一行 
absolute(int row):移动到指定行 
beforeFirst():移动 resultSet 的最前面。 
afterLast() :移动到 resultSet 的最后面。
注意:释放资源,
Jdbc 程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常有 ResultSet,Statement 和 Connection 对象。 
释放资源按照“后开先关”原则,顺序如下:ResultSet → Statement → Connection
为确保资源释放代码能正确运行,资源释放代码在使用 try-catch 时一定要放在 finally 语句中。 
数据类型

JDBC 驱动程序在将 Java 数据类型发送到数据库之前,会将其转换为相应的 JDBC 类型。对于大多数数据类型都采用了默认的映射关系。

SQLJDBC/JavasetXXXupdateXXX
VARCHARjava.lang.StringsetStringupdateString
CHARjava.lang.StringsetStringupdateString
LONGVARCHARjava.lang.StringsetStringupdateString
BITbooleansetBooleanupdateBoolean
NUMERICjava.math.BigDecimalsetBigDecimalupdateBigDecimal
TINYINTbytesetByteupdateByte
SMALLINTshortsetShortupdateShort
INTEGERintsetIntupdateInt
BIGINTlongsetLongupdateLong
REALfloatsetFloatupdateFloat
FLOATfloatsetFloatupdateFloat
DOUBLEdoublesetDoubleupdateDouble
VARBINARYbyte[ ]setBytesupdateBytes
BINARYbyte[ ]setBytesupdateBytes
DATEjava.sql.DatesetDateupdateDate
TIMEjava.sql.TimesetTimeupdateTime
TIMESTAMPjava.sql.TimestampsetTimestampupdateTimestamp
CLOBjava.sql.ClobsetClobupdateClob
BLOBjava.sql.BlobsetBlobupdateBlob
ARRAYjava.sql.ArraysetARRAYupdateARRAY
REFjava.sql.RefSetRefupdateRef
STRUCTjava.sql.StructSetStructupdateStruct
结果集类型

可能的 RSType 如下所示。如果你不指定 ResultSet 类型,将自动获得的值是 TYPE_FORWARD_ONLY。

类型描述
ResultSet.TYPE_FORWARD_ONLY光标只能在结果集中向前移动。
ResultSet.TYPE_SCROLL_INSENSITIVE光标可以向前和向后移动。当结果集创建后,其他人对数据库的操作不会影响结果集的数据。
ResultSet.TYPE_SCROLL_SENSITIVE.光标可以向前和向后移动。当结果集创建后,其他人对数据库的操作会影响结果集的数据。
结果集并发性

RSConcurrency 的值如下所示,如果你不指定并发类型,将自动获得的值是 CONCUR_READ_ONLY。

并发性描述
ResultSet.CONCUR_READ_ONLY创建一个只读结果集,这是默认的值。
ResultSet.CONCUR_UPDATABLE创建一个可修改的结果集。

到目前为止我们的示例可以如下所示,可以写成初始化一个 Statement 对象来创建一个只能前进,而且只读的 ResultSet 对象-

try {
   Statement stmt = conn.createStatement(
                           ResultSet.TYPE_FORWARD_ONLY,
                           ResultSet.CONCUR_READ_ONLY);
}
catch(Exception ex) {
   //....
}
finally {
   //....
}

在 ResultSet 接口中包括如下几种方法涉及移动光标-

S.N.方法 & 描述
1public void beforeFirst() throws SQLException将光标移动到第一行之前。
2public void afterLast() throws SQLException将光标移动到最后一行之后。
3public boolean first() throws SQLException将光标移动到第一行。
4public void last() throws SQLException将光标移动到最后一行。
5public boolean absolute(int row) throws SQLException将光标移动到指定的第 row 行。
6public boolean relative(int row) throws SQLException将光标移动到当前指向的位置往前或往后第 row 行的位置。
7public boolean previous() throws SQLException将光标移动到上一行,如果超过结果集的范围则返回 false。
8public boolean next() throws SQLException将光标移动到下一行,如果是结果集的最后一行则返回 false。
9public int getRow() throws SQLException返回当前光标指向的行数的值。
10public void moveToInsertRow() throws SQLException将光标移动到结果集中指定的行,可以在数据库中插入新的一行。当前光标位置将被记住。
11public void moveToCurrentRow() throws SQLException如果光标处于插入行,则将光标返回到当前行,其他情况下,这个方法不执行任何操作。
事务

如果你的 JDBC 连接是处于自动提交模式下,该模式为默认模式,那么每句 SQL 语句都是在其完成时提交到数据库。

若要启用手动事务模式来代替 JDBC 驱动程序默认使用的自动提交模式的话,使用 Connection 对象的的 **setAutoCommit()**方法。

如果传递一个布尔值 false 到 setAutoCommit()方法,你就关闭自动提交模式。你也可以传递一个布尔值 true 将其再次打开。

conn.setAutoCommit(false);

当你完成了你的修改,并且要提交你的修改,可以在 connection 对象里调用 **commit()**方法-

conn.commit( );

另外,用名为 conn 的连接回滚数据到数据库,使用如下所示的代码-

conn.rollback( );

下面的例子说明了如何使用提交和回滚对象-

public class UpdateData {
    public static void main(String[] args) {
        boolean update = update();
        System.out.println(update);


    }
    public static boolean update(){
        Connection connection = JDBCUtility01.getConnection();
        PreparedStatement statement=null;
        int i=0;
        if (connection!=null) {
            try {
                connection.setAutoCommit(false);
                String sql="update `user1` set username = ? where id = ?";
                statement=connection.prepareStatement(sql);
                statement.setString(1,"小米");
                statement.setInt(2,1);
                 i= statement.executeUpdate();
                connection.commit();
                return i!=0;
            } catch (SQLException e) {
                e.printStackTrace();
                try {
                    connection.rollback();
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
            }finally {
                JDBCUtility01.Close(statement,connection);
            }
        }
        return i==0;
    }
}
批处理

批处理是指你将关联的 SQL 语句组合成一个批处理,并将他们当成一个调用提交给数据库。

当你一次发送多个 SQL 语句到数据库时,可以减少通信的资源消耗,从而提高了性能。

JDBC 驱动程序不一定支持该功能。你可以使用 DatabasemetaData.supportsBatchUpdates() 方法来确定目标数据库是否支持批处理更新。如果你的JDBC驱动程序支持此功能,则该方法返回值为 true。

  • Statement,PreparedStatement 和 CallableStatement 的 addBatch() 方法用于添加单个语句到批处理。
  • executeBatch() 方法用于启动执行所有组合在一起的语句。
  • executeBatch() 方法返回一个整数数组,数组中的每个元素代表了各自的更新语句的更新数目。
  • 可以用 clearBatch() 方法删除它们。此方法删除所有用 addBatch() 方法添加的语句。

使用 Statement 对象来使用批处理所需要的典型步骤如下所示-

  1. 使用 createStatement() 方法创建一个 Statement 对象。
  2. 使用 setAutoCommit() 方法将自动提交设为 false。
  3. 被创建的 Statement 对象可以使用 addBatch() 方法来添加你想要的所有SQL语句。
  4. 被创建的 Statement 对象可以用 executeBatch() 将所有的 SQL 语句执行。
  5. 最后,使用 commit() 方法提交所有的更改。

下面的代码段提供了一个使用 Statement 对象批量更新的例子-

public static boolean insert(){
    Connection connection = JDBCUtility01.getConnection();
    PreparedStatement statement=null;
    if (connection!=null) {
        try {
            connection.setAutoCommit(false);
            String sql="insert into `user1`(username,password,birthday,gender,is_delete) value (?,?,?,?,?)";
            statement = connection.prepareStatement(sql);
            connection.setAutoCommit(false);
            statement.setString(1,"黄盖");
            statement.setString(2,"234345");
            statement.setDate(3,new Date(System.currentTimeMillis()));
            statement.setString(4,"男");
            statement.setBoolean(5,true);

            statement.addBatch();statement.setString(1,"刘禅");
            statement.setString(2,"234345");
            statement.setDate(3,new Date(System.currentTimeMillis()));
            statement.setString(4,"男");
            statement.setBoolean(5,true);

            statement.addBatch();statement.setString(1,"卢布");
            statement.setString(2,"234345");
            statement.setDate(3,new Date(System.currentTimeMillis()));
            statement.setString(4,"男");
            statement.setBoolean(5,true);
            statement.addBatch();

            int[] row = statement.executeBatch();
            connection.commit();
            return true;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            try {
                connection.rollback();//回滚
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    return false;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/682588.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号