(六) Java数据库
一、概述
程序开发没有数据库的参与,可以说几乎是不可能的。数据库和Java都已经有了简单的了解,现在的关键是对两者进行连接,起到这一作用的正是JDBC——Java Database Connectivity,数据库桥接。JDBC提供了一整套API使应用程序对数据库进行操作,如下图所示。

首先你要有一个能用的数据库,我比较熟悉MySQL,因此我并不想跳出舒适圈子,所有的数据库操作应该没什么不同,因此就以MySQL为例,MySQL的详细安装过程见这篇随笔。但是只有命令行对数据库的管理造成困难,因此介绍一款数据库图形化界面管理工具Navicat for MySQL(一个系列的,还有针对SQL Server,Oracle和MongoDB的版本)。官网在这https://www.navicat.com.cn/,这样管理起来相当方便。
准备工作的最后一步是下载JDBC驱动jar包(不要去搞什么jdbc-odbc设置),这个非常好找,下载之后解压找到jar包(我的这版名称是mysql-connector-java-5.1.40-bin.jar)导入目标工程中的library中即可,不论你是Eclipse还是IDEA,大致流程都相同,之前对Eclipse已经轻车熟路了,现在展示以下IDEA导入jar到library库中的详细步骤。
第一步:File——Project Structure

第二步:选择library,点击加号添加

第三步:选择Java,找到那个jar包


完结撒花!!等等,这好像才刚刚开始。
整个全部流程如下:

二、数据库连接和SQL“更新”语句的执行
这里我先上一段代码,作用是在数据库中创建一个表。
import java.sql.*;
public class Connect {
public static void main (String [] args)
{
String url = "jdbc:mysql://localhost:3306/manager?useUnicode=true&characterEncoding=UTF-8&useSSL=false";
String user = "root";
String password = "123456";
try
{
// 注册驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// 获得连接对象
Connection connection = DriverManager.getConnection(url, user, password);
Statement s = connection.createStatement();
String sql = "create table course " +
"( Course_id int primary key," +
" CourseNumber varchar(10)," +
" CourseName varchar(50))";
s.executeUpdate(sql);
s.close();
connection.close();
}
catch (SQLException e)
{
}
}
}
// 注册驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// 获得连接对象
Connection connection = DriverManager.getConnection(url, user, password);
这两句代码就是通过驱动连接数据库了,首先要注册驱动,当然除了registerDriver方法,还有其他的注册方法,例如Class.forName(“com.mysql.jdbc.Driver”)等,注册驱动之后需要调用getConnection方法返回一个Connection对象,参数是String形式的数据库的url,用户名和密码,即预先设置的String串,其中红色部分代表数据库名称,要进行相应的改变。 返回的Connection对象的最重要的作用应该就是创建另外一个对象,
Statement s = connection.createStatement();
就是Statement对象,Statement对象能够执行SQL语句,其重要性不言而喻,也是任何Java数据库初学者必须要接触的类。执行SQL语句并非只有一个方法,而是分为executeUpdate()和executeQuery()两种,分别执行更新和查询功能。本节介绍更新语句的执行,包括CREATE、DROP、INSERT等不返回结果的SQL语句都被归类于此。
String sql = "create table course " +
"( Course_id int primary key," +
" CourseNumber varchar(10)," +
" CourseName varchar(50))"; s.executeUpdate(sql);
方法调用形式也比较简易,只需将SQL语句的String形式作为参数即可,但是要注意SQL语句不能语法出错,否则异常可不好定位。上述语句将会创建一个名为course的表,并且拥有三个属性。
s.close();
connection.close();
做大事者需要拘小节,不要忘记关闭对象,也许这不会影响你程序的运行,也许会,但是一个良好的编码习惯是必要的。

创建的表,在navicat中的详情展示。
大多数情况下,更新语句的功能都可以可视化的操作,因此这一部分好像显得不是非常重要,但这绝对是要必须掌握的,仅仅只会查询语句和可视化的操作效率未必高、流程未必规范。
三、SQL“查询”语句的执行
本届介绍查询语句的执行,内容比较多,主要在于对查询结果的信息获取和处理。分为对列的处理和对行的处理,先来看对列的处理:
import java.sql.*;
public class Select {
public String url;
public String user;
public String password;
Select(String a,String b,String c)
{
url = a;
user = b;
password = c;
}
public Connection getConnection () throws SQLException
{
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// 获得连接对象
Connection connection = DriverManager.getConnection(url, user, password);
return connection;
}
public static void main(String []args)
{
String url = "jdbc:mysql://localhost:3306/manager?useUnicode=true&characterEncoding=UTF-8&useSSL=false";
String user = "root";
String password = "123456";
try {
Select select = new Select(url, user, password);
Connection c = select.getConnection();
Statement s = c.createStatement();
String sql = "select * from course";
ResultSet rs = s.executeQuery(sql);
ResultSetMetaData rm = rs.getMetaData();
int n = rm.getColumnCount();
for (int i = 0; i < n; i++) {
System.out.println("第" + (i + 1) + "列");
System.out.println("名称是:" + rm.getColumnName(i + 1));
System.out.println("类型是:" + rm.getColumnTypeName(i + 1));
System.out.println("精度是:" + rm.getPrecision(i + 1));
}
s.close();
c.close();
}
catch (SQLException e)
{
}
}
}
执行语句和更新基本相同,但是方法换成了executeQuery()方法,然后返回ResultSet类的实例对象,查询结果的所有信息都将从中获得。如想获得查询结果的列信息,还需要调用getMetaData()返回ResultSetMetaData对象。
上述代码的运行结果是:
第1列
名称是:Course_id
类型是:INT
精度是:11
第2列
名称是:CourseNumber
类型是:VARCHAR
精度是:10
第3列
名称是:CourseName
类型是:VARCHAR
精度是:50
处理行可能会是更为关注的内容,也即对查询的结果进行处理。行的处理一般是直接对ResultSet对象进行处理,先看实例
import java.sql.*;
public class Select2 {
public static void main(String []args) {
String url = "jdbc:mysql://localhost:3306/manager?useUnicode=true&characterEncoding=UTF-8&useSSL=false";
String user = "root";
String password = "123456";
try {
Select select = new Select(url, user, password);
Connection c = select.getConnection();
Statement s = c.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql = "select * from course";
ResultSet rs = s.executeQuery(sql);
/* row */
rs.last();
System.out.println("共查询到"+rs.getRow()+"条记录");
rs.beforeFirst();
while(rs.next())
{
System.out.println("第"+rs.getRow()+"行:");
System.out.println("id is "+rs.getInt(1));
System.out.println("number is "+rs.getInt(2));
System.out.println("name is "+rs.getString("CourseName"));
}
s.close();
c.close();
}
catch (SQLException e)
{
}
}
}
结果如下:
共查询到3条记录
第1行:
id is 1
number is 1010
name is Java
第2行:
id is 2
number is 1111
name is C
第3行:
id is 3
number is 1234
name is C++
数据库中的数据:

首先的与之前的区别在于createStatement()的参数不能再是空的了,多了两个参数,第一个是resultSetType设置返回结果集访问记录的顺序:

第二个参数是resultSetConcurrency设置是否能对结果集进行更新



而程序中的两个参数使得可以对结果集的记录以任意的顺序进行访问,较为常用。
其余的方法可以将ResultSet考虑成一个游标或者指针,last()将其指向最后一条记录,first()则是第一条,beforeFirst()指向第一条之前,next()指向下一条,初始情况指向第一条之前,与beforeFirst()一致,getRow()能够获取当前的行号。而常用的遍历结果集的方法正如代码中所示结合next()方法和getInt()或者getString()这些方法【参数可以是列名,也可以是列标号】。
此外,ResultSet也有打开和关闭两种状态,每个Statement实例对象可以进行多次查询,并产生多个ResultSet对象,但是每个时刻只能有一个处于打开状态,即当每次运行SQL产生新的ResultSet对象时,其他的就会关闭。当Statement对象被关闭时,其产生的ResultSet对象也都会关闭。
插一个JDBC(数据库)和JAVA类型的对照表:

四、带参数的SQL语句执行
实际上带参数的SQL语句是十分常用的,尤其是在嵌入到程序中时。比如当我输入课程号,输出相应的课程名称:
Select select = new Select(url, user, password);
Connection c = select.getConnection();
Statement s = c.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); Scanner sc = new Scanner(System.in);
int ii = sc.nextInt();
String sql = "select CourseName from course where Course_id = ' " + ii +" '";
ResultSet rs = s.executeQuery(sql); rs.next(); System.out.println("name is " + rs.getString("CourseName")); s.close();
c.close();
结果:

借此实现一些简单的数据库交互操作,但是更常见的方法是使用PreparedStatement,如下
Select select = new Select(url, user, password);
Connection c = select.getConnection(); Scanner sc = new Scanner(System.in);
int ii = sc.nextInt(); /* PreparedStatement */
PreparedStatement ps = c.prepareStatement("select CourseName from course where Course_id = ?");
ps.setInt(1,ii);
ResultSet rs= ps.executeQuery();
rs.next();
System.out.println("name is " + rs.getString("CourseName")); ps.close();
c.close();
1.首先PreparedStatement也是通过Connection对象调用方法preparedStatement,值得一提的是与createStatement()不同,参数不是为空,或者ResultType等设置,而必须是sql语句,可带?代表未定参数。
2.之后设置这些参数int型就用setInt()方法,字符串就用setString()方法,一般都是两个参数,第一个代表是前面sql中的第几个?,第二个是具体值。
3.最后PreparedStatement执行直接调用executeQuery()方法,无需任何参数即可返回ResultSet对象,之后的步骤和Statement就相同了。
比较Statement和PreparedStatement来说,后者会更加安全,而且多次使用会提高效率。但是单次执行来说前者会是更优的选择。
(六) Java数据库的更多相关文章
- JDBC与JAVA数据库编程
一.JDBC的概念 1. JDBC (Java DataBase Connectivity) Java数据库连接 a) 主要提供java数据库应用程序的API支持 2. JDBC的主要功能 a) 创建 ...
- JAVA数据库基本操作 (转)
JAVA数据库基本操作指南 Java数据库操作基本流程:取得数据库连接 - 执行sql语句 - 处理执行结果 - 释放数据库连接. 一.取得数据库连接 1.用DriverManager取数据库连接 ...
- Hbase深入学习(六) Java操作HBase
Hbase深入学习(六) ―― Java操作HBase 本文讲述如何用hbase shell命令和hbase java api对hbase服务器进行操作. 先看以下读取一行记录hbase是如何进行工作 ...
- java面向对象下:Java数据库编程
19.Java数据库编程: JDBC概述: JDBC(Java Database Connection)是java中提供的一套数据库编程API,它定义了一套用来访问数据库的标准Java类 ...
- Java数据库设计14个技巧
Java数据库设计14个技巧 1. 原始单据与实体之间的关系 可以是一对一.一对多.多对多的关系.在一般情况下,它们是一对一的关系:即一张原始单据对应且只对应一个实体.在特殊情况下,它们可能是一对 ...
- MinerDB.java 数据库工具类
MinerDB.java 数据库工具类 package com.iteye.injavawetrust.miner; import java.sql.Connection; import java.s ...
- MinerBean.java 数据库表 miner bean
MinerBean.java 数据库表 miner bean package com.iteye.injavawetrust.miner; import java.util.Date; /** * 数 ...
- Java数据库学习之模糊查询(like )
Java数据库学习之模糊查询(like ): 第一种方式:直接在SQL语句中进行拼接,此时需要注意的是parm在SQL语句中需要用单引号拼接起来,注意前后单引号之间不能空格 String sql = ...
- Java数据库操作(MySQL与SQLserver)
在java编程开发中,数据库的开发是重头戏. MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品: SQL Server是由Microsoft开发 ...
随机推荐
- [转帖]PKI技术原理(收集 整理 归纳)
PKI技术原理(收集 整理 归纳) https://blog.51cto.com/3layer/20430 总结归纳的 灰常好.. 7layer关注8人评论39427人阅读2007-03-14 11: ...
- 代码优化:Java编码技巧之高效代码50例
出处: Java编码技巧之高效代码50例 1.常量&变量 1.1.直接赋值常量值,禁止声明新对象 直接赋值常量值,只是创建了一个对象引用,而这个对象引用指向常量值. 反例: Long i = ...
- JSON函数表1
jsoncpp 主要包含三个class:Value.Reader.Writer.注意Json::Value 只能处理 ANSI 类型的字符串,如果 C++ 程序是用 Unicode 编码的,最好加一个 ...
- 区间dp 整数划分问题
整数划分(四) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近 ...
- mysql解决fail to open file的方法
由于没有安装有mysql的可视化工具,在使用cmd导入sql文件时,使用source 命令时出现 fail to open file的错误,各种查找后使用以下方法解决了: 1.首先进入mysql数据库 ...
- vue.js中,如何把text按html格式化显示
先说方法:v-html = "你的字符串" <el-table-column type="expand" label="详情" hea ...
- 进阶Java编程(4)多线程深入话题
多线程深入话题 1,优雅的停止线程 在多线程操作之中如果要启动多线程使用的肯定是Thread类中的start()方法,而如果对于多线程需要进行停止处理,Thread类原本提供有stop()方法,但是这 ...
- 换发型app任性扣费?苹果app订阅任性扣费?怎么办?刚成功
2019年9月18日17:09:27 什么黑猫举报没用 先关闭订阅 账户中心自助申请试试,不通过再进行下面这步 https://getsupport.apple.com/?caller=home&am ...
- JS基础_质数练习的改进,提高程序执行效率
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- O025、OpenStack 通用设计思路
参考https://www.cnblogs.com/CloudMan6/p/5427981.html API 前端服务 每个OpenStack组件可能包含若干子服务,其中必定有一个API服务负 ...