一、什么是jdbc ?
Java database connectivity: Java连接数据库技术
1.Sun公司研发java语言的程序员,他们定义出来的java连接数据库的一些接口。这些接口就是jdbc。
2.接口没有具体的功能,但是他统一了java连接各个数据库的标准。具体的实现类有各个数据库厂商去实现。
3.数据库厂商写好这些实现类后,把这些类打成压缩包,放到官网上,供java程序员下载使用。这些压缩包被称为jdbc驱动。
4.Java程序员想连接某个数据库,需要从该数据库官网上把jdbc驱动下载下来引入到自己的项目中,然后通过jdbc的接口提供的方法就可以连接到该数据库上了。
二、Jdbc的api(application program interface)
之前使用plsqldev或者navicat工具连接到数据库的过程:
1.输入账号,密码,数据库,连接到数据库服务器上。
2.连接到数据库上后,我们需要打开一个sql窗口,在sql窗口里面去写sql语句。
3.点击执行按钮
4.如果是dql语句,会得到一个查询结果,如果是dml,没有结果执行结束。
5.关闭窗口,整个过程结束。
使用java连接数据库需要的类或接口:
Connection:封装了数据库的连接,该对象一旦被创建,java代码就连接到了oracle数据库上。
PreparedStatement:执行器对象,当你要执行sql脚本时,你需要把sql脚本放入到该对象里面。
ResultSet:结果集对象,该对象封装的是dql的查询结果。
上面这些接口都在java.sql这个包里面。
Driver:jdbc驱动。各个数据库厂商实现的jdbc实现类。这些驱动是以压缩包的形式存在的。格式jar。这些jar包需要到各个数据库官网上下载。
DriverManager:各个数据库驱动的管理者。他是来管理众多的数据库驱动的。
三、使用jdbc连接Oracle数据库实例
让java连接到数据库上,创建出Connection conn对象。
前提准备:
1.下载jdbc驱动。
C:\oraclexe\app\oracle\product\10.2.0\server\jdbc\lib\ojdbc14.jar
2.把jar包放入到我们的项目中。在项目上面右键—》新建—》folder—》lib
3.让项目识别jar包。在jar上面右键—》bulid path—>add jar to bulid path
数据库连接步骤为:
1.加载驱动。
2.建立连接
3.写sql语句。
4.创建ps对象。
5.执行
6.释放资源。
例如:
package testconn; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * @author 超伟 * @2019年5月26日 上午10:13:08 * @博客:https://blog.csdn.net/MacWx */ public class conn { /** * @param args * @throws ClassNotFoundException * @throws SQLException */ public static void main(String[] args) throws ClassNotFoundException, SQLException { // TODO Auto-generated method stub //1,加载数据库连接驱动 Class.forName("oracle.jdbc.OracleDriver"); //2,创建连接 /*getConnection需要三个参数: * 第一个参数是数据库信息, * jdbc:oracle:thin指的是两台电脑之间连接的协议 * @localhost:1521:指的是 要找哪台计算机上的数据库,并且指明端口号,localhost指的是自己的本机电脑 * 第二个参数是连接数据库的账号 * 第三个参数是连接数据库的密码 */ Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr"); System.out.println(conn); //创建出prepareStatement对象,向数据库中插入一条数据 String sql = "insert into t_student(student_id,student_name,age,sex) values (seq_student.nextval,'macw',18,'男') "; PreparedStatement ps = conn.prepareStatement(sql); //执行ps里面 的sql脚本,如果是增删改dml语言,则调用ps 的executeUpdate方法; ps.executeUpdate(); //关闭ps资源,后创建的对象先关闭 ps.close(); //3,关闭数据库连接 conn.close(); } }
1.rs对象是对结果集的封装。
2.Rs调用一次next方法,光标就往下移动一行。
3.Next方法是有返回值的。返回值表示移动后,指向的行是否有数据。
4.从rs里面获取数据需要用到rs.getXxx(“字段名”)。其中xxx表示数据类型,参数表示字段名。
5.注意不要在while循环里面试图调用两次next方法。这样展示的数据就会有漏掉的。
这是一个对于数据库的DML (Data Manipulation Language) 数据操纵语言,插入一条数据,是没有返回值的,其他增删改也是一样没有返回值,但是查询就不一样了,查询有返回值,
查询操作的示例代码如下:
package testconn; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * @author 超伟 * @2019年5月26日 下午3:15:53 * @博客:https://blog.csdn.net/MacWx */ public class connQuery { /** * @param args * @throws ClassNotFoundException * @throws SQLException */ public static void main(String[] args) { // TODO Auto-generated method stub Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { // 1,加载数据库连接驱动 Class.forName("oracle.jdbc.OracleDriver"); // 2,创建连接 /* getConnection需要三个参数: 第一个参数是数据库信息, jdbc:oracle:thin指的是两台电脑之间连接的协议 * @localhost:1521:指的是 要找哪台计算机上的数据库,并且指明端口号,localhost指的是自己的本机电脑 * 第二个参数是连接数据库的账号 第三个参数是连接数据库的密码 */ conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr"); // 创建出prepareStatement对象,并查询student表中所有数据 String sqlQuery = "select * from t_student"; // 执行ps里面 的sql脚本,如果是查询语言dql,则调用ps 的executeQuery方法; ps = conn.prepareStatement(sqlQuery); rs = ps.executeQuery(sqlQuery); // 从rs中获取数据 // 让rs结果集光标从第一行的上一行指向第一行数据, 返回值表示如果第二行有数据, rs.next();就是true。否则为false // 所以,循环遍历t_student表中所有数据,让rs光标往下移,如果有数据就继续打印,没有就不进入循环 while (rs.next()) { // 获取id int id = rs.getInt("student_id"); // 获取name String name = rs.getString("student_name"); System.out.println(id + "\t" + name); } } catch (Exception e) { e.printStackTrace(); } finally { // 关闭ps资源,后创建的对象先关闭 //这里建议每一个关闭操作都单独抛出一个异常,保证每一个都可以正常关闭 try { if (rs != null) {rs.close();} } catch (SQLException e) { e.printStackTrace(); } try { if (rs != null) { ps.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (rs != null) {conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } } }
四、prepareStatement的占位符:
为什么要使用占位符?
1.字符串拼接后,代码的可读性差。
2.字符串拼接后,代码容易出现sql注入。安全性出现问题。
例如:假如说要实现一个简单的登录操作,如果用户密码都正确则输出登录成功,否则登录失败!
数据库设计如下:
--创建用户表 CREATE TABLE t_USer( user_id NUMBER(5) primary key, username VARCHAR2(30), password VARCHAR2(30) ); --建立索引 create sequence seq_uid; --插入数据 INSERT INTO t_user VALUES (seq_uid.nextval,'aaa','111'); INSERT INTO t_user VALUES (seq_uid.nextval,'bbb','222'); INSERT INTO t_user VALUES (seq_uid.nextval,'ccc','333'); SELECT * FROM t_user;
java 实现登录操作如下:
package testconn; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Scanner; /** * @author 超伟 * @2019年5月26日 下午4:26:25 * @博客:https://blog.csdn.net/MacWx */ public class testLogin { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入账号:"); String name = sc.nextLine(); System.out.println("请输入密码:"); String pwd = sc.nextLine(); Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { // 1,加载数据库连接驱动 Class.forName("oracle.jdbc.OracleDriver"); // 2,创建连接 conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr"); // 创建出prepareStatement对象 String sqlQuery = "select * from t_user where username = ? and password = ?"; // 执行ps里面 的sql脚本,如果是查询语言dql,则调用ps 的executeQuery方法; ps = conn.prepareStatement(sqlQuery); ps.setString(1, name); ps.setString(2, pwd); rs = ps.executeQuery(); // 从rs中获取数据 if (rs.next()) { // 获取id int id = rs.getInt("user_id"); // 获取name String usa = rs.getString("username"); String pwds = rs.getString("password"); System.out.println(id + "\t" + usa + "\t" + pwds); System.out.println("登录成功"); }else { System.out.println("登录失败!"); } } catch (Exception e) { e.printStackTrace(); } finally { // 关闭ps资源,后创建的对象先关闭 try { if (rs != null) {rs.close();} } catch (SQLException e) { e.printStackTrace(); } try { if (rs != null) {ps.close();} } catch (SQLException e) { e.printStackTrace(); } try { if (rs != null) {conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } } }
注意事项:
1.占位符可以用到dql,dml
2.占位符只可以表示一个具体的值,不能表示sql中的关键字。
3.给占位符赋值一定要写在执行之前。