(六) 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开发 ...
随机推荐
- PHP学习(2)——操作符与迭代整理
目录: 10.操作符整理 11.表单计算代码 12.优先级与结合性 13.可变函数 14.条件判断 15.循环迭代 16.跳出控制 17.可替换的控制结构 10.操作符 10.1 算术操作符 算术操作 ...
- 如何禁止谷歌浏览器隐藏url的www前缀
若要将Chrome浏览器的设置恢复为隐藏HTTP.HTTPS以及WWW前缀,则只需再次进入此页面: chrome://flags/#omnibox-ui-hide-steady-state-url-s ...
- [bzoj2288]【POJ Challenge】生日礼物_贪心_堆
[POJ Challenge]生日礼物 题目大意:给定一个长度为$n$的序列,允许选择不超过$m$个连续的部分,求元素之和的最大值. 数据范围:$1\le n, m\le 10^5$. 题解: 显然的 ...
- [转帖]字符编码笔记:ASCII,Unicode 和 UTF-8
字符编码笔记:ASCII,Unicode 和 UTF-8 http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html 转帖 ...
- 【LOJ】#3090. 「BJOI2019」勘破神机
LOJ#3090. 「BJOI2019」勘破神机 为了这题我去学习了一下BM算法.. 很容易发现这2的地方是\(F_{1} = 1,F_{2} = 2\)的斐波那契数列 3的地方是\(G_{1} = ...
- Feign的雪崩处理
在声明式远程服务调用Feign中,实现服务灾难性雪崩效应处理也是通过Hystrix实现的.而feign启动器spring-cloud-starter-feign中是包含Hystrix相关依赖的.如果只 ...
- 【spring boot】3.spring boot项目,绑定资源文件为bean并使用
整个例子的结构目录如下: 1.自定义一个资源文件 com.sxd.name = 申九日木 com.sxd.secret = ${random.value} com.sxd.intValue = ${r ...
- codeforce C. Success Rate
写完这道题目才发现自己对二分的理解太浅了 这题是典型的利用二分“假定一个问题可行并求最优解” 二分是通过不断缩小区间来缩小解的范围,最终得出解的算法 我们定义一个c(x) 表示判断函数 如果对任意y& ...
- HashMap—— values() remove方法 containsKey()方法 containsValue()方法
values()方法:看下面的实例,就是把所有的value值封装成一个connection型的数组 Map<Integer,Student> students=new HashMap< ...
- asp.net 13 缓存,Session存储
1.缓存 将数据从数据库/文件取出来放在服务器的内存中,这样后面的用来获取数据,不用查询数据库,直接从内存(缓冲)中获取数据,提高了访问的速度,节省了时间,也减轻了数据库的压力. 缓冲空间换时间的技术 ...