Java DataBase Connectivity
1.JDBC原理
什么是JDBC?
JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库。原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句。JDBC是sun公司(已被Oracle收购)制定一系列接口标准,由不同厂商(Oracle、MySQL等)实现接口方法并封装成驱动文件,供开发人员操作数据库。也就是说,开发人员可采用统一的代码来操作不同的数据库,而无需关注驱动文件的内部实现
2.JDBC使用步骤及原理
(1)导包并加载不同厂商为我们提供的驱动类
Class.forName(“com.mysql.jdbc.Driver”);//加载mysql驱动类
Class.forName(“oracle.jdbc.driver.OracleDriver”);//加载Oracle驱动类
抛出异常:ClassNotFoundException
类加载的条件:
-
new Constructor();构造器构建对象的时候会对该类以及该类父类进行类加载
-
调用某类中的静态成员时,会对该类进行加载,静态成员会被赋值,静态代码块会被执行
-
Class.forName(“java.lang.xxx”);反射时会对该类进行加载
类加载的过程
.java文件由编译会生成.class字节码文件,class文件中存放的就是类信息,而将类信息加载进JVM的方法区内,然后在堆区创建一个java.lang.Class对象,类的加载的最终产品是位于堆区中的Class对象
(2) 获得数据库连接
Connection mysqlconn = DriverManager.getConnection("jdbc:mysql://192.168.6.66:3306/database1",
"root", "123456");//Mysql数据库连接获取
Connection orclconn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.6.66:1521:orcl",
"root", "123456");//Oracle数据库连接获取
getConnection("","","")三个参数分别是数据库url、用户名和密码
(3) 生成Statement对象,用于命令数据库执行sql语句
Statment stat = conn.creatStatement();
(4) 控制数据库开始执行sql语句 (抛出SQLException异常)
-
stat.excute(“sql”)
返回boolean true——执行的是DQL(有结果集产生) false——执行的为无结果集的DML或DDL
若是有结果集产生的话可以随后用stat.getResultSet()方法获得结果集 -
stat.excuteUpdate(“sql”)
返回int表示通过DML语句(不能执行DQL)更新的数据条数 -
stat.excuteQuery()
返回ResultSet表示查询得到的结果集。
(5) 对结果集进行操作
ResultSet rs = stat.excuteQuery();/stat.getResultSet();
-
next();
返回的是boolean,表示是否还有下一条数据(rs一开始指向的是表头,rs.next()表示是否表内有数据) -
getInt(String colName\int colno)/getString(String colName\int colno)/getObject(String colName\int colno)/…
获取此时rs指代数据行的某列字段内容
-
a.Connection
代表着Java程序与数据库建立的连接。
-
b.Statement
代表SQL发送器,用于发送和执行SQL语句。
-
c.ResultSet
代表封装的数据库返回的结果集,用于获取查询结果。
JDBC连接数据库实现登录验证
import java.sql.*;
import java.util.Scanner;
public class jdbcdemo {
public static void main (String[] args) {
ResultSet rs = null;
Connection conn = null;
Statement sttm = null;
Scanner sc = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/employees",
"root", "123456");
sttm = conn.createStatement();
sc = new Scanner(System.in);
System.out.println("请输入登录账号:");
String usrname = sc.nextLine();
System.out.println("请输入对应密码:");
String usrpsw = sc.nextLine();
String sql = "select * from Resigt where UserName='"+usrname+"'";
rs = sttm.executeQuery(sql);
if(!rs.next()) {
System.out.println("登录失败,正在自动注册......");//对于没有的账号直接注册
sql = "insert into Resigt (UserName,Password) values ('"+usrname+"','"+usrpsw+"')";
sttm.executeUpdate(sql);
System.out.println("注册成功");
return;
}
if(rs.getString("PassWord").equals(usrpsw))
System.out.println("登录成功,欢迎您,"+usrname);
else
System.out.println("密码错误");
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (SQLException e1) {
e1.printStackTrace();
} finally {
if(sc != null)
sc.close();
if(rs!= null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(sttm!= null) {
try {
sttm.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!= null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
PreparedStatement和Statement
public class jdbcdemo3 {
public static void main (String[] args) {
ResultSet rs = null;
Connection conn = null;
PreparedStatement presttm = null;
Scanner sc = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/employees",
"root", "123456");
/*?作为占位符可以在PreparedStatement中进行二次设置*/
String sql = "select * from Resigt where UserName=? and Password=?";
presttm = conn.prepareStatement(sql);
sc = new Scanner(System.in);
System.out.println("请输入登录账号:");
String usrname = sc.nextLine();
System.out.println("请输入对应密码:");
String usrpsw = sc.nextLine();
presttm.setString(1,usrname);
presttm.setString(2,usrpsw);
rs = presttm.executeQuery();
if(rs.next())
System.out.println("登录成功,欢迎您,"+usrname);
else
System.out.println("密码错误");
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (SQLException e1) {
e1.printStackTrace();
} finally {
if(sc !=null)
sc.close();
if(rs!= null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(presttm!= null) {
try {
presttm.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!= null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
请输入登录账号:
HsuDone
请输入对应密码:
123456
登录成功,欢迎您,HsuDone
PrepareStatement使用步骤
- 编写带占位符(?)的sql
- 利用conn.prepareStatement(sql);方法获取PrepareStatement对象
- 利用setXXX()方法给sql的?设置参数值
- 调用无参的executeUpdate()或executeQuery()执行sql.
PreparedStatement和Statement之间的联系与区别
-
PrepareStatement是Statement的子类
-
都是用于发送和执行SQL语句的
-
PrepareStatement是一种预编译的Statement对象。
-
Statement对象是在executeUpdate或executeQuery方法时指定sql,此时将sql语句发送和执行。
-
PrepareStatement对象是在创建时指定并发送sql,在executeUpdate或executeQuery方法时触发sql执行。
PrepareStatement是一个预编译的Statement,将带占位符 ?的SQL语句发送给数据库后,SQL语句不会立即执行,数据库会生成一个执行计划,此时SQL语句结构已确定,不可更改注入,然后利用setXXX()方法给sql的?设置参数值,传参后即执行计划,返回结果集。另外,由于执行计划已生成,只要传入参数就可执行计划,这在大批量存入数据时,编码更简单,效率更高。