(六) 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开发 ...
随机推荐
- 并发-synchronized
线程并发-synchronized和Lock简单认知 前几天刚加深了线程的了解,期间在验证各种方法及多线程时遇到一些疑问,在高并发的情况下,怎么做才能保证程序还能按照我们预期的正常运行下去,这就是我们 ...
- 修改anocanda的channel
http://blog.csdn.net/mtj66/article/details/57074986
- pyton 类(4) 静态方法
class Cat(): tag = ' 猫科动物 ' def __init__(self, name): self.name = name @staticmethod def breah(): pr ...
- Python 3.8.0 正式版发布,新特性初体验 全面介绍
Python 3.8.0 正式版发布,新特性初体验 北京时间 10 月 15 日,Python 官方发布了 3.8.0 正式版,该版本较 3.7 版本再次带来了多个非常实用的新特性. 赋值表达式 PE ...
- 本地代码库,提交远程git
1.在git上新建项目,并填好相关信息 2.新建成功后,复制项目地址 3.idea新建本地仓库 4.Add所有文件,然后提交(commit) 5.先打开push界面,设置git远程地址,然后关掉,先p ...
- Jmeter之Dummy Sampler
Dummy Sampler(Dummy取样器) Dummy Sampler就像是一个模拟器,需要自己填入请求和响应的信息.(原理类似mock服务) 在没有服务的情况下,测试人员依据Dummy Samp ...
- Spring Boot源码分析-启动过程
Spring Boot作为目前最流行的Java开发框架,秉承"约定优于配置"原则,大大简化了Spring MVC繁琐的XML文件配置,基本实现零配置启动项目. 本文基于Spring ...
- java——包装类数据缓存 ==号详解
Java对部分经常使用的数据采用缓存技术,即第一次使用该数据则创建该数据对象并对其进行缓存, 当再次使用等值对象时直接从缓存中获取,从而提高了程序执行性能.(只对常用数据进行缓存) Java中只是对部 ...
- vue入门:(条件渲染)
v-if v-show v-else 一.v-if:生成或者移出一个元素 <div id="example"> <button v-on:click=" ...
- cookie、sessionStorage和localStorage区别
// 数据存储 cookie:生命周期一般是手动设置失效的时间,大小为4k,易用性不高,需要自己封装(封装请看上一篇博客) sessionStorage:生命周期是浏览器关闭接失效,大小为5m或者更大 ...