JDBC
Java Database Connectivity java和数据库的连接技术,sun公司推出的一套java应用程序访问数据库的技术规范。
规范:——>抽象类或者接口。
主要就是:
- java.sql包下的一组接口或抽象类。
- javax.sql包下的一组接口。
JDBC的好处:
- 不用去记住多套API,减轻开发压力。
- 提高代码的维护性。
JDBC相关API
DriverManager驱动管理类:
registDriver(Driver对象) :注册驱动,不建议使用。
getConnection(url,user,password) :获取连接。
Connection连接对象窗口:
createStatement :生成命令对象。
prepareStatement(sql) :生成预编译命令对象。
Statement命令对象接口:
executeUpdate(sql) :执行增删改语句,返回受影响的行数。
executeQuery(sql) : 执行查询语句,返回结果集。
execute(sql) : 执行任意sql语句,返回boolean,不建议使用。
PreparedStatement预编译命令对象接口:
executeUpdate(): 执行增删改语句,返回受影响的行数。
executeQuery() : 执行查询语句,返回结果集。
execute : 执行任意sql语句,返回boolean。
setXX(占位符索引,占位符的值) : 设置对应索引的占位符的值,类型为XX类型。
setObject(占位符索引,占位符的值) :设置对应索引的占位符的值,类型为Object类型。
占位符索引从1开始。sql语句中除了limit索引从0开始,其他基本从1开始。
ResultSet结果集对象接口:
next() : 下移一行,返回当前行是否有值。
pervious() : 上移一行,返回当前行是否有值。 基本不用。
getXX(列索引 |“列名”(“别名”) : 返回对应列的值,接收类型为XX。
getObject(列索引 |“列名”(“别名”) : 返回对应列的值,接收类型为Object。
一旦起别名,就不能用列名!
演示JDBC
步骤:
先准备mysql的驱动包,加载到项目中 marven java connector
idea中 , shift+ctrl+alt+S libraries添加驱动jar包
- 加载驱动
- 获取连接
- 执行增删改查操作
- 关闭连接
import java.sql.*;
import com.mysql.jdbc.Driver;
/*
步骤:
先准备mysql的驱动包,加载到项目中 marven java connector
idea中 shift+ctrl+alt+S libraries添加驱动jar包
1.加载驱动
2.获取连接
3.执行增删改查操作
4.关闭连接
*/
public class TestConnection {
public static void main(String[] args) throws SQLException {
//1.加载驱动
DriverManager.registerDriver(new Driver());
//2.获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/girls","root","123456");
System.out.println("连接成功");
//3.执行增删改查
//3.1 编写sql语句
// String sql = "delete from beauty where name='双儿'";
// String sql = "insert into beauty values(null,'张三','女','1976-1-1',123,null,5)";
String sql = "update beauty set name = '李四' where name = '张三'";
//3.2 获取执行sql语句的命令对象
Statement statement = connection.createStatement();
//3.3 使用命令对象 执行sql语句
int update = statement.executeUpdate(sql);
//3.4 处理执行结果
System.out.println(update);
//4. 关闭连接 释放资源
statement.close();
connection.close();
}
}
一、加载驱动
import com.mysql.jdbc.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
/*
JDBC使用步骤 一、加载驱动
*类的加载时机:
* 1.new 对象时
* 2.加载子类时
* 3.调用类中的静态成员
* 4.通过反射
*
* 使用 new 对象的方式加载类的不足之处:
* 1.属于编译器加载,如果编译期间该类不存在,直接报编译错误,即依赖性太强。
* 2.导致Driver对象创建了两遍,效率太低。
*
*使用 反射 的方式加载类优点:
*1.属于运行期加载,降低了依赖性。
*2.Driver对象只创建一次,效率较高。
*/
public class TestJDBC1 {
public static void main(String[] args) throws SQLException,ClassNotFoundException{
//老方法,不推荐使用
// DriverManager.deregisterDriver(new Driver());
//反射方式
Class.forName("com.mysql.jdbc.Driver");
}
}
二、创建连接
配置文件 properties
eclipse里面可以直接创建src目录下的properties文件;
但是idea里稍有不同,需要使用file–>Resource bundle来创建。
//配置文件 properties的使用
Properties info = new Properties();
info.load(new FileInputStream("src\\jdbc.properties.properties"));
// info.list(System.out); 查看配置文件
String user = info.getProperty("user");
String password = info.getProperty("password");
String url = info.getProperty("url");
String driver = info.getProperty("driver");
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
/*
*JDBC使用步骤 二、获取连接
*
*
*
*
*/
public class TestJDBC2 {
public static void main(String[] args) throws Exception{
//配置文件 properties的使用
Properties info = new Properties();
info.load(new FileInputStream("src\\jdbc.properties.properties"));
// info.list(System.out); 查看配置文件
String user = info.getProperty("user");
String password = info.getProperty("password");
String url = info.getProperty("url");
String driver = info.getProperty("driver");
//1.注册驱动
// Class.forName("com.mysql.jdbc.Driver");
Class.forName(driver);
//2.获取连接
// DriverManager.getConnection("jdbc:mysql://localhost:3306/girls?user=root&password=123456");
DriverManager.getConnection(url,user,password);
System.out.println("连接成功");
}
}
三、执行增删改查
-
executeUpdate 可以执行增删改语句
-
executeQuery 执行查询语句
-
execute 可以执行任何sql语句,但不常用到。
int update = statement.executeUpdate(sql); 执行增删改语句, 返回值是受影响的行数 ResultSet set = statement.executeQuery(sql);//执行查询语句,返回的是一个结果集 boolean flag = set.next(); System.out.println(flag);
next()方法:返回布尔值
就是在executeQuery方法的返回的结果集里面,光标每次只能下移一行,并返回当前行是否有值,的方法。
可以用while循环搭配next()方法,在有值的时候用getXX方法得到结果集里的值。
getXX()方法:得到具体的值
-
通用的是getObject(列数索引或者"列名") 方法。
-
方式一:get数据类型(列数索引) 方法,可以得到具体位置的值
-
方式二:get数据类型(“列名”) 方法,得到具体列名的值。
指针指向的列数索引,只针对executeQuery方法返回的结果集,不针对原始表。 结果集里面是第几列,列数索引就是几。
package com.miyon.jdbc;
import java.io.FileInputStream;
import java.sql.*;
import java.util.Properties;
/*
*JDBC使用步骤 三、增删改查
*
*
*
*
*/
public class TestJDBC3 {
public static void main(String[] args) throws Exception {
//配置文件 properties的使用
Properties info = new Properties();
info.load(new FileInputStream("src\\jdbc.properties.properties"));
// info.list(System.out); 查看配置文件
String user = info.getProperty("user");
String password = info.getProperty("password");
String url = info.getProperty("url");
String driver = info.getProperty("driver");
//1.注册驱动
// Class.forName("com.mysql.jdbc.Driver");
Class.forName(driver);
//2.获取连接
// DriverManager.getConnection("jdbc:mysql://localhost:3306/girls?user=root&password=123456");
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println("连接成功");
//3.执行增删改查
String sql = "select id,name,sex,borndate from beauty";
//获取执行sql的命令对象
Statement statement = connection.createStatement();
//执行sql语句
// boolean execute = statement.execute(sql); 可以执行所有sql语句。 不常用到,了解。
// int update = statement.executeUpdate(sql); 执行增删改语句, 返回值是受影响的行数
ResultSet set = statement.executeQuery(sql);//执行查询语句,返回的是一个结果集
//每调用一次next()方法,就在executeQuery方法返回的结果集里面下移一行。
// boolean flag1 = set.next();
// boolean flag2 = set.next();
// boolean flag3 = set.next();
// boolean flag4 = set.next();
// System.out.println(flag4);
//可以用while循环 打印全部结果集
while (set.next()) {
//通用的是getObject(列数索引或者"列名") 方法
//方式一:get数据类型(列数索引) 方法,可以得到具体位置的值
//方式二:get数据类型("列名") 方法,得到具体列名的值
//指针指向的列数索引,只针对executeQuery方法返回的结果集,不针对原始表。 结果集里面是第几列,列数索引就是几。
int id = set.getInt(1); //int id = set.getInt("id");
String name = set.getString(2); //String name = set.getString("name");
String sex = set.getString(3); //String sex = set.getString("sex");
Date date = set.getDate(4); //Date date = set.getDate("borndate");
System.out.println(id + "\t" + name + "\t" + sex + "\t" + date);//
}
//4.关闭连接
set.close();
statement.close();
connection.close();
}
};
四、关闭连接
按照定义的倒序关闭连接。
Connection connection = DriverManager.getConnection(url, user, password);
Statement statement = connection.createStatement();
ResultSet set = statement.executeQuery(sql);
set.close();
statement.close();
connection.close();
Statement 和 PreparedStatement的区别
关系:
Statement 和 PreparedStatement都属于执行sql命令语句的接口,都提供了一系列执行sql语句的方法。
PreparedStatement继承了Statement。
使用PreparedStatement预编译的好处
-
不再使用 “+” 号去拼接sql语句,减少语法错误,语义性强;
-
将模板sql语句(固定的sql语句部分)与参数部分进行了分离,提高维护性;
-
有效解决了sql注入问题;(使用Statement时的sql注入问题)
-
大大减少了编译次数,效率较高。
举例:10条sql语句,只是参数不同的情况下:
使用Statement,需要编译10次,执行10次;
使用PreparedStatement,需要编译1次,执行10次。
package com.miyon.jdbc;
import org.junit.Test;
import java.io.FileInputStream;
import java.sql.*;
import java.util.Properties;
import java.util.Scanner;
/**
*演示PreparedStatement和Statement的区别
*
*
*案例:登录验证
*
*
*/
public class TestPrepareStatement {
//使用Statement实现登录
@Test
public void testStatement() throws Exception{
Scanner input = new Scanner(System.in);
System.out.println("Please input username:");
String username = input.next();
System.out.println("Please input password:");
String psw = input.next();
input.close();
/*--------------------------------连接数据库的步骤-------------------------------------------*/
//配置文件
Properties info = new Properties();
info.load(new FileInputStream("src\\jdbc.properties.properties"));
String user = info.getProperty("user");
String password = info.getProperty("password");
String url = info.getProperty("url");
String driver = info.getProperty("driver");
//1.注册驱动
Class.forName(driver);
//2.获取连接
Connection connection = DriverManager.getConnection(url, user, password);
//3.执行sql语句
String sql = "SELECT COUNT(*) FROM admin WHERE username='"+username+"' AND password='"+psw+"'";
Statement statement = connection.createStatement();
ResultSet set = statement.executeQuery(sql);
if(set.next()){
int count = set.getInt(1);
System.out.println(count>0?"Login Success!":"Login Fail!");
}
//4.关闭连接
set.close();
statement.close();
connection.close();
}
//使用PreparedStatement实现登录
@Test
public void testPreparedStatement() throws Exception {
Scanner input = new Scanner(System.in);
System.out.println("Please input username:");
String username = input.next();
System.out.println("Please input password:");
String psw = input.next();
input.close();
/*--------------------------------连接数据库的步骤--------------------------------*/
//配置文件
Properties info = new Properties();
info.load(new FileInputStream("src\\jdbc.properties.properties"));
String user = info.getProperty("user");
String password = info.getProperty("password");
String url = info.getProperty("url");
String driver = info.getProperty("driver");
//1.注册驱动
Class.forName(driver);
//2.获取连接
Connection connection = DriverManager.getConnection(url, user, password);
//3.执行查询
//3-1 编写sql
String sql = "SELECT COUNT(*) FROM admin WHERE username=? AND password=?"; //? 占位符
//3-1 获取PreparedStatement命令对象
PreparedStatement statement = connection.prepareStatement(sql);
//3-2 设置占位符的值
statement.setString(1,username);
statement.setString(2,psw);
// statement.setObject(1,username); //不清楚类型就用setObject
//3-3 执行sql命令
// int update = statement.executeUpdate();//执行增删改,返回受影响的行数
ResultSet set = statement.executeQuery();//执行查询,返回结果集
if(set.next()){
int count = set.getInt(1);
System.out.println(count>0?"Login Success!":"Login Fail!");
}
//4 关闭连接
set.close();
statement.close();
connection.close();
}
}