JDBC
1.什么是JDBC
官方sun公司定义的一套操作所有关系型数据库的规则,接口。
各个数据库厂商去实现这个接口,提供jar包
我们使用数据库厂商提供的jar包进行连接和使用数据库。
2.JDBC涉及的API
- DriverManager 驱动管理类(注册驱动的)
- Connection 数据库连接对象
- Statement 执行SQL语句
- ResultSet 结果集对象(封装返回数据的对象)
3.SQL注入
什么是SQL注入?
解:SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。
Statement有SQL注入的问题,如下所示:
"String name = "abc";//这是用户名
"String pwd = "' or '1' = '1";//这是密码
String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"'";
拼接字符串后最后的SQL语句是:
String sql = "select * from tb_user where username = 'abc' and password = ''or'1'='1';
拆开来看这个拼接好的字符串
前面
select * from tb_user where username = 'abc' and password = ''
后面
or'1'='1';
前一部分是false, 后一部分是true, 因为是or,所以一方成立,就判定为true,所以最后可以登录成功。
4.使用PreparedStatement可以防止SQL注入
作用
- 预编译SQL语句
- 防止SQL注入,将敏感字符进行转义 开启预编译功能
- 在url后面加上useServerPrepStmts=true
PreparedStatement的使用
//定义sql
String name = "abc";
Int id = 1;
String sql = "insert into db values(?,?);";
//预编译SQL
PreparedStatement pstmt = connection.prepareStatement(sql);
//设置参数
pstmt.setString(1,name); //参数1代表SQL语句中的第一个问号
pstmt.setInt(2,id); //参数2代表SQL语句中的第二个问号
//执行SQL
int count = pstmt.executeUpdate();
//释放资源
...
5.数据库连接池
作用
-
管理数据库连接(connection)
-
资源重用
数据库连接池会提前创建一些连接,不需要在创建连接,用的时候直接从连接池获取,不用的时候在放回连接池 -
提升系统响应速度 数据库连接池接口名称
DataSource
常见的数据库连接池
- DBCP
- C3P0
- Druid
6.Druid的使用
-
导入jar包 druid.jar
-
定义配置文件
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql:///test?useSSL=false&useServerPrepStmts=true username=root password=1234 # 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时 initialSize=10 # 最大连接数 maxActive=10 # 最大等待时间 maxWait=3000 #最小连接池数量 minIdle=5 -
加载配置文件 (Properties.load 方法加载)
-
获取数据库连接池对象
DruidDataSourceFactory.createDataSource() -
获取连接
Connection connection = dataSource.getConnection();
7.练习
public class PracticeQuery {
public static void main(String[] args) throws Exception {
//1.导入jar包
//2.创建Druid.propeties配置文件
//3.加载配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("src/druid.properties"));
//4.获取连接对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
Connection connection = dataSource.getConnection();
//5.创建sql语句
String sql = "select * from tb_brand";
//6.传入sql语句,prepareStatement进行预编译SQL语句
PreparedStatement pstmt = connection.prepareStatement(sql);
//7.执行SQL语句
ResultSet rs = pstmt.executeQuery();
//8.创建pojo对象,防止在循环中重复创建对象
Brand brand = null;
//9.创建集合对象,用来存储pojo对象
ArrayList<Brand> brands = new ArrayList<>();
//10.对结果集对象进行遍历
while (rs.next()){
int id = rs.getInt("id");
String brandName = rs.getString("brand_Name");
String companyName = rs.getString("company_Name");
int ordered = rs.getInt("ordered");
String description = rs.getString("description");
int status = rs.getInt("status");
brand = new Brand();
//11.获取到数据后,进行赋值
brand.setId(id);
brand.setBrandName(brandName);
brand.setCompanyName(companyName);
brand.setOrdered(ordered);
brand.setDescription(description);
brand.setStatus(status);
//12.将对象加载到集合对象brands中
brands.add(brand);
}
System.out.println(brands);
//13.释放资源,倒序释放资源。
rs.close();
pstmt.close();
connection.close();
}
}