数据库总结
1.了解数据库
1.1了解什么是数据库: 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库;随着信息技术和市场的发展,数据管理不再仅仅是存储和管理数据,而转变成用户所需要的各种数据管理的方式 。
1.2常用数据库的分类:mysql , oracle
1.3sql语言的分类:DDL,DML , DCL
- DDL:数据定义语言:create: 创建 drop:删除 alter:修改 rename: 重命名 truncate: 截断
- DML数据管理语言: insert :插入 delete:删除 update:更新 select :查询
- DCL:数据控制语言: grant: 授权 revoke:回收权力 commit :提交事务 rollback: 回滚事务
1.4表结构:表由表名、字段(名称+类型+约束)、记录 组成。与 java 相对应:
2.select语句
结构:select distinct * 字段|表达式 as 别名 from 表 表别名
-
SELECT * FROM 表名; à查询某个表中所有的记录的所有字段信息
-
SELECT 列名 FROM 表名; à 查询某个表中所有的记录的指定字段信息
-
SELECT 列名1,列名2 FROM 表名; à 查询某个表中所有的记录的字段1 字段2
-
SELECT distinct 列名 FROM 表名; à去除重复记录
-
SELECT 表达式 FROM 表名; à查询表达式
-
SELECT xxx as 别名 FROM 表名 表别名 à使用别名
3.查询行(记录)
结构:…where 行过滤条件
条件:
a)、= 、 >、 <、 >=、 <=、 !=、 <>、 between and
b)、and 、or、 not、 union、 union all、 intersect 、minus
c)、null :is null、 is not null、 not is null
d)、like :模糊查询 % _ escape(‘单个字符’)
f)、in 、 exists(难点) 及子查询m
4.in,exists与排序
4.1 in相当于使用or的多个等值,定值集合 ,如果存在 子查询,确保 类型相同、字 段数为1,如果记录多,效率不高,用于 一些 少量定值判断上
4.2 exists条件为true,存在记录则返回结果,后续不再继续 比较查询,与查询的字 段无关,与记录有关
4.3 使用 ORDER BY 排序,排序不是真实改变存储结构的顺序,而是获取的集合的 顺序。
-
顺序 :asc(默认) desc
-
多字段: 在前面字段相等时,使用后面的字段排序
-
空排序: 降序为 desc,注意 null 为最后
5.组函数:sum() count() max() min() avg()
注意:计算组函数,null值不参与运算,组函数不能与非分组字段一起使用,组函数只能和组函数一起使用,不能与其他普通字段一起使用 group by,组函数不能使用在where后面
6.分组:group by
结构:select 查询数据 from 数据来源 where 行过滤条件 group by 分组字段1,分组字段2… having 组过滤条件 order by 排序字段…;
执行流程: from – where – group by – having – select – order by
7.表连接:92语法, 99语法
7.1 92语法:select 数据 from 数据来源1,数据来源2; 对乘 笛卡尔积
select 数据 from 数据来源1,数据来源2 where 表连接条件|行过滤条件;
外链接
当你想要表连接中某一张表中所有的数据全部展示,无论是否满足满足连接条件都显示,可以把这张表设置为主表
在外连接中主表的表中所有数据都能展示
如何设置外连接中的主表,在连接条件位置 主表对象加(+)
左外连接 : 主表在逗号左边就是左连接
右外连接 : 主表在逗号右边就是右连接
7.2:99语法:join
cross join 笛卡尔积 对乘
等值连接与非等值连接
--自然连接 natural join 自动根据同名字段|主外键关系
select ename,sal,deptno from emp natural join dept; --同名字段不能指明出处
jion using(等值连接字段名) 当存在多个同名字段,可以指明使用哪一个做等值连接
select ename,sal,deptno from emp join dept using(deptno);
数据来源1 join 数据来源2 on 连接条件 ; 即可以实现等值连接 可以实现非等值连接
select * from emp e join dept d on e.deptno = d.deptno;
--非等值连接
--查询员工信息以及每一个员工的薪资等级
select * from emp e join salgrade s on e.sal between s.losal and s.hisal;
外链接
想要某张表中不满足连接条件的数据都显示,把这张表定义为主表
左外 left join
右外 right join
8.rowid 和 rownum
8.1 rowid 相当于对象的地址,区分表中的数据,是记录的唯一,在数据插入表中时就存在
作用: 可以对多数相同数据做去重(没有主键的表)
8.2 rownum 伪列 结果集的序号 只要有select就有结果集就有rownum,每一套结果集都有自己的rownum
规律: 把以确定结果集中的数据从第一个开始 设置rownum,从1开始,依次+1
优点: 有规律,规律可循,是数字,可以进行判断
作用:实现分页查询
9.索引
- 是数据库的对象之一
- 字典的目录
- 只有在大量数据查询的时候效率较高
- 大量数据 查询,如果增删改效率降低,因为对象要维护
- 索引的创建与删除完全不影响字段的使用
- 唯一字段适合设置索引
- oracle自动为主键设置索引
-创建索引
--create index 索引名 on表名 (字段列表...)
create index index_sal on emp(sal);
--删除
--drop index 索引名
drop index index_sal;
10.表设计
10.1 设计表要注意的问题:
表 表名 字段 约束 表与表之间的关系
三范式
表与表之间的关系: 一对一 一对多|多对一(主外键) 多对多{中间表}
创建表与约束问题
1)创建表的同时不创建约束, 结束后追加约束
2)创建表的同时为字段添加约束
3)创建表的结构结束之间添加约束
约束的添加: 1)物理约束 :表中字段上添加 2)逻辑约束:java代码上使用逻辑判断
主键 外键 非空 唯一 检查
10.2 创建表:
create table 表名(
字段 字段类型,
字段 字段类型,
....
)
10.3删除表
drop table 表名;
10.4.添加数据
insert into 表名t values(字段1,字段2,字段3.....);
10.5 添加约束
- 字段后直接添加约束,没有约束名 不便于后期维护,但是编写简单
create table sxt_student(
--学生编号 主键约束
sid number(5) primary key,
--学生姓名 非空约束
sname varchar2(15) not null unique,
--年龄 检查约束0~150
sage number(3) check(sage between 0 and 150),
--性别 检查约束 '男' '女'
sgender char(1 char) check(sgender in('男','女')),
--入学日期 默认值 sysdate
hiredate date default(sysdate),
cid number(5)
)
- 字段后直接添加约束包括约束名
create table sxt_student(
--学生编号 主键约束
sid number(5) constraints pk_sxt_student_sid primary key,
--学生姓名 非空约束
sname varchar2(15) constraints sxt_student_sname_notnull not null,
--年龄 检查约束0~150
sage number(3) check(sage between 0 and 150),
--性别 检查约束 '男' '女'
sgender char(1 char),
--入学日期 默认值 sysdate
hiredate date default(sysdate),
cid number(5),
--创建表结构结束前 添加约束
constraint ck_user_pwd check(length(userpwd) between 4 and 18),
-- constraints pk_sgender check(sgender in('男','女')),
constraints sxt_student_sname_unique unique(sname)
)
10.6 添加注释
comment on table 表名 is ‘注释字段’;
11.数据删除
如果两张表存在主外键约束:
删除表:
默认先删除从表 再删除主表
cascade constraints 删除主表的同时级联删除约束
删除数据:
删除从表数据: 直接删除
删除主表数据:
从表中是否有数据引用了当前的主表数据
没有引用可以直接删除
有引用,想要删除需要一下三种方式处理:
默认 先删除从表引用的数据,再删除被引用的主表数据
添加外键约束时,on delete set null 删除主表数据的同时,从表引用字段设置为null
添加外键约束时,on delete cascade 删除主表数据的同时,级联删除从表引用了的数据
12.jdbc的流程
12.1JDBC基本流程:
- 1.加载驱动 (选择哪一个数据库)
- 2.获取连接 (与数据库连接上)
- 3.准备sql
- 4.获取处理块(打包发送)
- 5.接收结果集
- 6.处理结果数据
- 7.关闭
代码例子:
package com.shsxt.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/*
* JDBC基本流程:
* 1.加载驱动 (选择哪一个数据库)
* 2.获取连接 (与数据库连接上)
* 3.准备sql
* 4.获取处理块(打包发送)
* 5.接收结果集
* 6.处理结果数据
* 7.关闭
*/
public class JDBCDemo01 {
public static void main(String[] args) throws Exception {
//1.加载驱动 (选择哪一个数据库)
Class.forName("oracle.jdbc.OracleDriver");
//2.获取连接 (与数据库连接上)
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "SCOTT", "TIGER");
//3.准备sql
String sql = "select deptno,dname,loc from dept";
//4.获取处理块(打包发送)
Statement state = conn.createStatement();
//5.接收结果
ResultSet result = state.executeQuery(sql);
//6.处理结果数据
while(result.next()){
//注意:字段索引从1开始
int num = result.getInt(1);
String dname = result.getString(2);
String loc = result.getString(3);
System.out.println(num+"--->"+dname+"--->"+loc);
}
//7.关闭
result.close();
state.close();
conn.close();
}
}
12.2 jdbc的流程优化与封装
优化: 1.异常捕获
2.数据库的配置信息使用配置文件动态获取
封装:将配置文件的加载与驱动的加载以及连接的建立分装成方法
13.Mybatis框架
13.1 特点:
属于持久层的ORM框架
半自动化
13.2 Mybatis的环境搭架
-
创建项目
-
导入jar包:Mybatis的核心jar包 ,Mybatis依赖的jar包 ,数据库驱动包
-
Mybatis核心配置文件:是一个xml文件,命名无要求,位置无要求,一般成为mybatis.xml,放在src路径下
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <!-- Mybatis全局配置文件 根元素 --> <configuration> <!-- 用户指定使用哪一个开发环境 default : 用户指定使用的开发环境的id --> <environments default="dev"> <!-- id : 环境的标识 定义唯一 --> <environment id="dev"> <!-- 事务管理器: type : 设置mybatis采用什么方式管理事务 JDBC : 标识采用jdbc的事务管理方式 --> <transactionManager type="JDBC"/> <!-- 用户配置数据库连接池和数据库连接参数 type : 用户设置mybatis是否采用连接池技术 POOLED :表示mybatis采用连接池技术 --> <dataSource type="POOLED"> <!-- 设置连接数据库参数 --> <property name="driver" value="oracle.jdbc.OracleDriver"/> <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/> <property name="username" value="SCOTT"/> <property name="password" value="TIGER"/> </dataSource> </environment> </environments> <!-- sql映射文件加载设置 --> <mappers> <!-- 包路径 : 报名+文件名 --> <mapper resource="com/shsxt/mappers/DeptMapper.xml"/> </mappers> </configuration>
-
添加Dept|User类
package com.shsxt.pojo; import java.io.Serializable; public class Dept implements Serializable{ private int deptno; private String dname; private String loc; public Dept() { // TODO Auto-generated constructor stub } public Dept(int deptno, String dname, String loc) { super(); this.deptno = deptno; this.dname = dname; this.loc = loc; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + deptno; result = prime * result + ((dname == null) ? 0 : dname.hashCode()); result = prime * result + ((loc == null) ? 0 : loc.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Dept other = (Dept) obj; if (deptno != other.deptno) return false; if (dname == null) { if (other.dname != null) return false; } else if (!dname.equals(other.dname)) return false; if (loc == null) { if (other.loc != null) return false; } else if (!loc.equals(other.loc)) return false; return true; } @Override public String toString() { return "Dept [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + "]"; } }
-
Mybatis SQL映射文件:在Mybatis中,推荐使用mappers作为包名,我们只需要写一个映射配置文件就可以,DeptMapper.xml,用于定义要执行的sql语句,同时可以设置参数|返回值结果类型
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace 命名空间 要求: 全部唯一,在整个应用中不能出其他的映射文件的命名空间相同情况,保证唯一 设置值方式: 1)随意定义,只要不重复就行,但是不便于后期维护 2)推荐使用当前的报名+文件名形式(不要文件名后缀)->com.shsxt.mappers.DeptMapper --> <mapper namespace="com.shsxt.mappers.DeptMapper"> <!-- 查询标签: id: 当前Statement的唯一标识,当前文件中不能重复 resultType: 入参类型(结束的数据类型) --> <select id="queryAll" resultType="com.shsxt.pojo.Dept"> <!-- 权限定名 --> select * from Dept </select> </mapper>
-
测试代码
package com.shsxt.test; import java.io.IOException; import java.io.InputStream; import java.util.List; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import com.shsxt.pojo.Dept; public class DeptTest { public static void main(String[] args) throws IOException { //1.加载Mybatis全局配制文件 InputStream is=Resources.getResourceAsStream("mybatis.xml"); //2.构建SqlSessionFactory对象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); //3.根据工厂构建SqlSession会话对象 SqlSession session=factory.openSession(); //4.通过session中的方法执行查询 //参数: 命名空间+id List<Dept> list=session.selectList("com.shsxt.mappers.DeptMapper.queryAll"); list.forEach(System.out::println); //5.关闭会话 session.close(); } }