DriverManager(驱动管理类)作用:
注册驱动的相关函数:Class.forName(com.mysql.cj.jdbc.Driver) – 可以不写
获得数据库连接的函数:static Connection getConnection(String url, String user, String password)
url语法格式:jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2…
示例:“jdbc:mysql://localhost:3306/数据库名”
提示细节:
Connection(数据库连接对象)作用:
1、获得执行的SQL
2、管理事务
package com.lz;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBC_Connection {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获得数据库连接
String url="jdbc:mysql://localhost:3306/java";
String username="root";
String password="123456";
Connection conn= DriverManager.getConnection(url,username,password);
String sql1="update user set username='yjr' where id=1"; //定义两个sql语句
String sql2="update user set username='zzz' where id=3";
//获得执行sql的Statement的对象
Statement statement= conn.createStatement();
try {
//开启事务
conn.setAutoCommit(false);
System.out.println(statement.executeUpdate(sql1));//执行两个sql语句
//设置一个异常
int i=1/0;
System.out.println(statement.executeUpdate(sql2));
//提交事务
conn.commit();
} catch (Exception e) {
//回滚事务
conn.rollback();
throw new RuntimeException(e);
}
//释放资源
statement.close();conn.close();
}
}
Statement作用:执行SQL语句
执行SQL语句
int executeUpdate(sql) //执行DML、DDL语句
//返回值:(1)DML语句影响的行数(依据返回值的结果判断是否操作成功) (2)DDL语句操作后,执行成功可能也返回0(当只要不出异常就表示操作成功)
ResultSet executeQuery(sql) //执行DQL语句
//返回值:ResultSet结果集对象
ResultSet(结果集对象)作用:封装了DQL查询语句的结果
ResultSet executeQuery(sql) //执行DQL语句,返回ResultSet对象
获取查询的结果
boolean next():(1)将光标从当前位置向前移动一行 (2)判断当前行是否为有效行
/*
返回值: true--有效行,当前行有数据
false--无效行,当前行没有数据
*/
xxx getXxx(参数):获取数据
/*
Xxx:数据类型; 如:int getInt(参数);String getString(参数)
参数:int--列的编号,从1开始
String-- 列的名称
*/
//示例:
@Test
public void test() throws SQLException, ClassNotFoundException {
Class.forName("com.mysql.cj.jdbc.Driver"); //注册驱动
// 定义url、数据库用户名、数据库的密码
String url="jdbc:mysql:///java?useSSL=false";
String username="root";
String password="123456";
Connection conn= DriverManager.getConnection(url,username,password); //获取数据库连接
String sql="select * from user";
//创建执行sql的Statement对象
Statement stm= conn.createStatement();;
//执行sql语句,返回一个ResultSet结果集对象
ResultSet rs=stm.executeQuery(sql);
while (rs.next()){
// //通过下标的方式:获得resultset集合中的数据
// int id=rs.getInt(1);
// String name=rs.getString(2);
// String pass=rs.getString(3);
//通过表中的字段属性来获取resultset中的数据
int id=rs.getInt("id");
String name= rs.getString("username");
String pass=rs.getString("password");
System.out.println(id + " " + name + " " + pass);
}
//释放资源
stm.close();
conn.close();
}
PreparedStatement原理:
String username="yjr";
String password="' or '1 = 1";
String sql="select * from user where username='"+username+"' and password='"+password+"'"; //定义sql语句
//最终执行的sql语句(有sql注入)
//select * from user where username='yjr' and password='' or '1 = 1'
PreparedStatement作用:预编译SQL语句并执行;预防SQL注入的问题(将敏感字符进行转义)
//SQL语句中的参数值,使用?占位符代替
String sql="select * from user where username=? and password=?";
//通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt=conn.PrepareStatement(sql);
2.设置参数值
PreparedStatement对象:setXxx(参数1,参数2):给?赋值
Xxx:数据类型; 如setInt(参数1,参数2)
参数:
参数1:?的位置编号,从1开始
参数2:?的值
3.执行SQL
executeUpdate();//此时这两种方法不需要再传递sql
executeQuery();
4.示例
package com.lz;
import org.junit.Test;
import java.sql.*;
public class JDBC_PreparedStatement {
/**
*解决SQL注入的问题--PreparedStatement
*/
@Test
public void testLogin() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver"); //注册驱动
// 定义url、数据库用户名、数据库的密码
String url="jdbc:mysql:///java?useSSL=false";
String username1="root";
String password1="123456";
Connection conn= DriverManager.getConnection(url,username1,password1); //获取数据库连接
String username="yjr";
String password="123";//'or' 1' = '1
String sql="select * from user where username=? and password=?";
PreparedStatement pstmt= conn.prepareStatement(sql);
pstmt.setString(1,username);//设置参数=》?---这里解决了sql注入的问题,pstmt.setXxx()在设置参数时,进行了转义,就没有将正常中的单引号保留
pstmt.setString(2,password);
System.out.println(sql);
ResultSet rs=pstmt.executeQuery();//直接调用方法,不传递参数并返回结果集
if (rs.next()){
System.out.println("用户登录成功!");
}
else {
System.out.println("登录失败!");
}
//释放资源
conn.close();
rs.close();
pstmt.close();
}
/**
*SQL注入问题
*/
@Test
public void testLogin_inject() throws SQLException, ClassNotFoundException {
Class.forName("com.mysql.cj.jdbc.Driver"); //注册驱动
// 定义url、数据库用户名、数据库的密码
String url="jdbc:mysql:///java?useSSL=false";
String username1="root";
String password1="123456";
Connection conn= DriverManager.getConnection(url,username1,password1); //获取数据库连接
String username="yjr";
String password="'or '1'='1";//sql注入
String sql="select * from user where username='"+username+"' and password='"+password+"'";
System.out.println(sql);//select * from user where username='yjr' and password=''or '1'='1'
Statement stmt= conn.createStatement();
ResultSet rs=stmt.executeQuery(sql);
if (rs.next()){
System.out.println("用户登录成功!");
}
else {
System.out.println("登录失败!");
}
//释放资源
conn.close();
rs.close();
stmt.close();
}
}
2. 数据库连接池的实现
标准接口:DataSource(获取连接)
Connection getConnection()//获取连接--不在使用DriverManager。getConnection()方法获取
常见的数据库连接池:DBCP、C3P0、Druid
Druid(德鲁伊):是阿里巴巴开源的数据库连接池的项目;功能强大,性能优秀,是java语言最好的数据库连接池之一。
3. 数据库连接池的使用步骤
导入响应的Maven依赖、定义配置文件、加载配置文件、获取数据库连接对象、获取连接
4. 使用
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.2.3version>
dependency>
package com.lz.druid;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;
public class Demo_Druid {
public static void main(String[] args) throws Exception {
//1.导入Maven依赖
//2.定义配置文件
//3.加载配置文件
Properties prop=new Properties();
prop.load(new FileInputStream("src/main/java/com/lz/druid.properties"));
//4.获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//5.获取数据库连接对象
Connection connection= dataSource.getConnection();
System.out.println(connection);
System.out.println(System.getProperty("user.dir"));//当前工程的路径
}
}