8.子查询
MySQL的子查询是指在一个SQL查询语句中嵌套使用另一个SQL查询语句。子查询通常用于根据外部查询的结果来过滤、限制或计算数据。
8.1用处
1.返回结果为单行单列,作为条件放在WHERE后面
2.返回结果为多行多列的表,作为表放在FROM后面
3.返回结果为多行单列,作为条件放在WHERE 字段 IN 后面
#查询平均薪水最多的部门
SELECT * FROM (SELECT avg,t.deptno,name,city FROM (SELECT avg(sal) avg,deptno FROM work GROUP BY deptno) t join part on t.deptno=part.deptno
) t WHERE avg = (select max(avg) FROM (SELECT avg,t.deptno,name,city FROM (SELECT avg(sal) avg,deptno FROM work GROUP BY deptno) t join part on t.deptno=part.deptno
) m);
8.2使用注意
使用子查询可以在一个查询语句中实现更灵活和复杂的数据过滤和计算,使查询结果更精确和符合实际需求。但同时,过多或复杂的子查询可能会影响查询性能,因此在使用子查询时需要考虑性能方面的问题。
9.约束
表中字段上规则,用于限制表中数据存储。
1、唯一约束 UNIQUE
2、默认值 DEFAULT
3、非空 NOT NULL
5、主键 PRIMARY KEY (非空且唯一)
6、外键 FOREIGN KEY (关联其他表中的主键字段)(不建议直接关联,建议逻辑上关联)
10.事务
一个事务是最小的执行单元,在事务中包含多条sql语句,在事务中sql语句要么全部执行成功要么全部执行失败,一般一个事务就是完整业务流程。
10.1事务的特征
1.原子性:事务是一个不可分割的操作单元,要么全部执行成功,要么全部失败回滚。
2.一致性:事务在执行前后,数据库的状态必须保持一致。事务的执行不能违反数据库中定义的约束和规则,保证数据的完整性和正确性。
3.隔离性:多个并发执行的事务之间应该互不干扰,每个事务都应该感觉到它是在独立执行的,即使在实际执行过程中可能存在并发冲突。
4.持久性:一旦事务提交成功,其对数据库的修改应该永久保存,即使系统发生故障或重启,数据也不会丢失。
10.2事务的隔离级别
-
读未提交(Read Uncommitted):事务中的修改可以被其他事务读取,即一个事务可以看到另一个事务尚未提交的数据变更。这个隔离级别最低,可能导致脏读、不可重复读和幻读的问题。
-
读已提交(Read Committed):一个事务只能读取到已经提交的数据,即一个事务只能看到另一个事务已经提交的数据。但是在同一个事务中,多次读取同一数据可能会得到不同的结果,可能导致不可重复读和幻读的问题。
-
可重复读(Repeatable Read):在一个事务中多次读取同一数据会得到一致的结果,即事务执行期间其他事务对该数据的修改不可见。阻止了脏读和不可重复读的问题,但仍然可能出现幻读。
-
串行化(Serializable):最高的隔离级别,事务串行执行,确保事务之间没有并发冲突。避免了脏读、不可重复读和幻读的问题,但会降低并发性能。
隔离级别越高,事务之间的隔离程度越高,但也意味着并发性能可能会降低。在实际应用中,根据业务需求和并发性能的要求,选择合适的隔离级别。
10.3MySQL中的事务(DML)
在MySQL中执行一条sql语句就是一个事务,如果要把多条语句作为一个事务,就要用到start transaction开启一个事务。
START TRANSACTION
:开始一个事务。COMMIT
:提交事务,将已执行的操作永久保存到数据库。ROLLBACK
:回滚事务,撤销已执行的操作,恢复到事务开始前的状态。SAVEPOINT
:在事务中创建一个保存点,可以在回滚时将事务回滚到保存点处。RELEASE SAVEPOINT
:删除一个保存点。
-- 开始事务
START TRANSACTION;
-- 执行数据库操作
-- 注意:这里的 SQL 语句可以包含插入、更新、删除等操作
-- 例:插入一条记录
INSERT INTO table_name (column1, column2) VALUES ('value1', 'value2');
-- 例:更新记录
UPDATE table_name SET column1 = 'new_value' WHERE condition;
-- 提交事务
COMMIT;
-- 回滚事务(可选,根据需要决定是否回滚)
-- 如果在执行数据库操作时发生错误或条件不满足,可以使用 ROLLBACK 回滚事务
ROLLBACK;
-- 结束事务
-- 注意:MySQL 默认使用自动提交模式,所以在结束事务后可以继续执行其他的 SQL 语句
11.数据库连接池(C3P0、德鲁伊)
频繁创建和关闭连接对象,影响程序性能和浪费资源;我们可以引入数据库连接池,自动创建连接对象,管理连接对象。数据库连接池的主要目的是优化数据库连接的创建和销毁过程,以提高系统性能和资源利用率。
11.1 C3P0数据库连接池
-
导入c3p0的相关jar文件
-
配置连接池:在项目的配置文件中,配置C3P0连接池的参数,包括数据库的URL、用户名、密码等。可以通过XML配置文件或Java代码的方式进行配置。
// 配置数据库连接信息 dataSource.setDriverClass("com.mysql.cj.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mydb"); dataSource.setUser("root"); dataSource.setPassword("password");
-
创建连接池:通过C3P0提供的API,创建一个C3P0连接池对象。可以使用ComboPooledDataSource类来创建连接池。
// 创建一个静态的 ComboPooledDataSource 实例,用于管理数据库连接池 private static ComboPooledDataSource dataSource; // 创建 ComboPooledDataSource 对象 dataSource = new ComboPooledDataSource();
-
获取连接:使用连接池对象,调用getConnection()方法获取一个数据库连接对象。这个连接对象是从连接池中获取的,而不是直接与数据库建立新的连接。
// 获取数据库连接 Connection connection = connection = getConnection();
-
使用连接:通过获取到的数据库连接对象,进行数据库操作,执行SQL语句、事务处理等。
-
关闭连接:在使用完数据库连接后,需要调用连接对象的close()方法将连接归还给连接池。连接池会自动管理连接的打开和关闭。
-
连接池参数配置:C3P0提供了丰富的参数配置选项,可以根据实际需求进行调整。例如,可以配置最大连接数、最小连接数、连接超时时间、空闲连接回收等。
-
连接池监控:C3P0还提供了连接池的监控功能,可以通过配置参数开启监控,实时查看连接池的状态、连接数等信息。