目录
JDBC概述
概述
- JDBC(Java Data Base Connectivity,java数据库连接)是SUN公司开发的,一种用于执行SQL语句的Java API
- JDBC是Java访问数据库的标准规范,可以为不同的关系型数据库提供统一访问,它由一组用Java语言编写的接口和类组成
- JDBC需要连接驱动,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信
- mysql的驱动mysql-connector-java-5.1.37-bin.jar
原理
- JDBC是接口,驱动是接口的实现,没有驱动将无法完成数据库连接,从而不能操作数据库
- 驱动一般都由数据库生成厂商提供
JDBC入门案例
- 准备数据
CREATE TABLE `sort` (
`sid` int(11) NOT NULL AUTO_INCREMENT,
`sname` varchar(100) DEFAULT NULL,
`sprice` double DEFAULT NULL,
`sdesc` varchar(5000) DEFAULT NULL,
PRIMARY KEY (`sid`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
INSERT INTO `sort` VALUES ('1', '家电', '2000', '优惠的促销');
INSERT INTO `sort` VALUES ('2', '家具', '8900', '家具价格上调,原材料涨价');
INSERT INTO `sort` VALUES ('3', '儿童玩具', '300', '赚家长钱');
INSERT INTO `sort` VALUES ('4', '生鲜', '500.99', '生鲜商品');
INSERT INTO `sort` VALUES ('5', '服装', '24000', '换季销售');
INSERT INTO `sort` VALUES ('6', '洗涤', '50', '洗发水促销');
INSERT INTO `sort` VALUES ('7', '汽车用品', '50000', '疯狂涨价');
- 导入驱动jar包
- JDBC核心类
- java.sql.DriverManager:管理JDBC程序的
- java.sql.Connection:java程序与数据库之间建立的连接,相当于一个管道
- java.sql.Statement:用于执行SQL语句,并返回结果
- java.sql.ResultSet:存储数据库查询的结果
- 开发步骤
- 注册驱动.
- 获得连接.
- 获得语句执行平台
- 执行sql语句
- 处理结果
- 释放资源.
- 案例实现
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/*
* JDBC操作数据库的步骤:
* 1.注册驱动
* 告知JVM使用的是哪一个数据库的驱动
* 2.获得连接
* 使用JDBC中的类,完成对mysql数据库的连接(TCP协议)
* 3.获得语句执行平台
* 通过连接对象获取对SQL语句的执行者对象
* 4.执行sql语句
* 使用执行者对象,向数据库执行SQL语句
* 获取数据库的执行后的结果
* 5.处理结果
* 6.释放资源
* 调用一堆close
*/
public class JDBCTest {
public static void main(String[] args) throws Exception {
// 1. 注册驱动
// 使用java.sql.DriverManager类的静态方法registerDriver(Driver driver)
// Driver是一个接口,参数传递:MySQL驱动程序的实现类
// DriverManager.registerDriver(new Driver());
// 查看驱动类源码,注册两次驱动,浪费资源
Class.forName("com.mysql.jdbc.Driver");
// 2. 获得连接
// uri:数据库地址 jdbc:mysql://连接主机ip:端口号//数据库名字
String url = "jdbc:mysql://localhost:3306/itheima";
// static Connection getConnection(String url, String user, String password)
// 返回值是java.sql.Connection接口的实现类,在MySQL驱动程序中
Connection conn = DriverManager.getConnection(url, "root", "root");
System.out.println(conn);// com.mysql.jdbc.JDBC4Connection@10d1f30
// 3. 获得语句执行平台,通过数据库连接对象,获取到SQL语句的执行者对象
//conn对象,调用方法 Statement createStatement() 获取Statement对象,将SQL语句发送到数据库
//返回的是Statement接口的实现类对象,在MySQL驱动程序中
Statement stat = conn.createStatement();
System.out.println(stat);//com.mysql.jdbc.StatementImpl@137bc9
// 4. 执行sql语句
//通过执行者对象调用方法执行SQL语句,获取结果
//int executeUpdate(String sql) 执行数据库中的SQL语句,仅限于insert,update,delete
//返回值int,操作成功数据库的行数
int row = stat.executeUpdate("INSERT INTO sort(sname,sprice,sdesc) VALUES('汽车用品',50000,'疯狂涨价')");
System.out.println(row);
// 5. 释放资源
stat.close();
conn.close();
}
}
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCDemo {
public static void main(String[] args) throws Exception {
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接对象
String url = "jdbc:mysql://localhost:3306/itheima";
Connection conn = DriverManager.getConnection(url, "root", "root");
// 3.获取执行SQL语句
Statement stat = conn.createStatement();
// 拼写SQL语句
String sql = "select * from sort";
// 4.调用执行者对象方法,执行SQL语句获取结果集
// 返回的是ResultSet接口的实现类对象,实现类在mysql驱动中
ResultSet rs = stat.executeQuery(sql);
// System.out.println(rs);//com.mysql.jdbc.JDBC4ResultSet@18cef0a
// 5.处理结果集
// ResultSet接口的方法 boolean next() 有结果集true,没有结果集返回false
while (rs.next()) {
// 获取每列的数据,使用的是ResultSet接口的方法getXXX
int sid = rs.getInt("sid");// 相当于rs.getInt(1);这个方法有弊端
String sname = rs.getString("sname");
double sprice = rs.getDouble("sprice");
String sdesc = rs.getString("sdesc");
System.out.println(sid+"\t"+sname+"\t"+sprice+"\t"+sdesc);
}
// 6.关闭资源
rs.close();
stat.close();
conn.close();
}
}
API详解
java.sql.DriverManager类
public static Connection getConnection(String url, String user, String password)//建立到给定数据库URL 的连接
public static void registerDriver(Driver driver);//注册驱动
java.sql.Connection接口
PreparedStatement prepareStatement(String sql);//创建一个PreparedStatement 对象,高效执行SQL语句
java.sql.PreparedStatement接口
ResultSet executeQuery()//执行查询语句,返回结果集
int executeUpdate();//执行更新语句,返回成功修改的行数
void setObject(int parameterIndex, Object x)//给占位符设置参数
java.sql.ResultSet接口
boolean next();//从当前位置向后移一行
抽取工具类
jdbc.properties配置文件
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/itheima
user=root
password=root
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* 使用JDBC工具类,获取数据库的连接 采用读取配置文件的方式 读取配置文件,获取连接,执行一次,static{}
*/
public class JDBCUtilsConfig {
private static Connection con;
private static String driverClass;
private static String url;
private static String user;
private static String password;
static {
try {
readConfig();
Class.forName(driverClass);
} catch (Exception e) {
throw new RuntimeException("数据库连接失败");
}
}
/**
* @Title: readConfig
* @Description:读取配置文件
* @throws IOException
*/
private static void readConfig() throws IOException {
InputStream is = JDBCUtilsConfig.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties pro = new Properties();
pro.load(is);
driverClass = pro.getProperty("driverClass");
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
}
public static Connection getConnection() {
try {
con = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
public static void close(Connection con, Statement stat) {
if (stat != null) {
try {
stat.close();
} catch (SQLException ex) {
}
}
if (con != null) {
try {
con.close();
} catch (SQLException ex) {
}
}
}
public static void close(Connection con, Statement stat, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException ex) {
}
}
if (stat != null) {
try {
stat.close();
} catch (SQLException ex) {
}
}
if (con != null) {
try {
con.close();
} catch (SQLException ex) {
}
}
}
}
测试工具类
import java.sql.Connection;
import com.itheima.utils.JDBCUtilsConfig;
public class TestJDBCUtils {
public static void main(String[] args) {
Connection con = JDBCUtilsConfig.getConnection();
System.out.println(con);
}
}
预处理对象
SQL注入攻击
create table users(
id int primary key auto_increment,
username varchar(100),
password varchar(100)
);
insert into users (username,password) values ('a','1'),('b','2');
select * from users;
-- SQL注入攻击(无论用户名和密码是什么,结果都是查询所有数据)
select * from users where username ='wess' and password ='*nkj' or 1=1
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
/*
* java程序实现用户登录,用户名和密码,数据库检查
* 演示被别人注入攻击
*/
public class JDBCDemo02 {
public static void main(String[] args) throws Exception {
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接对象
String url = "jdbc:mysql://localhost:3306/itheima";
Connection conn = DriverManager.getConnection(url, "root", "root");
// 3.获取执行SQL语句
Statement stat = conn.createStatement();
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String user = sc.nextLine();
System.out.println("请输入密码:");
String pass = sc.nextLine();
// 拼写SQL语句
String sql = "select * from users where username ='"+user+"' and password ='"+pass+"'";
System.out.println(sql);
// 4.调用执行者对象方法,执行SQL语句获取结果集
ResultSet rs = stat.executeQuery(sql);
// 5.处理结果集
while (rs.next()) {
System.out.println(rs.getString("username") + "\t" + rs.getString("password"));
}
// 6.关闭资源
rs.close();
stat.close();
conn.close();
}
}
防止SQL注入攻击
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
/*
* Java程序实现用户登录,用户名和密码,数据库检查
* 防止注入攻击
* Statement接口实现类,作用执行SQL语句,返回结果集
* 有一个子接口PreparedStatement (SQL预编译存储,多次高效的执行SQL)
* PreparedStatement的实现类数据库的驱动中,如何获取接口的实现类
* Connection数据库连接对象的方法
* PreparedStatement prepareStatement(String sql)
*/
public class JDBCDemo03 {
public static void main(String[] args) throws Exception {
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接对象
String url = "jdbc:mysql://localhost:3306/itheima";
Connection conn = DriverManager.getConnection(url, "root", "root");
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String user = sc.nextLine();
System.out.println("请输入密码:");
String pass = sc.nextLine();
// 拼写SQL语句
String sql = "select * from users where username = ? and password = ? ";
// 3.获取执行SQL语句
//Connection接口
PreparedStatement pst = conn.prepareStatement(sql);
//调用pst对象的setXXX方法设置问号占位符的参数
pst.setObject(1, user);
pst.setObject(2, pass);
System.out.println(sql);
// 4.调用执行者对象方法,执行SQL语句获取结果集
ResultSet rs = pst.executeQuery();
// 5.处理结果集
while (rs.next()) {
System.out.println(rs.getString("username") + "\t" + rs.getString("password"));
}
// 6.关闭资源
rs.close();
pst.close();
conn.close();
}
}
使用防止SQL注入的方式,更新数据库信息
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
/**
* @Title: JDBCDemo04
* @Description:防止SQL注入的方法,增加一条数据
* @author jsz
* @date 2018年7月22日
*/
public class JDBCDemo04 {
public static void main(String[] args) throws Exception {
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接对象
String url = "jdbc:mysql://localhost:3306/itheima";
Connection conn = DriverManager.getConnection(url, "root", "root");
// 3.拼写修改的SQL语句,参数采用?占位
String sql = "UPDATE sort SET sname=?,sprice=? WHERE sid=?";
// 4.调用数据库连接对象con的方法prepareStatement获取SQL语句的预编译对象
PreparedStatement pst = conn.prepareStatement(sql);
// 5.调用pst的方法setXXX设置?占位
pst.setObject(1, "汽车美容");
pst.setObject(2, 49988);
pst.setObject(3, 7);
// 6.调用pst方法执行SQL语句
pst.executeUpdate();
// 7.关闭资源
pst.close();
conn.close();
}
}
查询所有数据信息
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
/*
* PreparedStatement接口实现数据表的查询操作
*/
public class JDBCDemo05 {
public static void main(String[] args) throws Exception {
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接对象
String url = "jdbc:mysql://localhost:3306/itheima";
Connection conn = DriverManager.getConnection(url, "root", "root");
// 3.拼写修改的SQL语句,参数采用?占位
String sql = "select * from sort";
// 4.调用数据库连接对象con的方法prepareStatement获取SQL语句的预编译对象
PreparedStatement pst = conn.prepareStatement(sql);
// 5.调用pst方法执行SQL语句
ResultSet rs = pst.executeQuery();
while(rs.next()){
System.out.println(rs.getString("sid")+"\t"+rs.getString("sname")+"\t"+rs.getString("sprice")+"\t"+rs.getString("sdesc"));
}
// 7.关闭资源
rs.close();
pst.close();
conn.close();
}
}