Java数据库编程
1996年,SUN公司发布了第1版的Java数据库连接(JDBC)API,使编程人员可以通过这个API连接到数据库,并使用SQL完成对数据库的各种操作CURD【创建(Create)、更新(Update)、读取(Read)和删除(Delete)】,自此JDBC成为Java类库中最常使用的API之一。
JDBC(Java Database Connection):为多种关系数据库提供统一访问。它由一组用Java语言编写的类和接口组成。是Java访问数据库的标准和规范。它在哪呢?就在Java的标准库java.sql里。
JDBC原理图
关于MySQL安装与使用可参见,MySQL8.0.19数据库管理系统安装与简单使用 https://blog.csdn.net/cnds123/article/details/104454487
JDBC 的简单使用步骤:
加载数据库驱动;
建立连接;
创建 Statement 对象,用于向数据库发送 SQL 语句;
获取 ResultSet 对象,取出数据,此对象代表结果集;
释放资源,断开与数据库的连接。
Java数据库编程常用几个 JDBC 的类:DriverManager、Collection、Statement 和 ResultSet,下面我们将详细介绍这几个类。
DriverManager 是驱动管理类,此类用于注册驱动和获得连接。
Connection类可以创建执行 SQL 语句的对象,还可以进行事务的管理。
Connection 类的常用实例方法:
Statement createStatement():创建执行 SQL 语句对象,又 SQL 注入风险;
PrepareStatement prepareStatement(String sql):预编译 SQL 语句,解决 SQL 注入的漏洞;
CallableStatement prepareCall(String sql):执行 SQL 中存储过程;
setAutoCommit(boolean autoCommit):设置事务是否自动提交;
commit():事务提交;
rollback():事务回滚。
Statement 类用于执行 SQL 语句的对象,下面列举了 Statement 类的常用实例方法:
boolean execute(String sql):执行 SQL 语句,如果返回的第一个结果为 ResultSet 对象,则返回 true,如果其为更新计数或者不存在任何结果,则返回 false。该方法不常用;
ResultSet executeQuery(String sql):执行 SQL 中的 select 语句;
int executeUpdate(String sql):执行 SQL 中的 insert、update、delete 语句,返回影响的行数。
Statement 还可以执行批量操作。
ResultSet类用于select 语句查询的结果的封装。下面列举了 ResultSet 类的常用实例方法:
boolean next():将光标从当前位置向前移一行,判断是否有下一行记录;
getString(String columnLable):以 Java 语言中 String 的形式获取此 ResultSet 对象的当前行中指定的值;
getInt(String columnLable):以 Java 语言中 int 的形式获取此 ResultSet 对象的当前行中指定的值;
getXXX():对于不同类型的数据,可以使用 getXXX() 来获取数据(例如 getString(),getInt()),另外还有一个通用的 getObject() 方法,用于获取所有 Object 类型的数据。
数据类型
使用JDBC的时候,需要在Java数据类型和SQL数据类型之间进行转换。JDBC在java.sql.Types定义了一组常量来表示如何映射SQL数据类型,但是平时我们使用的类型通常也就以下几种:
SQL数据类型 | Java数据类型 |
BIT, BOOL | boolean |
INTEGER | int |
BIGINT | long |
REAL | float |
FLOAT, DOUBLE | double |
CHAR, VARCHAR | String |
DECIMAL | BigDecimal |
DATE | java.sql.Date, LocalDate |
TIME | java.sql.Time, LocalTime |
用纯Java的JDBC驱动程序实现与数据库连接
Java程序也可以用纯Java的JDBC驱动程序实现与数据库连接。这种方法应用较广泛,但是需要下载相应的驱动程序包,因为不同的数据库的连接代码可能不同,连接不同的数据库,加载的驱动程序也可能不同。例如,连接SQLServer的驱动程序在www.msdn.com网站下载,有3个包:msbase.jar,mssqlserver.jar和msutil.jar,并要求将这3个包放在jdk\jre\lib\ext\目录下,或在CLASSPATH中设置其放置位置。
使用纯Java的JDBC驱动程序实现与数据库连接的过程如下:
- 加载驱动程序。有两种加载驱动程序的方式:
- 创建指定数据库的URL。数据库的URL对象类似网络的统一资源定位符,其格式是:
jdbc:subProtocol:subName://hostname:port:Databasename=XXX
其中,subprotocol是某种驱动程序支持的数据库连接机制; subName是当前连接机制下的具体名称;hostName是主机名;port是相应的连接端口;DatabaseName是要连接的数据库名称。例如,以下代码可以是一个数据库的URL:
jdbc:Microsoft:sqlserver://localhost:1433;Databasename=ksinfo
该数据库的URL说明利用miscrosoft提供的机制,用sqlserve驱动,通过1433端口访问本机上的ksInfo数据库。
- 建立连接。驱动程序管理器(DriverManager)的方法getConnection()建立连接。
例 、与数据库连接的静态方法connectByJdbc(),该方法按给定的数据库URL、用户名和密码连接数据库,如果连接成功,方法返回true,连接不成功,则返回false。
public static Connection conectByJdbc(String url, String username, String password){
Connection con = null;
try{
Class.forName( //加载特定的驱动程序
"com.microsoft.jdbc.sqlserver.SQLServerDriver");
}
catch (Exception e){
e.printStackTrace();
return null; //连接失败
}
try{
con = DriverManage.getConnection(url, username, password);
}
catch (SQLException e){
e.printStackTrace();
return null; //连接失败
}
return con; //连接成功
}
编写访问数据库的Java程序还需要几个重要的类和接口。
DriverManager类
DriverManager类处理驱动程序的加载和建立新数据库连接。DriverManager是java.sql包中用于管理数据库驱动程序的类。通常,应用程序只使用类DriverManager的getConnection()静态方法,用来建立与数据库的连接,返回Connection对象:
static Connection getConnection(String url,String username,String password)
指定数据的URL用户名和密码创建数据库连接对象。url的语法格式是:
jdbc:<数据库的连接机制>:<ODBC数据库名>。
Connection类
Connection类是java.sql包中用于处理与特定数据库连接的类。Connection对象是用来表示数据库连接的对象,Java程序对数据库的操作都在这种对象上进行。Connection类的主要方法有:
- Statement createStatement():创建一个Statement对象。
- Statement createStatement(int resultSetType,int resultSetConcurrency):创建一个Statement对象,生成具有特定类型的结果集。
- void commit():提交对数据库的改动并释放当前持有的数据库的锁。
- void rollback():回滚当前事务中的所有改动并释放当前连接持有的数据库的锁。
- String getCatalog():获得连接对象的当前目录。
- boolean isClose():判断连接是否已关闭。
- boolean isReadOnly():判断连接是否为只读模式。
- void setReadOnly():设置连接为只读模式。
- void close():释放连接对象的数据库和JDBC资源。
Statement类
Statement类是java.sql包中用于在指定的连接中处理SQL语句的类。数据库编程的要点是在程序中嵌入SQL命令。程序需要声明和创建连接数据库的Connection对象,并让该对象连接数据库。调用类DriverManager的静态方法getConnection()获得Connection对象,实现程序与数据库的连。然后,用Statement类声明SQL语句对象,并调用Connection对象的createStatement()方法,创建SQL语句对象。例如,以下代码创建语句对象sql:
Statement sql = null;
try{
sql = con.createStatement();
}catch(SQLException e){}
ResultSet类
有了SQL语句对象后,调用语句对象的方法executeQuery()执行SQL查询,并将查询结果存放在一个用ResultSet类声明的对象中,例如,以下代码读取学生成绩表存于rs 对象中:
ResultSet rs = sql.executeQuery(“SELECT * FROM ksInfo”);
ResultSet对象实际上是一个由查询结果数据的表,是一个管式数据集,由统一形式的数据行组成,一行对应一条查询记录。在ResultSet对象中隐含着一个游标,一次只能获得游标当前所指的数据行,用next方法可取下一个数据行。用数据行的字段(列)名称或位置索引(自1开始)调用形如getXXX()方法获得记录的字段植 。以下是ResultSet对象的部分方法:
- byte getByte(int columnIndex):返回指定字段的字节值。
- Date getDate(int columnIndex):返回指定字段的日期值。
- float getFloat(int columnIndex):返回指定字段的浮点值。
- int getInt(int columnIndex):返回指定字段的整数值。
- String getString(int columnIndex):返回指定字段的字符串值。
- double getDouble(String columnName):返回指定字段的双精度值。
- long getLong(String columnName):返回指定字段的long型整值。
- boolean next():返回是否还有下一字段。
以上方法中的columnIndex是位置索引,用于指定字段,columnName是字段名。
用户需要在查询结果集上浏览,或前后移动、或显示结果集的指定记录,这称为可滚动结果集。程序要获得一个可滚动结果集,只要在获得SQL的语句对象时,增加指定结果集的两个参数即可。例如,以下代码:
Statement stmt = con.createStatement(type,concurrency);
ResultSet rs = stmt.executeQuery(SQL语句)
语句对象stmt的SQL查询就能得到相应类型的结果集。
- int 型参数type决定可滚动集的滚动方式:
- ResultSet.TYPE_FORWORD_ONLY,结果集的游标只能向下滚动。
- ResultSet.TYPE_SCROLL_INSENSITIVE,游标可上下移动,当数据库变化时,当前结果集不变。
- ResultSet. TYPE_SCROLL_SENSITIVE,游标可上下移动,当数据库变化时,当前结果集同步改变。
- int 型参数concurrency决定数据库是否与可滚动集同步更新:
- ResultSet.CONCUR_READ_ONLY,不能用结果集更新数据库中的表。
- ResultSet.CONCUR_UPDATETABLE,能用结果集更新数据库中的表。
例如,以下代码利用连接对象connect,创建Statement对象stmt,指定结果集可滚动,并以只读方式读数据库:
stmt = connect.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
可滚动集上另外一些常用的方法如下:
- boolean previous():将游标向上移动,当移到结果集的第一行时,返回false。
- void beforeFirst():将游标移结果集的第一行之前。
- void afterLast():将游标移到结果集的最后一行之后。
- void first():将游标移到第一行。
- void last():将游标移到最后一行。
- boolean isAfterLast():判游标是否在最后一行之后。
- boolean isBeforeFirst():判游标是否在第一行之前。
- boolean isLast():判游标是否在最后一行。
- boolean isFirst():判游标是否在第一行。
- int getRow():获取当前所指的行(行号自1开始编号,结果集空,返回0)。
- boolean absolute(int row):将游标移到row行。
下面是使用JDBC连接MySQL为一个示例
创建一个数据库:test,在这个数据库上创建一张表:employees。
employees的内容如下:
ID | Age | First | Last |
100 | 18 | Zara | Ali |
101 | 25 | Mahnaz | Mahnaz |
102 | 30 | Zaid | Khan |
103 | 28 | Sumit | Mitta |
Employees表结构如下
字段名 ID Age First Last
类型 INTEGER INTEGER CHAR CHAR
如果手动编译,需要把代码文件FirstExample.java存放到 F:\worksp\jdbc\ 文件夹中,并创建一个目录:F:\worksp\jdbc\libs,把下载的mysql-connector-java-5.1.40-bin.jar库(下载地址:http://downloads.mysql.com/archives/c-j/)放入到 F:\worksp\jdbc\libs 目录中。使用命令行编译Java程序并加载指定目录中的Jar包(mysql-connector-java-5.1.40-bin.jar),现在编译上面的例子如下:
F:\worksp\jdbc> javac -Djava.ext.dirs=F:\worksp\jdbc\libs FirstExample.java
此示例代码基于环境和数据库环境设置完成的前提下使用。
//STEP 1. Import required packages
import java.sql.*;
public class FirstExample {
// JDBC driver name and database URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost/test";
// Database credentials -- 数据库名和密码自己修改
static final String USER = "username";
static final String PASS = "password";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try{
//STEP 2: Register JDBC driver
Class.forName("com.mysql.jdbc.Driver");
//STEP 3: Open a connection
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL,USER,PASS);
//STEP 4: Execute a query
System.out.println("Creating statement...");
stmt = conn.createStatement();
String sql;
sql = "SELECT id, first, last, age FROM Employees";
ResultSet rs = stmt.executeQuery(sql);
//STEP 5: Extract data from result set
while(rs.next()){
//Retrieve by column name
int id = rs.getInt("id");
int age = rs.getInt("age");
String first = rs.getString("first");
String last = rs.getString("last");
//Display values
System.out.print("ID: " + id);
System.out.print(", Age: " + age);
System.out.print(", First: " + first);
System.out.println(", Last: " + last);
}
//STEP 6: Clean-up environment
rs.close();
stmt.close();
conn.close();
}catch(SQLException se){
//Handle errors for JDBC
se.printStackTrace();
}catch(Exception e){
//Handle errors for Class.forName
e.printStackTrace();
}finally{
//finally block used to close resources
try{
if(stmt!=null)
stmt.close();
}catch(SQLException se2){
}// nothing we can do
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}//end finally try
}//end try
System.out.println("Goodbye!");
}//end main
}//end FirstExample
关于 JDBC实现增删改查,可参见
JDBC实现CRUD(增删改查) https://blog.csdn.net/qq_37867421/article/details/106410471