一
数据库是一种存储结构,它允许使用各种格式输入、处理和检索数据——不必在每次需要数据时重新输入它们。
例如,当需要某人的电话号码时,需要查看电话簿,按照姓名来查阅,这个电话本就是一个数据库。数据库具有以下主要特点:
1.实现数据共享。
2.减少数据的冗余度。
3.数据的独立性。
4.数据实现集中控制。
5.数据的一致性和可维护性,以确保数据的安全性和可靠性。
数据库系统一般基于某种数据模型,可以分层次型、网状型、关系型及面向对象型等。
1.层次型数据库
2.网状型数据库
3.面向对象型数据库
4.关系型数据库
SQL(Structure Query Language,结构化查询语言)被广泛地应用于大多数数据库中,
使用SQL语言可以方便地查询、操作、定义和控制数据库中的数据。SQL语言主要由以下几部分组成。
数据定义语言(Data Definition Language,DDL),如create、alter、drop等。
数据操纵语言(Data Manipulation Language,DML),如select、insert、update、delete等。
数据控制语言(Data Control Language,DCL),如grant、revoke等。
事务控制语言(Transaction Control Language),如commit、rollback等。
二
JDBC-ODBC桥是一个JDBC驱动程序,完成了从JDBC操作到ODBC操作之间的转换工作,允许JDBC驱动程序被用作ODBC的驱动程序。
使用JDBC-ODBC桥连接数据库的步骤如下:
(1)首先加载JDBC-ODBC桥的驱动程序。
(2)使用java.sql包中的Connection接口,并通过DriverManager类的静态方法getConnection()创建连接对象。
(3)向数据库发送SQL语句。
JDBC是一种底层的API,因此访问数据库时需要在业务逻辑层中嵌入SQL语句。SQL语句是面向关系的,依赖于关系模型,
所以通过JDBC技术访问数据库也是面向关系的。JDBC技术主要完成以下几个任务:
1.与数据库建立一个连接。
2.向数据库发送SQL语句。
3.处理从数据库返回的结果。
需要注意的是,JDBC并不能直接访问数据库,必须依赖于数据库厂商提供的JDBC驱动程序。下面详细介绍JDBC驱动程序的分类。
JDBC的总体结构由4个组件——应用程序、驱动程序管理器、驱动程序和数据源组成JDBC驱动基本上分为以下4种。
1.JDBC-ODBC桥
2.本地API一部分用Java编写的驱动程序
3.JDBC网络驱动
4.本地协议驱动
三
Connection接口代表与特定的数据库的连接。要对数据表中数据进行操作,首先要获取数据库连接。Connection实例就像在应用程序与数据库之间开通了一条渠道。
Statement接口用于创建向数据库中传递SQL语句的对象,该接口提供了一些方法可以实现对数据库的常用操作。Statement接口的常用方法如下表所示:
DriverManager类用来管理数据库中的所有驱动程序。是JDBC的管理层,作用于用户和驱动程序之间,跟踪可用的驱动程序,并在数据库的驱动程序之间建立连接。此外,DriverManager类也处理诸如驱动程序登录时间限制及登录和跟踪信息的显示等事务。DriverManager类中的方法都是静态方法,所以在程序中无须对它进行实例化,直接通过类名就可以调用。
四
要访问数据库,首先要加载数据库的驱动程序(只需要在第一次访问数据库时加载一次),然后每次访问数据时创建一个Connection对象,之后执行操作数据库的SQL语句,最后在完成数据库操作后销毁前面创建的Connection对象,释放与数据库的连接。
1.加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
// mysql 驱动类
需要导入下面的包:
mysql_connector_java_5.1.36_bin.jar
2.链接数据库
String driver="jdbc:mysql://localhost:3306/day21";
Connection conn=DriverManager.getConnection(driver,"root","123456");
//数据库url 数据库账号 数据库密码
连接其他数据库
- 连接Oracle数据库
驱动=oracle.jdbc.driver.OracleDriver
驱动包 = ojdbc6.jar
URL=jdbc:oracle:thin:@::
默认端口=1521
- 连接SQL Server 2000数据库
驱动=com.microsoft.jdbc.sqlserver.SQLServerDriver
驱动包=msbase.jar 或者 mssqlserver.jar
URL=jdbc:microsoft://:;databaseName=
默认端口=1433
- 连接SQL Server 2000数据库
连接SQL Server 2005以上数据库
驱动=com.microsoft.jdbc.sqlserver.SQLServerDriver
驱动包 = sqljdbc4.jar
URL= jdbc:sqlserver://:;databaseName=
默认端口= 1433五
连接数据库的常见错误
1.未导入驱动包
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:191)
at jdbc.Demo3.conn(Demo3.java:20)
at jdbc.Demo3.main(Demo3.java:13)
2.URL写错了
java.sql.SQLException: No suitable driver found for
at java.sql.DriverManager.getConnection(DriverManager.java:596)
at java.sql.DriverManager.getConnection(DriverManager.java:215)
at jdbc.Demo3.conn(Demo3.java:23)
at jdbc.Demo3.main(Demo3.java:13)
3.用户名密码错误
java.sql.SQLException: Access denied for user 't'@'localhost' (using password: YES)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3515)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3447)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:911)
at com.mysql.jdbc.MysqlIO.secureAuth411(MysqlIO.java:3953)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1276)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2048)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:723)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:302)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:282)
at java.sql.DriverManager.getConnection(DriverManager.java:571)
at java.sql.DriverManager.getConnection(DriverManager.java:215)
at a.driver.Demo3.conn(Demo3.java:23)
at a.driver.Demo3.main(Demo3.java:13)
数据库会返回无法登陆的数据。
4.驱动包的版本不兼容
mysql_connector_java_5.1.36_bin.jar(上面的为新版本)
mysql-connector-java-3.1.6-bin.jar
驱动包穿插使用会导致不兼容的现象产生。
六
下面这个例子中的getConnection()方法只是获取与数据库的连接,要执行SQL语句首先要获得Statement类对象。
如下例子:
import java.sql.*;
public class Renewal {
private static String url = "jdbc:mysql://localhost:3306/day21";
private static String user = "root";
private static String password = "root";
// 创建类
static Connection con; // 声明Connection对象
static PreparedStatement sql; // 声明PreparedStatement对象
static ResultSet res; // 声明ResultSet对象
public Connection getConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
public static void main(String[] args) {
Renewal c = new Renewal(); // 创建本类对象
con = c.getConnection(); // 调用连接数据库方法
try {
sql = con.prepareStatement("select * from tb_stu"); // 查询数据库
res = sql.executeQuery(); // 执行SQL语句
System.out.println("执行增加、修改、删除前数据:");
while (res.next()) {
String id = res.getString(1);
String name = res.getString("name");
String sex = res.getString("sex");
String birthday = res.getString("birthday"); // 遍历查询结果集
System.out.print("编号:" + id);
System.out.print(" 姓名:" + name);
System.out.print(" 性别:" + sex);
System.out.println(" 生日:" + birthday);
}
sql = con.prepareStatement("insert into tb_stu(name,sex,birthday) values(?,?,?)");
sql.setString(1, "张一"); // 预处理添加数据
sql.setString(2, "女");
sql.setString(3, "2012-12-1");
sql.executeUpdate();
sql = con.prepareStatement("update tb_stu set birthday "
+ "= ? where id = ? ");
sql.setString(1, "2012-12-02"); // 更新数据
sql.setInt(2, 1); // 更新数据
sql.executeUpdate();
Statement stmt = con.createStatement();
stmt.executeUpdate("delete from tb_stu where id = 1");
// 查询修改数据后的tb_stu表中数据
sql = con.prepareStatement("select * from tb_stu");
res = sql.executeQuery(); // 执行SQL语句
System.out.println("执行增加、修改、删除后的数据:");
while (res.next()) {
String id = res.getString(1);
String name = res.getString("name");
String sex = res.getString("sex");
String birthday = res.getString("birthday");
System.out.print("编号:" + id);
System.out.print(" 姓名:" + name);
System.out.print(" 性别:" + sex);
System.out.println(" 生日:" + birthday);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
通过上例创建的连接数据库对象con的createStatement()方法可获得Statement对象。有了Statement对象以后,可调用相应的方法实现对数据库的查询和修改,并将查询的结果集存放在ResultSet类的对象中。
import java.sql.*;
public class SearchEmp {
private static String url = "jdbc:mysql://localhost:3306/day21";
private static String user = "root";
private static String password = "root";
static Connection con;
static Statement sql;
static ResultSet res;
public Connection getConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
public static void main(String[] args) {
SearchEmp c = new SearchEmp();
con = c.getConnection();
try {
sql = con.createStatement();
res = sql.executeQuery("select * from tb_emp where"
+ " dapt = '销售部'");
while (res.next()) {
String id = res.getString(1);
String name = res.getString("name");
String sex = res.getString("sex");
String birthday = res.getString("birthday");
System.out.print("编号:" + id);
System.out.print(" 姓名:" + name);
System.out.print(" 性别:" + sex);
System.out.println(" 生日:" + birthday);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
ResultSet类的next()方法的返回值是boolean类型的数据,当游标移动到最后一行之后会返回false。下面的实例就是将数据表tb_emp中的全部信息显示在控制台上。
SQL语句中提供了LIKE操作符用于模糊查询,可使用“%”来代替0个或多个字符,使用下划线“_”来代替一个字符。例如,在查询姓张的同学的信息时,可使用以下SQL语句:
select * from tb_stu where name like ‘张%’
向数据库发送一个SQL语句,数据库中的SQL解释器负责把SQL语句生成底层的内部命令,然后执行该命令,完成相关的数据操作。如果不断地向数据库提交SQL语句,肯定会增加数据库中SQL解释器的负担,影响执行的速度。可以通过SQL语句对数据执行添加、修改和删除操作。可通过PreparedStatement类的指定参数动态地对数据表中原有数据进行修改操作,并通过executeUpdate()方法执行更新语句。
package com.jdbc.c_preparedstatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.jdbc.Util.JDBCUtil;
public class Demo {
public static void main(String[] args) {
//testInsert();
//testUpdate();
//testDelete();
testSelect();
}
private static void testSelect() {
Connection conn =null;
PreparedStatement stmt = null;
ResultSet rs = null;
try{
//获取连接
conn = JDBCUtil.getConn();
//定义预编译sql
String sql = "SELECT * FROM student WHERE id=?;";
//获取预编译sql对象
stmt = conn.prepareStatement(sql);
//给问好赋值
stmt.setInt(1, 3);
//发送参数并执行sql语句
//ResultSet executeQuery()throws SQLException在此
//PreparedStatement 对象中执行 SQL 查询,并返回该查询生成的 ResultSet 对象。
rs = stmt.executeQuery();
//遍历结果集
while (rs.next()) {
System.out.println(rs.getInt("id")+"--"+rs.getString("name")+"--"+rs.getInt("age"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtil.close(conn, stmt, rs);
}
}
private static void testDelete() {
Connection conn =null;
PreparedStatement stmt = null;
try{
conn = JDBCUtil.getConn();
//写一个参数化的sql
String sql = "DELETE FROM student WHERE id=?;";
//获取预编译的sql对象
stmt = conn.prepareStatement(sql);
//给?设置参数
stmt.setInt(1, 2);
//发送参数并执行sql
int count = stmt.executeUpdate();
System.out.println(count);
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtil.close(conn, stmt, null);
}
}
private static void testUpdate() {
Connection conn =null;
PreparedStatement stmt = null;
try{
conn = JDBCUtil.getConn();
String sql = "UPDATE student SET NAME=? WHERE id=?;";
//执行预编译sql
stmt = conn.prepareStatement(sql);
//给?赋值
stmt.setString(1, "张学友");
stmt.setInt(2, 5);
//发送参数到数据库服务器,并执行sql,将执行结果返回
int count = stmt.executeUpdate();
System.out.println(count);
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtil.close(conn, stmt, null);
}
}
private static void testInsert() {
//定义连接对象和预编译sql对象
Connection conn = null;
PreparedStatement stmt = null;
try{
//获取连接
conn = JDBCUtil.getConn();
//PreparedStatement prepareStatement(String sql)
//throws SQLException创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。
String sql = "INSERT INTO student VALUES(?,?,?);";//参数化的sql,动态sql
stmt = conn.prepareStatement(sql);
//需要一个预编译的sequel语句,将sq发送到数据库端,检查sql语法及用户权限等信息
//给之前参数化的sql语句设置参数
//两个参数:1:是给第几个?设置数据 2:给?设置的数据
stmt.setInt(1, 5);
stmt.setString(2, "黎明");
stmt.setInt(3, 60);
//int executeUpdate()throws SQLException
int count = stmt.executeUpdate();
System.out.println(count);
}catch(Exception e){
e.printStackTrace();
}finally{
//释放资源
JDBCUtil.close(conn, stmt, null);
}
}
}