数据库介绍
数据库是一种存储结构,允许使用各种格式输入、处理和检索数据,不必再每次需要数据时重新输入。当前比较流行的数据库主要有MySQL、Oracle、SQL Server等
使用JDBC操作数据库,SQL语句是比不可少的,SQL是一种结构化查询语句,通过使用它,可以很方便地查询、操作、定义和控制数据库中的数据(select、insert、update、delete)
JDBC(Java DataBase Connectivity)简介
它是一种可用于执行SQL语句的Java API(Application Programming Interface,应用程序设计接口),是连接数据库和Java应用程序的纽带
由于JDBC是一种底层的API,因此访问数据库时需要在业务逻辑层中嵌入SQL语句
JDBC常用类和接口(java.sql)
1.加载数据库驱动
(1)加载Oracle数据库驱动程序(包名为ojdbc6.jar)
Class.forName("oracle.jdbc.driver.OracleDriver");
(2)加载SQL Server 2005 以上版本数据库驱动程序(包名为sqljdbc.jar)
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
(3)加载MySQL驱动包
Class.forName("com.mysql.jdbc.Driver");
2.DriverManager类(管理驱动)
DriverManager类用来管理数据库中的所有驱动程序,它是JDBC的管理层,作用于用户和驱动程序之间,跟踪可用的驱动程序,并在数据库的驱动程序之间建立连接
常用方法
方法 | 描述 |
---|---|
getConnection(String url,String user,String password) | 指定三个入口(依次是URL、用户名、密码)来获取与数据库的连接 |
setLoginTimeout() | 获取驱动程序试图登录到某一数据库时可以等待的最长时间,以秒为单位 |
println(String message) | 将一条消息打印到当前JDBC日志流中 |
3.Connection接口(获得连接)
代表与特定的数据连接
常用方法
方法 | 描述 |
---|---|
createStatement() | 创建Statement对象 |
createStatement(int resultSetTpye,int resultSetConnection) | 创建一个Statement对象,该对象将生成具有给定类型、并发性和保存性的ResultSet对象 |
preparedStatement() | 创建预处理对象preparedStatement |
prepareCall(String sql) | 创建一个CallableStatement对象来调用数据库存储过程 |
isReadOnly() | 查看当前Connection对象的读取模式是否是只读形式 |
setReadOnly() | 设置当前Connection对象的读写模式,默认为非只读模式 |
commit() | 是所有上一次提交/回滚后进行的更改成为持久的操作,并释放此Connection对象当前持有的所有数据库锁 |
roolback() | 取消在当前事务中进行的所有更改,并释放此Connection对象当前持有的所有数据库锁 |
close() | 立即释放此Connection对象的数据库和JDBC资源,而不是等待它们被自动释放 |
获得连接
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, user, password);
4.Statement接口(发送SQL)
在已经建立连接的基础上向数据库发送SQL语句(SQL注入)
常用方法
方法 | 描述 |
---|---|
execute(String sql) | 执行静态的select语句,该语句可能返回多个结果集 |
executeQuery(String sql) | 执行给定的SQL语句,该语句返回单个ResultSet对象 |
clearBatch() | 清空此Statement对象的当前SQL命令列表 |
executeBatch() | 将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。数组元素的排序与SQL语句的添加顺序对应 |
addBatch(String sql) | 将给定的SQL命令添加到此Statement对象的当前命令列表中。如果驱动程序不支持批量处理,将抛出异常 |
close() | 释放Statement实例占用的数据库和JDBC资源 |
发送SQL
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
stmt.execute("update user set name=1234 where id=1");
5.PreparedStatement接口(发送SQL,可以防止SQL注入)
继承自Statement接口,用来指定动态的SQL语句
常用方法
方法 | 描述 |
---|---|
setInt(int index,int k) | 将指定位置的参数设置为int值 |
setFloat(int index,float f) | 将指定位置的参数设置为float值 |
setLong(int index,long l) | 将指定位置的参数设置为long值 |
setDouble(int index,double d) | 将指定位置的参数设置为double值 |
setBoolean(int index,boolean b) | 将指定位置的参数设置为boolean值 |
setDate(int index,date date) | 将指定位置的参数设置为date值 |
executeQuery() | 在此PreparedStatement对象中执行SQL查询,并返回该查询生成的ResultSet对象 |
setString(int index,String s) | 将指定位置的参数设置为对应的String值 |
setNull(int index,int sqlType) | 将指定位置的参数设置为SQL NULL |
executeUpdate() | 执行前面包含的参数的动态insert、update或delete语句 |
clearParameters() | 清除当前所有参数的值 |
安全发送SQL
使用连接数据库对象conn的prepareStatement()方法创建PreparedStatement对象sql,其中设置一个参数
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement ps = conn.prepareStatement("select * from stuednt where name=?");
ps.setString(1, "阿强");
ps.executeQuery();
6.CallableStatement接口
CallableStatement接口继承并扩展了PreparedStatement接口,用来执行对数据库的存储过程的调用
常用方法
方法 | 描述 |
---|---|
get+数据类型(如getInt) | 以JAVA中指定类型值的形式获取指定的JDBC中相应类型参数的值 |
set+数据类型(如setInt) | 将指定参数是设置为Java中指定数据类型的值 |
在执行存储过程之前,必须注册所有输出参数(out)的类型,它们的值是在执行后通过getXXX()方法获得的
使用Connection对象的prepareCall方法生成一个CallableStatement对象,并指定执行pro_insert存储过程:
// 调用存储过程
CallableStatement cablStmt = conn.prepareCall("{call pro_insert (?,?)}");
每个‘?’代表一个参数,之间用‘,’分隔
7.ResultSet接口(查询数据库获得结果集)
ResultSet接口类似于一个临时表,用来暂时存放数据库查询操作所获得的结果集。ResultSet实例具有指向当前数据行的指针,指针开始的位置在第一条记录前面,通过next()方法可将指针向下移
常用方法
(1)get + 数据类型(如getInt)
以指定类型值的获取ResultSet对象的当前行的指定列值
如果列值是NULL,则返回值是int:0/Float:0/Date、boolean、String、Object:null
方法 | 描述 |
---|---|
first() | 将指针移到当前记录的第一行 |
last() | 将指针移到当前记录的最后一行 |
next() | 将指针向下移一行 |
beforeFirst() | 将指针移到集合的开头(第一行位置) |
afterLast() | 将指针移到集合的尾部(最后一行位置) |
absolute(int index) | 将指针移到ResultSet给定编号的行 |
isFirst() | 判断指针是否位于当前ResultSet集合的第一行,是,返回true |
isLast() | 判断指针是否位于当前ResultSet集合的最后一行 |
updateInt() | 用Int值更新指定列 |
updateLong() | 用指定的long值更新指定列 |
updateString() | 用指定的string值更新指定列 |
updateObject() | 用Object值更新指定列 |
updateNull() | 将指定的列值修改为NULL |
updateDate() | 用指定的date值更新指定列 |
updateDouble() | 用指定的double值更新指定列 |
getrow() | 查看当前行的索引 |
insertRow() | 将插入行的内容插入到数据库 |
updateRow() | 将当前的内容同步到数据表 |
deleteRow() | 删除当前行,但并不同步到数据库总,而是在执行close()方法后同步到数据库 |
获取结果集
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement ps = conn.prepareStatement("select * from user where name=?");
ps.setString(1, "阿强");
ResultSet rs = ps.executeQuery();
List<User> list = new ArrayList<User>();
while(rs.next()) { //指针下移
User b = new User();
b.setId(rs.getInt("id"));
b.setName(rs.getString("name"));
list.add(b);
}
操作数据库步骤
①加载驱动程序
②建立连接
③向数据库中发送SQL语句
④处理返回结果
⑤关闭连接
简单工具类
1.basedao.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/bdqn?useUnicode=true&characterEncoding=utf-8
username=root
password=password
2.工具类
public class BaseDao {
private static String driver;
private static String url;
private static String username;
private static String password;
private static Connection conn;
private static PreparedStatement ps;
static {
InputStream in=BaseDao.class.getClassLoader().getResourceAsStream("com/dao/basedao.properties"); 相当于classes/目录
Properties p = new Properties();
try {
p.load(in);
driver=p.getProperty("driver");
url=p.getProperty("url");
username=p.getProperty("username");
password=p.getProperty("password");
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConn() {
try {
return DriverManager.getConnection(url,username,password);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
//增删改
public static void toBaseDao(String sql,Object[] obj) {
try {
conn=getConn();
ps=conn.prepareStatement(sql);
if(obj.length>0&&obj!=null) {
for(int i=0;i<obj.length;i++) {
ps.setObject(i+1, obj[i]);
}
}
ps.execute();
} catch (SQLException e) {
e.printStackTrace();
}finally {
CloseAll(conn, ps, null);
}
}
//资源关闭
public static void CloseAll(Connection conn,PreparedStatement ps,ResultSet rs) {
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(ps!=null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
JDBC(Java DataBase Connectivity)
Java应用程序与各种不同数据库之间进行对话的媒介,可以把数据持久的保存,一种持久化机制。
持久化:将程序中的数据在瞬时状态和持久状态键转换的机制。通俗讲,就是瞬时数据(如内存中的数据,不能永久保存),持久化为持久数据(如持久化至数据库中,能够永久保存)
JDBC工作原理
1.JDBC API
提供了Java应用程序与各种不同数据库交互的标准接口,如Conntion(连接)接口、Statement接口、ResultSet(结果集)接口、PreparedStatement接口等
2.JDBC Driver Manager
驱动程序管理器,它是JDBC体系结构的支柱,负责管理各种不同的JDBC驱动,把Java应用程序连接到相应的JDBC驱动程序上,位于JDK的java.sql包中
3.JDBC驱动
JDBC驱动有各个数据库厂商或第三方中间提供,负责连接各种不同的数据库,
在开发Java应用程序时,我们只需要正确加载JDBC驱动,正确调用JDBC API,就可以进行数据访问
JDBC API介绍
DriverManager类:装载驱动程序,并为创建新的数据库连接提供支持
Connection接口:负责连接数据库并担任传送数据的任务
Statement接口:由Connection产生,负责执行SQL语句
ResultSet接口:负责保存和处理Statement执行后产生的查询结果
PreparedStatement接口:Statement的子接口,也由Connection产生,同样负责执行SQL语句。与Statement接口相比,PrepareStatement接口具有高安全性、高性能、高可读性和高可维护性的优点
JDBC访问步骤
(1)加载JDBC驱动
使用Class.forName()方法将给定的JDBC驱动类加载到Java虚拟机中。若系统中不存在给定的类,则会引发异常,异常类型为ClassNotFoundException。
Class.forName(“JDBC驱动类的名称”);
(2)与数据库建立连接
DiverManager类是JDBC的管理层,作用于用户和驱动程序之间。DriverManager类跟踪可用的驱动程序,并在数据库和相应的驱动程序之间建立连接。当调用getConnection()方法时,DriverManager类首先从已加载的驱动程序列表中找到一个可以接收该数据库URL的驱动程序,然后请求该驱动程序使用相关的URL、用户名和密码连接到数据库中,于是就建立了与数据库的连接
创建并返回引用,代码:
Connection con=DriverManager.getConnection(数据连接字符串,数据库用户名,密码);
(3)发送SQL语句,并得到返回结果
一旦建立连接,就使用该连接创建Statement接口的对象,并将SQL语句传递给他所连接的数据库。如果是查询操作,将返回类型为ResultSet的结果集,它包含执行SQL查询的结果。如果是其他操作,将根据调用方法的不同返回布尔或操作影响的记录数目
Statement stmt = con.createStatement();
ResultSet rs = stmt.executQuery(“select id,name from master”);
(4)处理返回结果
处理返回结果主要是针对查询操作的结果集,通过循环取出结果集中每条记录并作出相应处理
while(rs.next()){
Int id = rs.getInt(“id”);
String name=rs.getString(“name”);
System.out.println(id+” ”+name);
}
连接数据库
两种常用的驱动方式
①JDBC:由数据库厂商或第三方中间厂商提供、有两种较为常用的驱动方式
②JDBC-ODBC桥连方式:适用于个人开发和测试,它通过ODBC与数据库进行连接
纯Java驱动方式,它直接同数据库进行连接,在生产型开发中,推荐使用Java驱动方式
(1)使用JDBC-ODBC桥连方式连接数据库
JDK中包括了JDBC-ODBC驱动接口,所以只需要下载ODBC驱动程序
1.驱动下载
http://dev.mysql.com/downloads/connector/odbc
2.配置MySQL ODBC数据源
控制面板–>系统和安全–>管理工具–>数据源–>ODBC数据源管理器–>添加
配置如下:
(1)选择安装数据源的驱动程序
(2)配置数据源
配置 | 描述 |
---|---|
Data Source Name | 数据源名称 |
Description | 数据源描述信息 |
Server | 服务器IP地址,本机为localhost |
User | 用户名 |
Password | 密码 |
Database | 连接的数据库 |
JDBC驱动类是sun.jdbc.odbc.JdbcOdbcDriver,数据库连接字符串将以“jdbc:odbc”开始,后面跟的是数据源名称
假设我已经配置了一个myDBde ODBC数据源,数据库连接字符串就是“jdbc:odbc:myDB”,登录数据库系统的用户名为“root”口令为“root”
使用纯Java方式连接数据库
由JDBC驱动直接访问数据库,驱动程序完全用Java语言编写,运行速度快,而且具备了跨平台特点。
由于技术限制,这类JDBC驱动一般只能有数据厂商自己提供,即这类JDBC驱动只对应一种数据库,甚至某个版本的数据库,如果数据库更新了,一般需要更换JDBC驱动程序
首先需要下载数据厂商提供的驱动程序jar包,并将jar包引入工程中
Statement接口和ResultSet接口
获取对象后就可以进行各种数据库的操作了,此时需要使用Connection对象创建Statement对象
Connection接口常用方法
方法 | 描述 |
---|---|
void close() | 立即释放此Connection对象的数据库和JDBC资源 |
Statement createStatement | 创建一个Statement对象来将SQL语句发送到数据库 |
PreparedStatement prepareStatement(String sql) | 创建一个PrearedStatement对象来将参数化的SQL语句发送数据库 |
boolean isClosed() | 查询此Connection对象是否已经被关闭 |
Statement接口常用方法
方法 | 描述 |
---|---|
ResultSet executeQuery(String sql) | 可以执行SQL查询并获取ResultSet |
int executeUpdate(String sql) | 可以执行插入、删除、更新的操作,返回值是执行该操作所影响的行数 |
boolean execute(String sql) | 可以执行任意SQL语句,若结果为ResultSet对象,则返回true;若其为更新计数或者不存在任何结果,则返回false |
ResultSet接口常用方法及作用
方法 | 描述 |
---|---|
boolean next() | 将光标从当前位置向下移动一行 |
boolean previous() | 将光标从当前位置向上移动一行 |
void close() | 关闭ResultSet对象 |
int getInt(int columnIndex) | 以int形式获取结果集当前行指定列名的值 |
int getInt(String columnLabel) | 以int形式获取结果集当前行指定列名的值 |
float getFloat(int columnIndex) | 以float的形式获取结果集当前行指定列号的值 |
float getFloat(String columnLabel) | 以float的形式获取结果集当前行指定列名的值 |
String getString(int columnIndex) | 以String的形式获取结果集当前行指定的列号的值 |
String getString(String columnLabel) | 以String的形式获取结果集当前指定列名的值 |
int getRow() | 得到光标当前所指行的行号 |
boolean absolute(int row) | 光标移动到row指定的行 |
PreparedStatement接口
继承自Statement接口,比普通的Statement对象使用起来更加灵活
方法 | 描述 |
---|---|
boolean exectute() | 在此PrearedStatement对象中执行SQL语句,该语句可以是任何SQL语句。如果是Result对象,则返回true;结果是更新计算或没有结果,则返回false |
ResultSet executrQuery() | 在此PreparedStatement对象中执行SQL查询,并返回该查询生成的ResultSet对象 |
int executeUpdate() | 在此PrearedStatement对象中执行SQL语句,该语句必须是一个DML语句,如Insert、update或delete语句;或是无返回内容的SQL语句,如DDL语句。返回值是执行该操作所影响的行数 |
void setInt(int index,int x) | 将指定参数设置为给定Java int值。设置其他类型参数也类似,如setFloat(int index,flost x)、setDouble(int index,double x)等 |
void setObject(int index,Object x) | 使用给定对象设置指定参数的值 |