子查询
在select语句中包含另一个select 语句 -->子查询
子查询的分类
单行单列子查询
在where子句中使用 运算符 = != >= <=
-- 查询工资比公司平均工资高的员工信息
-- 查询与员工’smith‘同职位的员工信息
-- 查询比员工joins入职造的员工信息
-- 查询与scott同一个领导的员工信息
-- 查询10号部门中最高工资的员工信息
-- 查询20号部门中比本部门平均工资高的员工信息
单列多行查询
在where子句中使用 运算符 all some any
查询比10号部门所有工资都高的员工信息
select empno,ename,job,sal,deptno
from emp
where sal > all (select sal from emp where deptno =10)
查询20号部门中任意员工工资相同的非20号员工信息 any与in相同
select empno,ename,job,sal,deptno
from emp
where sal = all (select sal from emp where deptno =20)
and deptno != 20;
查询比任何一个部门平均工资高的员工信息
select *
from emp
where sal > any(select avg(sal) from emp group by deptno);
查询比每个部门平均工资都高的员工i信息
select *
from emp
where sal > all (select avg(sal) from emp group by deptno)
查询与职位 salesman工资相同的员工信息
select *
from emp
where sal = any(select sal from emp where job ='salesman');
查询所有领导的信息
select *
from emp
where empno = any(select mgr from emp where mgr is not null )
查询所有非领导的信息
select *
from emp
where empno != any(select mgr from emp where mgr is not null )
查询每个部门的平均工资(部门编号 部门名称 平均工资 工资等级)
select dept.dname, dept.deptno,avg(sal),salgrade.grade
from emp inner join dept on emp.deptno = dept.deptno
inner join salgrade on emp.sal between salgrade.losal and salgrade.hisal
group by deptno
having avg(sal) = any(select avg(sal) from emp group by deptno);
查询每个部门中最高工资的员工信息
1)每个部门的最高工资
select deptno,max(sal)
from emp
group by deptno
2)
select *
from emp
where (deptno,sal) in(
select deptno,max(sal)
from emp
group by deptno);
--方法2 多表查询
select e.*
关联子查询
内部的select中使用到外部select语句中查询到的数据
当外部select语句执行一次,内部语句也会执行一次
查询每个部门中本部门高于平均工资的员工信息。按部门编号升序显示
select *
from emp inner join (select avg(sal),deptno from emp group by deptno) a on
where sal > any(a)
and deptno = any(a)
order by deptno;
或
select *
from
查询所有领导信息
select * from emp where empno in (select distinct mgr from emp where mgr is not null);
select *
exists 子查询
exists判断子查询是否有结果返回 有则为true
not exists判断子查询是否有结果返回 无则为true
查询领导信息
select * from emp e1 where exists (select mgr from emp e2 where e2.mgr = e1.empno);
查询没有员工的部门信息
select * from emp e1 where exists
( select e2.deptno,d.*
from emp e2 join on dept d on e2.deptno = d.deptno where e2.mgr is null )
查询没有领导的员工信息
select * from emp e1 where exists
(select e1.empno
from emp e2 where e2.mge is null)
数据库连接池
jdbc知识点
jdbc基本概述
jdbc相关的四个接口一个类
jdbc操作步骤
封装连接工具类
DAO service.view
事务
jdbc基本概述
java database connect (java数据库连接技术)
相关四个接口一个类 java.sql javax.sql包
java.sql.Driver 驱动接口
java.sql.Connection连接接口
java.sql.Statement:接口 把java中sql语句发送到数据库,并返回执行后的结果
java.sql.ResultSet 结果集接口 指 Statement执行查询后的结果集
java.sql.DriverManager 驱动管理类
操作步骤
1)查询的操作步骤
1加载驱动 Class.forName(驱动实现类的名称)
2获取连接
Connection c = DriverManager.getConnection(url,user,password)
3定义查询的sql语句
String sql= "";
4创建Statement对象
Statement s =c.createStatement();
5调用Statement的查询方法,返回结果集
Result r = s.executeQuery(sql);
注意没有查询到数据,结果集对象不为null,r.next()为false
6遍历结果集
r.next():
结果集光标在第一行的列名之前,
第一次调用next方法使数据第一行成为当前行
读取每列的值
r.getXXX(int index): 按列的下标读取,下标从一开始 指结果集的下标
r.getXXX(String columnName)按列名读取数据 指结果集的列名
7 释放资源
执行增删改的操作步骤
s.updateQuery(sql);
使用PreparedStatement 替换 Statement
java.sql.PreparedStatement extends Statement
表示预编译的sql语句对象
区别
1)Statement使用字符串拼接sql语句,易造成sql注入不安全
PreparedStatement使用占位符编写sql语句,防止sql注入,提高数据安全性
2)PreparedStatement预编译sql语句,多次高效执行sql语句,预编译的sql仅执行一次
多次执行,statement对象每次都先编译再执行.
连接工具类
如果数据库发生改变,连接字符串同时也发生改变?
实现步骤
1)定义一个配置文件(src目录下)xxx.properties
2)在DBUtil使用properties属性文件获取属性值
3)当有多个线程同时操作连接时,出现异常
原因:Connection是static修饰的,多个线程使用的同一个连接对象
其中一个线程把连接关闭.其他线程连接关闭
解决方式一:是否可以把获取连接方法时,每次获取生成一个新的连接对象?
这种方式不可以,当有实务操作时,保证所有的sql操作使用的为同一个连接对象
解决:为每个线程单独存储一份连接对象
ThreadLocal对象 java.lang包下
为每个线程存储单独的数据,互相之间不影响.
问题:当有多个线程访问时,每一个线程都创造一个连接对象
会造成资源的浪费,同时增加维护成本.
解决方案:
使用连接池
1)有哪些常用的连接池
DBCP,C3PO,MDRUID
2)核心对象 javax.sql.Datasource
3)实现步骤
1在项目中添加jar包