web基础第十一天:JDBC+C3P0连接池

JDBC

JDBC概述

JDBC(Java DataBase Connectivity)Java数据库连接

利用java语言/java程序连接并访问数据库的一门技术

JDBC程序访问数据库

第一步:准备数据

第二步:创建工程并导入jar包

jar包:mysql-connector-java-8.0.11.jar

WEB项目:放到WebContent/WEB-INF/lib目录下

Java基础项目:可以在项目中建一个lib目录,上面的jar文件赋值到项目的lib目录下,在选中jar文件,右键—>Build Path–>Add to Build

第三步:创建测试类,实现JDBC程序(六个步骤)

//1.注册驱动
/* 将mysql驱动包中的"com.mysql.cj.JDBC.Driver"类加载到内存中,Driver类中的静态代码块就会执行,而在Driver类的静态代码块中由一行代码是用于注册驱动的,因此这行代码可以注册驱动!
注册驱动:将mysql驱动交给JDBC程序管理,以便于使用其中的功能
在JDBC4.0以后的版本中,这一步可以省略。
*/
Class.forname("com.mysql.cj.jdbc.Driver");
//2.获取数据库连接
/*
DriverManager.getConnection(url,user,password)
url:指定要链接的是哪一个位置的哪一个库
如果连接的数据库端口是3306,端口可以省略不写
如果是连接本机上的数据库,主机名/IP地址可以省略不写
getConnection方法返回一个Connection对象,用于表示Java程序和数据库服务器之间的连接
*/
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jt_db?serverTimezone=Asia/Shanghai&CharacterEncoding=utf-8","root","root");
//3.获取传输器
/*
conn.createStatement():用于获取向数据库发送SQL语句的传输器对象
*/
Statement stat = conn.createStatement();
//4.发送SQL语句到服务器执行,并将结果返回
String sql ="";
//用于执行查询类型的SQL语句,返回的是一个ResultSet对象
ResultSet rs = stat.executeQuery(sql);
//用于执行新增、删除、修改类型的SQL语句,返回一个int值,表示影响的记录行数
int rows = stat.executeUpdate(sql);
//5.处理执行的结果
/*
rs.next():用于将指向数据行的箭头往下挪动一行,并且返回布尔值(true或false)
true表示箭头往下挪动一行后,指向的行有数据,false表示箭头往下挪动一行后,指向的行没有数据
*/
while(rs.next()){
    
}
//6.释放资源
rs.close();
stat.close();
conn.close();

SQL注入攻击

SQL注入攻击产生的原因:由于SQL语句中的参数是拼接而来的,其中的参数值是用户提交过来的,如果用户在提交参数时,在参数中参杂一些SQL关键字或特殊字符(or、#、-- 、/* */等)就可能回导致SQL语句的语义被篡改,从而执行一些意外的操作

SQL注入攻击解决的方法

方法一:

可以对用户提交过来的参数进行校验,如果用户名或密码中由类似于or、#、-- 等符号,就不再登陆,直接提示用户不合法,请重新登陆。

方法二:

使用JDBC中提供的PreparedStatement对象。

如何解决SQL注入攻击的?

1)PreparedStatement对象是先将SQL语句的骨架(不含参数)发送给服务器编译并确定下来。

String sql="select * from user where username=? and password=?";

PreparedStatement stat = conn.preparedStatement(sql);

2)在将SQL语句中的参数值传递给服务器

//设置SQL语句中的参数值
stat.setString(1,user);
stat.setString(2,psw);
ResultSet rs = stat.executeQuery(sql);
/*
由于前面SQL语句的骨架已经被确定了,因此SQL参数中即使在包含SQL关键字或者特殊符号,也不会影响SQL语句的骨架或语义,只会被当前普通的文本来处理,因此可以防止SQL注入!
*/

数据库连接池

连接池

池:常量池、线程池、连接池等中的池都是一个容器。是指内存中的一片空间

连接池:就是将一批连接资源存入到一个容器中。目的是为了实现连接的复用,减少连接创建和关闭的次数,以此来提高程序执行的效率!

为什么要使用连接池

传统方式中,每次需要连接都是直接创建一个连接(对象/资源),在基于这个创建的连接去访问数据库,最后用完连接还要关闭!

而每次【创建连接】和【关闭连接】相比使用连接是要消耗大量的时间和资源,导致程序的执行效率非常低下!

为了提高程序执行的效率,我们可以在程序启动时,就创建一批连接放在一个连接池中,供整个程序共享。

当用户需要连接时,不用再去创建连接,而是直接从连接池中获取一个连接进行使用,在用完连接后,也不需要关闭,而是直接将连接还回到连接池中。这样一来,用来用去都是连接池中的这一批连接,必然可以实现连接的复用,减少连接创建和关闭的次数。提高程序执行的效率!

如何使用C3P0连接池

第一步:导入c3p0的jar包:c3p0-0.9.1.2.jar

第二步:在程序中创建一个c3p0连接池对象(存放连接的容器)

ComboPooledDataSource pool = new ComboPooledDataSource();

第三步:设置连接数据库的基本信息(四个参数)

//方式一:将连接数据库的参数通过setXxx方法直接通过java代码写死在程序中
/*
这种方法不推荐使用,因为这种方式将连接参数写死在程序中了,将来一旦参数发生变化,就需要我们去改程序,改完之后需要对项目重新编译、打包、部署、运行等,会提高维护成本!
*/
pool.setDriverClass("com.mysql.cj.jdbc.Driver");
pool.setJdbcUrl("jdbc:mysql:///jt_db?serverTimezone=Asia/Shanghai");
pool.setUser("root");
pool.setPassword("root");

//方式二:将连接数据库的参数提取到c3p0.properties(文件名是固定的)文件中,并且需要将这个文件放在源码根目录(src根目录)下,文件内容如下:
c3p0.driverClass=com.mysql.cj.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///jt_db?characterEncoding=utf8&serverTimezone=Asia/Shanghai
c3p0.user=root
c3p0.password=root

//方式三:将连接数据库的参数提取到c3p0-config.xml(文件名也是固定的)文件中,并且需要将这个文件放在源码根目录(src根目录下),文件内容如下:
<?xml version="1.0"  encoding="UTF-8"?>
<c3p0-config>
	<default-config>
		<property name="driverClass">
			com.mysql.jdbc.Driver
		</property>
		<property name="jdbcUrl">
			jdbc:mysql:///jt_db?characterEncoding=utf-8&amp;serverTimezone=Asia/Shanghai
		</property>
		<property name="user">
			root
		</property>
		<property name="password">
			root
		</property>
	</default-config>
</c3p0-config>

第四步:从连接池中获取一个连接对象进行使用

Connection conn = pool.getConnection();

第五步:将用完的连接对象还回到连接池中

pool.close();

xml文件和properties的区别

相同点:这两种文件在企业开发中都可以作为配置文件使用,而且用得特别多

不同点:

1)xml文件缺点:配置信息多,编写起来比较麻烦,如果需要通过java程序读取,代码也会比较麻烦

2)xml文件优点:可以保存由结构的数据

3)properties文件缺点:配置信息结构是key=value,无法保存有结构的数据

4)properties文件优点:配置信息简洁,如果需要通过java程序读取,读取起来也比较方便

数据库事物(Database Transaction)

概述

事物是将一堆的SQL语句绑定在一起执行,结果是要么全部执行成功,要么全部执行失败。而且是都成功了才算成功,但凡有一条执行失败,就按全失败来处理。

事物的四大特性

1)原子性

表示食物中的所有操作(SQL)是一个整体,不能被分割,要么全部执行成功,要么全部执行失败

2)一致性

在事物前后的业务数据之和是保持一致的

3)隔离性

是指所有的事物都是隔离开的,在一个事务中看不到另外一个事物正在进行中的状态

4)持久性

在事务提交后,对数据的更新操作才会持久的保存到数据库中

MySQL中的事物

在mysql中默认一条SQL语句就是一个事物

如果希望将多余SQL放在一个事务中执行,可以手动开启事物,并手动结束事物

开启事务

start transaction / begin

结束事物

提交 commit | 回滚 rollback

JDBC操作事物

在JDBC中默认是自动提交事务,所以需要关闭自动提交,改为手动提交事务

也就是说,关闭了自动提交后,事物就自动开启,但是执行完后需要手动提交或者回滚

//关闭JDBC自动提交事物
conn.setAutoCommit(false)
//手动提交事务
conn.commit()
//回滚事务
conn.rollback()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值