JDBC
JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。是Java访问数据库的标准规范
JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。
JDBC需要连接驱动,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信。
JDBC是接口,驱动是接口的实现,没有驱动将无法完成数据库连接,从而不能操作数据库!每个数据库厂商都需要提供自己的驱动,用来连接自己公司的数据库,也就是说驱动一般都由数据库生成厂商提供。
JDBC操作数据库的步骤
1.注册驱动
- 告知JVM使用的是哪一个数据库的驱动
2.获得连接
- 使用JDBC中的类,完成对MySQL数据库的连接
3.获得语句执行平台
- 通过连接对象获取对SQL语句的执行者对象
4.执行sql语句
- 使用执行者对象,向数据库执行SQL语句;获取到数据库的执行后的结果
5.处理结果
6.释放资源 一堆close()
1、增删改操作
public static void main(String[] args)throws ClassNotFoundException,SQLException{
//registerDriver的参数传递MySQL驱动程序中的实现类
//DriverManager.registerDriver(new Driver());
//但是看MySQL的驱动类源代码,也进行了一次注册,这样就注册了2次驱动程序,所以我们要用反射技术
//1.注册驱动 反射技术,将驱动类加入到内容
// 使用java.sql.DriverManager类静态方法 registerDriver(Driver driver)
Class.forName("com.mysql.jdbc.Driver");
//2.获得数据库连接 DriverManager类中静态方法
//static Connection getConnection(String url, String user, String password)
//返回值是Connection接口的实现类,在mysql驱动程序
//url: 数据库地址 jdbc:mysql://连接主机IP:端口号//数据库名字
String url = "jdbc:mysql://localhost:3306/xingedb";
String username="root";
String password="xxx";
Connection conn = DriverManager.getConnection(url, username, password);
//3.获得语句执行平台, 通过数据库连接对象,获取到SQL语句的执行者对象
// conn对象调用方法 Statement createStatement() 获取Statement对象,将SQL语句发送到数据库
// 返回值是 Statement接口的实现类对象,,在mysql驱动程序
Statement stat = conn.createStatement();
//4.执行sql语句
// 通过执行者对象调用方法执行SQL语句,获取结果
// int executeUpdate(String sql) 执行数据库中的SQL语句, insert delete update
// 返回值int,操作成功数据表多少行
int row = stat.executeUpdate
("INSERT INTO sort(sname,sprice,sdesc) VALUES('汽车用品',50000,'疯狂涨价')");
System.out.println(row);
//6.释放资源 一堆close()
stat.close();
conn.close();
}
2、查询操作
查询使用的是executeQuery方法
public static void main(String[] args) throws Exception{
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2. 获取连接对象
String url = "jdbc:mysql://localhost:3306/mybase";
String username="root";
String password="123";
Connection conn = DriverManager.getConnection(url, username, password);
//3 .获取执行SQL 语句对象
Statement stat = conn.createStatement();
// 拼写查询的SQL
String sql = "SELECT * FROM sort";
//4. 调用执行者对象方法,执行SQL语句获取结果集
// ResultSet executeQuery(String sql) 执行SQL语句中的select查询
// 返回值ResultSet接口的实现类对象,实现类在mysql驱动中
ResultSet rs = stat.executeQuery(sql);
//5 .处理结果集
// ResultSet接口方法 boolean next() 返回true,有结果集,返回false没有结果集
while(rs.next()){
//获取每列数据,使用是ResultSet接口的方法 getXX方法参数中,建议写String列名
System.out.println(rs.getInt("sid")+" "+rs.getString("sname")+" "+rs.getDouble("sprice")+" "+rs.getString("sdesc"));
}
rs.close(); //查询还要关闭结果集
stat.close();
conn.close();
}
SQL注入攻击
3、解决SQL注入问题
预处理对象
使用PreparedStatement预处理对象时,建议每条sql语句所有的实际参数,都使用逗号分隔
查询
private static void func() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/testdb";
String username = "root";
String password = "5456";
Connection conn = DriverManager.getConnection(url, username, password);
String sql = "SELECT * FROM users WHERE uname=? AND passwd=?"; // 使用?做占位符
String uname = "a";
String passwd = "123456' OR '1";
// 调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类
PreparedStatement pst = conn.prepareStatement(sql);
pst.setObject(1,uname); // 调用pst对象set方法,设置问号占位符上的参数
pst.setObject(2,passwd);
ResultSet rs = pst.executeQuery();
while (rs.next()){
System.out.println(rs.getString("uname")+" "+rs.getString("passwd"));
}
}
增删改
public static void main(String[] args) throws Exception{
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mybase";
String username="root";
String password="123";
Connection con = DriverManager.getConnection(url, username, password);
//拼写修改的SQL语句,参数采用?占位
String sql = "UPDATE sort SET sname=?,sprice=? WHERE sid=?";
//调用数据库连接对象con的方法prepareStatement获取SQL语句的预编译对象
PreparedStatement pst = con.prepareStatement(sql);
//调用pst的方法setXXX设置?占位
pst.setObject(1, "汽车美容");
pst.setObject(2, 49988);
pst.setObject(3, 7);
//调用pst方法执行SQL语句
pst.executeUpdate();
pst.close();
con.close();
}
JDBCUtils工具类
读取配置文件版
package cn.x5456.demo2;
/*
* 实现JDBC的工具类
* 定义方法,直接返回数据库的连接对象
*
* 写关闭方法
*/
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;
public class JDBCUtils {
private JDBCUtils(){}
private static Connection conn ;
private static String dirverClass;
private static String url;
private static String username;
private static String password;
// 静态代码块,调用就执行
static{
try{
func();
Class.forName(dirverClass);
conn = DriverManager.getConnection(url, username, password);
}catch(Exception ex){
throw new RuntimeException(ex+"数据库连接失败");
}
}
private static void func() throws IOException {
// 获取类的加载器 返回指定资源的输入流
InputStream in = PropertiesDemo.class.getClassLoader().getResourceAsStream("database.properties");
Properties prop = new Properties();
prop.load(in);
dirverClass = prop.getProperty("dirverClass");
url = prop.getProperty("url");
username = prop.getProperty("username");
password = prop.getProperty("password");
}
/*
* 定义静态方法,返回数据库的连接对象
*/
public static Connection getConnection(){
return conn;
}
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){}
}
}
}