Java操作数据库——使用JDBC连接数据库

摘要:本文主要学习了如何使用JDBC连接数据库。

背景

数据持久化

数据持久化就是把数据保存到可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以“固化”,而持久化的实现过程大多通过各种关系数据库来完成。

持久化的主要应用是将内存中的数据存储在关系型数据库中,当然也可以存储在磁盘文件、XML数据文件中。

基础

概念

JDBC的全称是Java Database Connectivity,意为Java和数据库的连接。

JDBC是SUN公司提供的一套操作数据库的接口规范,定义了用来访问数据库的标准Java类库,使用这个类库可以更加方便地访问数据库资源。

程序员在使用数据库的时候,需要安装数据库驱动,不同的数据库的驱动也是不同的。所以为了程序员开发方便,SUN公司提供了一套接口,让数据库厂商实现这些接口,程序员只需要使用这个接口就可以操作不同的数据库,不需要关注底层数据库驱动的安装,从而大大简化和加快了开发过程。

架构

JDBC接口包括两个层次:

JDBC API:即面向应用的API,是一个抽象的接口,供应用程序开发人员使用,提供了程序到JDBC管理器的连接。

JDBC Driver API:即面向数据库驱动的API,需要开发商去实现这个接口,提供了JDBC管理器到数据库驱动程序的连接。

规范

主要有四个核心对象:

DriverManager类(java.sql.DriverManager):用于注册驱动,创建连接对象。

Connection接口(java.sql.Connection):表示与数据库创建的连接。

Statement接口(java.sql.Statement):执行数据库SQL语句,并返回相应结果的对象。

ResultSet接口(java.sql.ResultSet):结果集或一张虚拟表,用于存储表数据的对象。

其中,Statement接口还有两个子接口:

PreparedStatement接口(java.sql.PreparedStatement):预编译对象,是Statement接口的子接口,用于解决sql的注入问题。

CallableStatement接口(java.sql.CallableStatement):支持带参数的SQL操作,支持调用存储过程,是PreparedStatement接口的子接口。

连接数据库

下面的说明以连接MySQL数据库为例。

准备工作

拥有一个可以正常访问的MySQL数据库,已经可以登录使用的用户名和密码。

建立一个准备连接数据库的项目。

导入jar包

导入Java连接MySQL所用到的jar包,这个jar包通常是由数据库的厂商提供的,这里下载的是 mysql-connector-java-5.1.32.jar 这个包。

那Eclipse为例,在项目上右键,然后点击Properties:

然后在弹出的页面左侧找到 Java Build Path 目录并进入,选择 Libraries 标签页,找到标签页右侧的 Add External JARs... 按钮:

找到下载的jar包,点击打开:

可以看到jar包被成功导入到项目中:

点击OK完成导入。

加载驱动

加载数据库驱动的方法是调用Class类的静态方法forName。语法格式如下:

 public static Class<?> forName(String className)

其中,传入的参数className是每个数据库厂商各自提供的一个驱动程序名称。

不同的数据库,驱动程序名称如下:

 MySQL驱动:com.mysql.jdbc.Drive
Oracle驱动:oracle.jdbc.driver.OracleDriver
SQLServer驱动:com.microsoft.sqlserver.jdbc.SQLServerDriver
PostgreSQL驱动:org.postgresql.Driver
DB2驱动:com.ibm.db2.jdbc.net.DB2Driver
Sybase驱动:com.sybase.jdbc.SybDriver

建立连接

使用DriverManager类的静态方法getConnection建立到指定数据库的连接。语法格式如下:

 public static Connection getConnection(String url, String user, String password)

url是SUN公司与数据库厂商之间的一种协议,user是连接数据库的用户名,password是用户名对应的密码。

不同的数据库,url协议的格式如下:

 MySQL格式:jdbc:mysql://地址或主机名:端口号/数据库名
Oracle格式:jdbc:oracle:thin:@地址或主机名:端口号:数据库名
SQLServer格式:jdbc:sqlserver://地址或主机名:端口号;databaseName=数据库名
PostgreSQL格式:jdbc:postgresql://地址或主机名:端口号/数据库名
DB2格式:jdbc:db2:地址或主机名:端口号/数据库名
Sybase格式:jdbc:sybase:Tds:地址或主机名:端口号/数据库名

如果是在本机并且用的是默认的端口号,可以将地址和端口号省略:

 jdbc:mysql:///数据库名

建议url中的文件编码、数据库连接编码、数据库编码保持一致,向数据库中添加数据时,连接参数最好包含Unicode字符支持,这样添加的字符就能被数据库识别并且正常显示了:

 jdbc:mysql://地址或主机名:端口号/数据库名?useUnicode=true&characterEncoding=UTF-8

至此,就成功获取到了连接MySQL数据库的Connection对象。

执行语句

获取到连接之后,使用Connection接口的createStatement方法获取Statement对象。语法格式如下:

 Statement createStatement()

获取到了Statement对象之后,使用executeQuery方法执行查询语句得到ResultSet类型的结果集,使用executeUpdate方法执行增加、删除、修改语句得到int类型的记录数。

释放连接

数据库连接Connection是非常稀有的资源,用完后必须马上释放,如果Connection不能及时正确的关闭将导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。

释放的方法是通过调用Connection的close方法,语法格式如下:

 void close()

一次完整的操作数据库的流程包括加载驱动、建立连接、执行语句、释放连接。其中,加载驱动只执行一次即可,建立的连接用完之后必须马上释放。

连接数据库实例

在程序里配置连接信息

完整代码如下:

 public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection conn = null;
try {
String url = "jdbc:mysql://192.168.35.128:3306/demo";
String user = "root";
String password = "123456";
conn = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

在配置文件里配置连接信息

配置文件 jdbc.properties 在 src 目录下,和当前的源文件的根目录 package jdbc; 平级,内容如下:

 driverClass=com.mysql.jdbc.Driver
url="jdbc:mysql://192.168.35.128:3306/demo"
user=root
password=123456

完整代码如下:

 public static void main(String[] args) {
Properties pros = new Properties();
try {
pros.load(TestConnection.class.getClassLoader().getResourceAsStream("jdbc.properties"));
} catch (IOException e) {
e.printStackTrace();
}
try {
Class.forName(pros.getProperty("driverClass"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection conn = null;
try {
String url = pros.getProperty("url");
String user = pros.getProperty("user");
String password = pros.getProperty("password");
conn = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

增删改查

查询

使用实例:

 public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
String url = "jdbc:mysql://192.168.35.128:3306/demo";
String user = "root";
String password = "123456";
conn = DriverManager.getConnection(url, user, password);
stmt = conn.createStatement();
rs = stmt.executeQuery("select * from student");
while (rs.next()) {
System.out.println(rs.getInt("id") + "\t" + rs.getString(2) + "\t" + rs.getString(3) + "\t" + rs.getString("address"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

增加、修改、删除

使用实例:

 public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection conn = null;
Statement stmt = null;
try {
String url = "jdbc:mysql://192.168.35.128:3306/demo";
String user = "root";
String password = "123456";
conn = DriverManager.getConnection(url, user, password);
stmt = conn.createStatement();
int count = stmt.executeUpdate("delete from student where id = 903");
System.out.println("受影响的行数:" + count);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

Statement接口

Statement接口是通过Connection的createStatement方法获取的,用来执行SQL语句并返回相应的结果。语法格式如下:

 Statement createStatement()

使用完之后需要手动关闭Statement对象。

PreparedStatement接口

PreparedStatement接口是通过Connection的preparedStatement方法获取的,是Statement的子接口,表示一条预编译过的SQL语句。语法格式如下:

 PreparedStatement prepareStatement(String sql)

传入的SQL语句中的参数用问号“?”来表示,调用PreparedStatement对象的setXxx方法来设置这些参数。setXxx方法有两个参数,第一个参数是要设置的参数索引(从1开始),第二个是设置的参数值。

使用Statement可能会因为字符串拼接导致被人SQL注入攻击,但使用PreparedStatement不需要拼接字符串,而是使用占位符的方法,有效避免了SQL注入攻击的问题。

使用举例:

 pstmt = conn.prepareStatement("select * from student where id = ?");
pstmt.setInt(1, 904);
rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3) + "\t" + rs.getString("address"));
}

ResultSet接口

使用Statement接口的executeQuery方法执行传入的查询语句,并得到ResultSet类型的结果集。语法格式如下:

 ResultSet executeQuery(String sql)

ResultSet接口由数据库厂商实现,以逻辑表格的形式封装了执行数据库操作的结果集。

ResultSet对象维护了一个指向当前数据行的游标,游标默认从1开始,可以通过next方法移动到下一行。

使用完之后需要手动关闭ResultSet对象。

常用方法:

 byte getByte(int columnIndex) throws SQLException;
byte getByte(String columnLabel) throws SQLException;
byte[] getBytes(int columnIndex) throws SQLException;
byte[] getBytes(String columnLabel) throws SQLException;
short getShort(int columnIndex) throws SQLException;
short getShort(String columnLabel) throws SQLException;
int getInt(int columnIndex) throws SQLException;
int getInt(String columnLabel) throws SQLException;
long getLong(int columnIndex) throws SQLException;
long getLong(String columnLabel) throws SQLException;
float getFloat(int columnIndex) throws SQLException;
float getFloat(String columnLabel) throws SQLException;
double getDouble(int columnIndex) throws SQLException;
double getDouble(String columnLabel) throws SQLException;
String getString(int columnIndex) throws SQLException;
String getString(String columnLabel) throws SQLException;
boolean getBoolean(int columnIndex) throws SQLException;
boolean getBoolean(String columnLabel) throws SQLException;
java.sql.Date getDate(int columnIndex) throws SQLException;
java.sql.Date getDate(String columnLabel) throws SQLException;
java.sql.Time getTime(int columnIndex) throws SQLException;
java.sql.Time getTime(String columnLabel) throws SQLException;
java.sql.Timestamp getTimestamp(int columnIndex) throws SQLException;
java.sql.Timestamp getTimestamp(String columnLabel) throws SQLException;
Object getObject(int columnIndex) throws SQLException;
Object getObject(String columnLabel) throws SQLException; boolean next() throws SQLException;
void close() throws SQLException; ResultSetMetaData getMetaData() throws SQLException;

使用举例:

 stmt = conn.createStatement();
rs = stmt.executeQuery("select * from student");
while (rs.next()) {
System.out.println(rs.getInt("id") + "\t" + rs.getString(2) + "\t" + rs.getString(3) + "\t" + rs.getString("address"));
}

ResultSetMetaData接口

ResultSetMetaData对象可以用来获取ResultSet对象中列的类型和属性信息。

常用方法:

 int getColumnCount() throws SQLException;
int getColumnTypeName(int column) throws SQLException;
String getColumnLabel(int column) throws SQLException;
String getColumnName(int column) throws SQLException;

使用举例:

 stmt = conn.createStatement();
rs = stmt.executeQuery("select * from student");
while (rs.next()) {
ResultSetMetaData rsmd = rs.getMetaData();
System.out.println(rsmd.getColumnName(1) + "=" + rs.getInt("id") + "\t" + rsmd.getColumnName(2) + "=" + rs.getString(2));
}

Java操作数据库——使用JDBC连接数据库的更多相关文章

  1. Java操作数据库——在JDBC里使用事务

    Java操作数据库——在JDBC里使用事务 摘要:本文主要学习了如何在JDBC里使用事务. 使用Connection的事务控制方法 当JDBC程序向数据库获得一个Connection对象时,默认情况下 ...

  2. Java操作数据库之JDBC增删改查

    1.java连接MySql数据库 代码区域: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ...

  3. Java操作数据库——使用连接池连接数据库

    Java操作数据库——使用连接池连接数据库 摘要:本文主要学习了如何使用JDBC连接池连接数据库. 传统方式和连接池方式 传统方式的步骤 使用传统方式在Java中使用JDBC连接数据库,完成一次数据库 ...

  4. JDBC 数据库连接 Java操作数据库 jdbc快速入门

    JDBC基本概念 Java DataBase Connectivity 数据库连接 java操作数据库 本质上(sun公司的程序员)定义的一套操作关系型数据库的规则 既接口  更新内容之前 代码 pa ...

  5. JDBC数据源(DataSource)数据源技术是Java操作数据库的一个很关键技术,流行的持久化框架都离不开数据源的应用。

    JDBC数据源(DataSource)的简单实现   数据源技术是Java操作数据库的一个很关键技术,流行的持久化框架都离不开数据源的应用. 2.数据源提供了一种简单获取数据库连接的方式,并能在内部通 ...

  6. JDBC 4.0 开始Java操作数据库不用再使用 Class.forName加载驱动类了

    JDBC 4.0 开始Java操作数据库不用再使用 Class.forName加载驱动类了 代码示例 转自 https://docs.oracle.com/javase/tutorial/jdbc/o ...

  7. JavaSE学习总结(九)—— Java访问数据库(JDBC)

    一.JDBC简介 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java ...

  8. java操作数据库:增删改查

    不多bb了直接上. 工具:myeclipse 2016,mysql 5.7 目的:java操作数据库增删改查商品信息 test数据库的goods表 gid主键,自增 1.实体类Goods:封装数据库数 ...

  9. Java操作数据库——手动实现数据库连接池

    Java操作数据库——手动实现数据库连接池 摘要:本文主要学习了如何手动实现一个数据库连接池,以及在这基础上的一些改进. 部分内容来自以下博客: https://blog.csdn.net/soonf ...

随机推荐

  1. 设计模式之单例模式C#实现

    前言 单例模式是老生常谈的一种设计模式,同时它是最简单也是最容易被忽视的一种设计模式. 下面是一些个人看法: (1) 单例类需要保证自己的唯一性,同时也需要避免被继承,即需要使用sealed修饰: ( ...

  2. Nginx实现负载均衡时常用的分配服务器策略

    场景 Nginx配置实例-负载均衡实例:平均访问多台服务器: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103019576 在 ...

  3. Android Battery 架构【转】

    Android Battery 架构 Android电源 android中和电源相关的服务有两个他们在/frameworks/base/services/core/java/com/android/s ...

  4. windows客户端访问FTP服务器

    客户端访问FTP服务器步骤: 首先双击此电脑,在弹出的窗口输入如下信息 刚安装完的FTP服务器只有一个pub目录,因为这里是使用匿名用户登录的 FTP服务器默认的匿名目录在/var/ftp/pub/下 ...

  5. hadoop集群搭建教程

    1. 相关软件准备: VMware-workstation-full-15.0.4-12990004.exe CentOS-7-x86_64-DVD-1810.iso jdk-8u231-linux- ...

  6. Angular 彻底解决 Dropdown 在 Safari 上无法自动关闭的问题

    之前在 Safari 上用 focus 事件来实现 Dropdown 下拉菜单,结果在 iOS 上不兼容. 尝试了 MDN 和 stack over flow 上各种奇技淫巧,然而在 iOS 上全都败 ...

  7. ubuntu下安装截图工具

    安装shutter 1.添加安装包软件源 sudo add-apt-repository ppa:shutter/ppa 2.更新软件源并且安装 sudo apt-get update sudo ap ...

  8. mac下使用minicom几个注意事项

    一 安装: 安装是比较简单的,直接: brew install minicom 二 查找串口驱动 这里不得不吐槽苹果公司,搞一个串口,从来就不像ubuntu中那样很简洁的名字,这里的名字一般是一长串, ...

  9. IT兄弟连 HTML5教程 DIV+CSS网页标准化布局 小结及习题

    小结 DIV+CSS布局页面的优势:表现和内容相分离.代码简洁,提高页面浏览速度.易于维护和改版.提高搜索引擎对网页的索引效率.每个HTML元素都可以看作一个区块,类似于装了东西的盒子,称为盒子模式. ...

  10. 12-19 js

    js是一个脚本语言  可插入到HTML网页文件中 在浏览器中执行 1 如何插入到网页中 1. 内部穿插 script 标签 type属性在网页中使用 2. 外部引入 script src属性引用js文 ...