day02-mysql1. 数据库概述 数据库是存储和管理数据的仓库。 数据库软件和数据库的区别: l 数据库大的范围,泛指所有存储和管理数据的数据库(数据库软件) l 数据库软件: app: application(应用),就是一款软件(软件实现想要的功能) 数据库软件:管理和存储数据 l 使用统一的方式(指的sql)来操作所有的数据库。 2. mysql数据库安装错误:报这个状态码1006(1007)错误,原因是安装软件时,没有管理员权限。 解决安装出现1006(1007)的方案:先卸载软件,卸载完成以后,安装下面的步骤安装 第一步:以管理员命令打开 DOS命令窗口 第二步:msiexec /package mysql软件所在的路径, 比如:msiexec /package D:\soft\mysql-5.5.36-win32.msi 注意: mysql数据库服务器软件 和 数据库 和 表 和 数据(表记录)关系: 1. 先有mysql数据库软件。 2. 在数据库软件上面,创建多个数据库(对应文件夹) 比如:mysql , performance_schema, test 3. 在数据库里面,创建多张表(对应的文件) 4. 在表(二维表格)里面,管理表记录(数据) 表区分表结构 和 表记录: ==表结构:表头(表的字段)和字段对应的类型(数据类型) ==表记录:表头(字段)对应的值 5. sql指令(掌握)5.1 sql概述什么是sql: 是一种结构化查询语言(sql不仅能从查询,还能进行添加,删除和修改操作)。 通俗的讲:sql就是一套规则(一套语法),通过sql对数据库进行查询 添加 删除和修改(crud)操作。 5.2 sql常见的分类---四类Ø DDL :数据库定义语言,作用创建数据库和数据表以及修改数据库和数据表(表结构) Ø DCL: 数据库控制语言,作用给数据库和数据表进行授权操作(了解) Ø DML: 数据库操作语言,作用对表中的记录(数据)进行添加 ,修改 删除操作。 Ø DQL: 数据库查询语言,作用:对表中的记录进行查询操作。 5.3 sql操作数据库和表== DDL 创建数据库和数据表(表的结构)以及修改等操作。关键词:create ,drop , alter DDL的sql语句:truncate table 表名 == DML: 操作表记录(数据) u 添加数据: insert into u 修改数据:update u 删除数据: delete == DQL: 查询表记录l 基础查询 l 条件查询 A. *模糊条件查询 B. *分组条件查询 C. *排序条件查询 D. *子查询 E. *聚合函数查询 注意:
1.字段 ,列名称,表头 ,都表示一个意思,都是表的Field 2.字符集,编码格式,编码表,都表示一个意思,都是编码 常见的编码: n utf-8:万能的码表,支持所有的字符。 n gbk,gb2312,gb18030: 中文的码表,支持中文,还支持其它字符,但不包含日文,韩文等字符 n iso-8859-1:西欧的码表,支持西欧的字符,但不支持日文,韩文,中文等字符 day03-mysql1. 单表查询(掌握)1.0 模糊查询基本语法:where 字段 like ‘ %或者使用_’; 字符: % 表示任意字符(0-N个字符),_ 表示一个任意字符。 1.1 条件查询 ==字段 between 值1 and 值2 等同于 字段>=值1 and 字段<=值2 ==字段 in(值1,----,值n) 等同于 字段=值1 or 字段=值2,--- ==is null 如果值为null,不能使用=,要使用is null ==is not null 值不为null 1.2 排序查询 基本语法:-------- order by 字段 desc (asc) 1.3聚合函数查询n * sum(score) n *avg(score) n *count(score) n *max(score) n *min(score) 注意: 1. 聚合函数里面的参数:表的字段 2. 聚合函数在进行运算是,null值不参与运算。 3. 聚合函数一般是对int类型的进行运算,其它类型没有意义。 4. 特别在使用count(字段) 字段一般是主键字段(非空,唯一), 1.4 分组查询==基本语法:group by 分组字段 注意: 1. 分组字段数据 要有 共同特点。 2. 分组查询时, select 分组字段,聚合函数 from ---- 分组字段 和 聚合函数都具有共同特点 ==查询 操作时,关键词的先后顺序: 1. select 字段 2. from 表名 3. where 分组前条件判断 4. group by 分组字段 5. having 分组后的条件判断 6. order by 排序字段 1.5分页查询:分页:数据太多,一次性查询出来完,展示效果不好,就是用户的体验不好。 分页操作,不同的数据库分页基本原理不一样: mysql: limit 进行分页,其它数据库不能使用limit进行分页。 基本语法: limit 参数1,参数2: 参数1 :数据的起始位置(索引),从0 开始,表示第1条记录 参数2 :每页显示的具体记录的个数。 规律 : 参数1 = (参数2-1)* 参数2 1.6综合案例(作业)sql脚本: -- 员工表 CREATE TABLE `employee` ( `empno`int(11) NOT NULL, `ename`varchar(50) DEFAULT NULL, `job`varchar(50) DEFAULT NULL, `mgr`int(11) DEFAULT NULL, `hiredate`date DEFAULT NULL, `sal`decimal(7,2) DEFAULT NULL, `COMM`decimal(7,2) DEFAULT NULL, `deptno`varchar(11) DEFAULT NULL, PRIMARY KEY(`empno`), KEY`fk_emp` (`mgr`), CONSTRAINT`fk_emp` FOREIGN KEY (`mgr`) REFERENCES `emp` (`empno`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO emp VALUES (1009, '曾阿牛', '董事长', NULL, '2001-11-17',50000, NULL, 10); INSERT INTO emp VALUES (1004, '刘备', '经理', 1009,'2001-04-02', 29750, NULL, 20); INSERT INTO emp VALUES (1006, '关羽', '经理', 1009,'2001-05-01', 28500, NULL, 30); INSERT INTO emp VALUES (1007, '张飞', '经理', 1009,'2001-09-01', 24500, NULL, 10); INSERT INTO emp VALUES (1008, '诸葛亮', '分析师', 1004,'2007-04-19', 30000, NULL, 20); INSERT INTO emp VALUES (1013, '庞统', '分析师', 1004,'2001-12-03', 30000, NULL, 20); INSERT INTO emp VALUES (1002, '黛绮丝', '销售员', 1006,'2001-02-20', 16000, 3000, 30); INSERT INTO emp VALUES (1003, '殷天正', '销售员', 1006,'2001-02-22', 12500, 5000, 30); INSERT INTO emp VALUES (1005, '谢逊', '销售员', 1006,'2001-09-28', 12500, 14000, 30); INSERT INTO emp VALUES (1010, '韦一笑', '销售员', 1006,'2001-09-08', 15000, 0, 30); INSERT INTO emp VALUES (1012, '程普', '文员', 1006,'2001-12-03', 9500, NULL, 30); INSERT INTO emp VALUES (1014, '黄盖', '文员', 1007,'2002-01-23', 13000, NULL, 10); INSERT INTO emp VALUES (1011, '周泰', '文员', 1008,'2007-05-23', 11000, NULL, 20);
练习题: -- 查询 薪水介于 8000到16000之间的 员工 的姓名 和 工作 ,薪水(两种方式) SELECT ename , job,sal FROM emp WHERE sal>=8000 AND sal<=16000; SELECT ename , job,sal FROM emp WHERE sal BETWEEN 8000 AND 16000; -- 查询 受雇日期是 2000-12-17,2001-02-20 的员工姓名和受雇日期(两种方式) SELECT ename,hiredate FROM emp WHERE hiredate = '2000-12-17' OR hiredate='2001-02-20'; SELECT ename,hiredate FROM emp WHERE hiredate IN ('2000-12-17' ,'2001-02-20'); -- 查询 工作不是文员的 薪水总和 SELECT SUM(sal) FROM emp WHERE job!='文员'; -- 查询受雇日期 早于 2007-05-23的 员工的薪水总和 SELECT SUM(sal) FROMemp WHEREhiredate <'2007-05-23'; -- 查询 每一种工作的薪水总和 SELECT job,SUM(sal) FROM emp GROUP BY job; -- 查询 工作不是文员的每一种工作的薪水总和 SELECT job,SUM(sal) FROM emp WHERE job !='文员' GROUP BY job; -- 查询 查询受雇日期 早于 2007-05-23的 员工 ,并且按照部门分组,查询每个部门的薪水总和 SELECT SUM(sal),deptno FROM emp WHERE hiredate < '2007-05-23' GROUP BY deptno -- 查询 查询受雇日期 早于 2007-05-23的 员工 ,并且按照部门分组,查询每个部门的薪水总和,且部门的总薪水大于25000 SELECT SUM(sal),deptno FROM emp WHERE hiredate<'2007-05-23' -- 分组前条件 GROUP BY deptno -- 分组字段 HAVING SUM(sal)>95000 -- 分组后条件,只有分完组后,才能求每个部门的总薪水 -- 查询 查询受雇日期 早于 2007-05-23的 员工 ,并且按照部门分组,查询每个部门的薪水总和,且部门的总薪水大于25000,最终按照总薪水的大小进行降序排列 SELECT SUM(sal),deptno FROM emp WHERE hiredate<'2007-05-23' -- 分组前条件 GROUP BY deptno -- 分组字段 HAVING SUM(sal)>95000 -- 分组后条件,只有分完组后,才能求每个部门的总薪水 ORDER BY SUM(sal) DESC;-- 对最终符合条件的数据,进行排序 2. 约束(掌握)2.1约束概述:一种规范(限制),数据库约束就是对表中的数据进行规范,让数据具有某种特点。 2.2数据库的约束分类:l 主键约束 l 非空约束 l 唯一约束 l 外键约束 2.3 外键约束:==外键作用:让表与表建立关系(关联性),保证数据的有效性和正确性。 ==外键特点: 1. 外键的值不能随意写。 2. 外键的值引用于另一张表的主键值 3. 外键的值可以为null(但是为null,没有任何意义) ==外键设计原则:n 主表 n 子表 多表之间的关联关系: l 一对一 比如: 用户表 和 信息表 主表(子表)可以是任意一方。 -- 一对一:用户表和信息表 -- 分析:一个用户一个手机号,可以利用主键的唯一特点,可以把任何一方的主键设计成外键 -- 1. 用户表 CREATE TABLEtab_user( uidINT PRIMARY KEY, usernameVARCHAR(32) ); -- 2.信息表 CREATE TABLE tab_info( info_idINT PRIMARY KEY, phoneVARCHAR(11), CONSTRAINTinfo_user FOREIGN KEY(info_id) REFERENCES tab_user(uid) );
l 一对多(多对一) 比如:部门表和员工表 主表:一方表,这里指的就是部门表 子表:多方表,这里指的就是员工表 外键设计在子表里面。 -- 一对多的关联(多对一) 外键的设计原则:外键放在多表里面 -- 1.设计一方表(主表) CREATE TABLE tab_dept( didINT PRIMARY KEY, dnameVARCHAR(23) ); -- 2. 设计多方表(子表),外键在多方表里面 CREATE TABLE tab_emp( eidINT PRIMARY KEY, enameVARCHAR(32), dept_idINT ,-- 外键:让 tab_emp 和 tab_dept CONSTRAINTemp_dept FOREIGN KEY(dept_id) REFERENCES tab_dept(did) );
l 多对多(通俗来说,强化版 的 一对一) 比如:学生表和课程表 主表(子表)可以是任意一方(不推荐这样区分 和设计外键) 外键设计原则:提供一张中间表 。 -- 多对多: 学生和课程 ,设计原则 提供一张中间表 来关联 学生和课程 -- 1. 设计多方表 学生 CREATE TABLEtab_stu( sid INT PRIMARY KEY, snameVARCHAR(32) ); -- 2. 设计多方表 课程 CREATE TABLE tab_course( cidINT PRIMARY KEY, cnameVARCHAR(32) ); -- 3. 提供中间表:tab_stu_course CREATE TABLE tab_stu_course( s_id INT ,-- 外键,来关联 tab_stu c_id INT, -- 外键,来关联 tab_course CONSTRAINT s_c_1 FOREIGN KEY(s_id) REFERENCEStab_stu(sid), CONSTRAINT s_c_2 FOREIGN KEY(c_id) REFERENCEStab_course(cid) );
案例:黑马旅游商城项目-----设计多表之间的关联 设计表: l 用户表:tab_user l 旅游分类表:tab_category l 旅游线路(产品)表: tab_route l 用户收藏旅游线路表:tab_favorite 表与表之间的关联关联: l tab_user 和 tab_favorite : 一对多 l tab_category 和tab_route : 一对多 l tab_favorite 和 tab_route: 多对多 淘宝商城项目,设计表与表之间关联 l 用户表: tab_taoUser l 商品分类表: tab_taoCategory l 商品表: tab_taoProduct l 购物车表:tab_taoCart == 级联操作(了解)u 级联操作概述:只有表与表之间有关联关系,才能进行级联操作。 作用:当主表的数据发生变化时,那么子表的数据会级联发生变化。 u 级联操作:一般情况下,操作是对update和delete. Ø 分两种情况: 第一种情况:当主表的数据变化时,子表的数据和主表的数据保持一致。 语法: on update cascade on delete cascade 第二种情况:当主表的数据变化时,子表的数据(外键的数据)设置为null. 语法:on update set nullon delete set null. 3. 多表关联(掌握)
3.2 表的关联关系l 一对一(了解) 比如:人和身份证,用户表和身份证表 l 一对多(多对一) 比如:商品分类和商品,分类表和商品表 l 多对多 比如:老师和学生,学生和课程 4. 数据库的设计范式(了解)
5. 数据库的备份和还原(简单) day04-mysql1. 多表的查询(掌握)1.1 概述:多个表放在一起查询。 出现问题:出现笛卡尔积(就是出现的无用数据) 解决方法:消除不合理的数据(笛卡尔积) 通过主键和 外键 关联(因为外键的值 引用于主键的值)。 1.2 连接分类l 内连接 消除无效数据条件:外键的值=主键的值 l 外连接 *左外连接 *右外连接 消除无效数据条件:外键的值=主键的值 l 子查询 子查询的情况 第一种情况:子查询作为一个值(单行单列) 比如:salary = (select max(salary) from emp) 第二种情况:子查询作为一个数组(多行单列) 比如:dept_id in (SELECT id FROM dept where name in(‘销售部’,‘公关部’) ) 消除无效数据条件:外键的值=主键的值 子查询常见的错误: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOMEsubquery' 错误原因:子查询(subquery)不支持limit和in一块使用。 第三种情况:子查询作为一个表(多行多列的) ==案例(作业):l 内连接的sql练习题: -- 查询 员工和部们的信息 SELECT * FROM emp e,dept d WHERE e.dept_id = d.id; -- 查询 员工姓名 ,部门编号 ,部门编号,部门名称 SELECT e.name,e.dept_id, d.id,d.name FROM emp e,dept d WHERE e.dept_id = d.id; -- 查询 入职日期 早于2011年的员工姓名 ,以及所在的部门编号,部门名称 SELECT e.join_date,e.name,e.dept_id, d.id ,d.name FROM emp e,dept d WHERE e.dept_id = d.id ANDe.join_date<'2011'; -- 查询 不是 开发部的员工姓名 和 部门名称 SELECT e.name,d.name FROM emp AS e, dept AS d WHERE e.dept_id = d.id ANDd.name<>'开发部' -- 查询 没有部门的员工姓名 和部门编号 SELECT NAME,dept_id FROM emp WHERE dept_id IS NULL -- 查询 有部门的员工姓名,部门编号 和 部门名称 SELECT e.name,e.dept_id,d.id,d.name FROM emp e ,dept d WHERE (e.dept_id IS NOT NULL)AND (e.dept_id = d.id) 2. 事务(了解)== 事务的概述:是一组操作,这一组操作是不可以分割的单元,要不一起成功,或者一起失败 == 事务的四大特性: l 原子性 l 持久性 l 隔离性 l 一致性 == 事务的三大读问题 l 脏读: 一个事务读到了另一个事务未提交的数据 l 不可重复读(虚读):在一次事务中,前后读取的数据不一样。 l 幻读 == 事务的四大隔离级别(解决上面的三大读问题) l read uncommitted:读未提交 解决:什么问题都没解决。 l read committed: 读已提交 解决:脏读 l repeatable read: 可重复读 解决:脏读,不可重复读 l serializable: 串行化 解决:所有问题都已经解决。 3. SQL分类:DCL(了解或不了解)
day05-jdbc今天的知识点介绍: l JDBC概述 l JDBC常用的api l JDBC工具类的封装 l 综合案例:通过jdbc对数据库进行crud操作 l 事务操作:通过jdbc完成事务的操作 jdbc常见的异常: l java.sql.Exception: Accessdenied for user ‘root@localhost’(use password yes): 提示数据库的用户名或者密码错误。 一.jdbc(掌握)1. jdbc概述原理:jdbc其实就是一套规范(接口),不同的数据库厂商实现这一套规范,通过jdbc一套规范,操作不同的数据库。 jdbc的一套接口:java.sql.* 不同的数据库厂商实现一套接口: //mysqlConnectionmysql数据库厂商提供的实现类 //Connection 就是sun官方提供的接口,通过操作接口,去调用相关的实现类的方法 // java.sql.Connection 接口 ,实现类:com.mysql.jdbc.MySqlConnection(mysql数据库提供的) public MySqlConnection implements java.sql.Connection{ ---------- } 操作Connection(多态): Connection con = new MySqlConnection(); 2. jdbc的apil 1.java.sql.DriverManager(类) 作用1:注册驱动(不用),推荐使用:Class.forName(“com.mysql.jdbc.Driver”) 作用2:获取Connection con =getConnection(url,user,password); l 2.java.sql.Connection(接口) l 3.java.sql.Statement(接口) l 4.java.sql.PreparedStatment(接口) l 5.java.sql.ResultSet(接口) 3.案例<1>添加,删除,修改操作:² 存在的问题: 代码有冗余(重复度太高) ² 解决问题方案:可以把重复的代码提取出来,封装一个方法或者一个类。 ² 冗余代码: 1. 第一部分:从注册驱动到获取连接对象,这些代码都是冗余 2. 第二部分:每次关闭资源(connection,statement),这些代码也是冗余 package cn.itheima.utils; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /* 解决:代码的冗余问题 1.从加载驱动到获取连接对象 2.关闭资源 */ public class JDBCUtils { //工具类:简单方便 //1.提供一个方法: 获取连接对象 public staticConnection getMyConnection() throwsException { //0.加载驱动 Class.forName("com.mysql.jdbc.Driver"); //1.直接通过DriverManager String url = "jdbc:mysql://localhost:3306/day04_mysql_moretab";// http://www.baidu.com:80 String user="root"; String password="root"; Connection con = DriverManager.getConnection(url,user,password); return con; } //2.提供一个关闭资源的方法:closeResource // Connection, Statement public staticvoid closeResource(Statement stmt,Connection con) throwsException { //1.关闭statement if(stmt!=null){ stmt.close(); } //2.关闭Conn if(con!=null){ con.close(); } } }
上面的工具类: 问题1:获取连接对象的四个参数写死了。 *原因:四个参数写死了,后期在开发中,如果更换任意一个参数,需要修改源码,这种操作是不被允许的。 *细节:在开发中,遵循一个OOP原则。 OOP原则:对代码的修改时关闭的,对代码的扩展是开放的。 *解决方案: 步骤一:把四个连接参数配置到properties文件 步骤二:通过读取配置文件的四个参数获取连接对象。 /** * * @author Administrator *1.需要把四个连接参数配置到properties *2.通过读取配置文件,获取四个参数,得到连接对象了 *步骤一:1.在src下面创建一个config.properties */ public class JDBCUtlis2 { //为了避免每次都加载配置文件,获取四个连接参数,需要把这些操作放在静态代码块(只加载一次) private staticString driver=null; private staticString url=null; private staticString user=null; private staticString password=null; static{ try{ //----读取配置文件,获取四个连接参数 //创建Properties对象 Properties pro= new Properties(); //获取配置文件的字节输入流,让pro对象加载 ClassLoader loader=JDBCUtlis2.class.getClassLoader(); InputStream in= loader.getResourceAsStream("config.properties"); pro.load(in); driver=pro.getProperty("driverUrl"); url= pro.getProperty("urla"); user=pro.getProperty("usera"); password=pro.getProperty("passworda"); }catch(Exceptione){ e.printStackTrace(); } } //1.提供一个方法: 获取连接对象 public staticConnection getMyConnection() throwsException { //0.加载驱动 Class.forName(driver); //1.直接通过DriverManager Connection con = DriverManager.getConnection(url,user,password); return con; } //2.提供一个关闭资源的方法:closeResource // Connection, Statement public staticvoid closeResource(Statement stmt,Connection con) throwsException { //1.关闭statement if(stmt!=null){ stmt.close(); } //2.关闭Conn if(con!=null){ con.close(); } } public staticvoid main(String[] args) throwsException{ getMyConnection(); } } day06-jdbc今日内容:(全部掌握) l 数据库连接池 l 小框架(组件)spring的模版类:JDBCTemplate(crud操作) 1. 数据库连接池: DataSource ConnectionPool== 概述: 存储和管理Connection对象的容器,这个容器称之为数据库连接池 优点: 1. 不用每次都创建连接对象,可以从数据库连接池取 2. 在没有数据库连接池时,使用完connection以后,释放connection(销毁) 如果送数据库连接池里面取connection使用,使用完以后,归还给数据库连接池。 == 常见的数据库连接池: l C3P0: 数据库连接池技术: ComboPooledDataSource 注意细节: 配置文件的名称必须是c3p0,并且放在src下面,所以在代码实现里不需要指出配置文件,因为会自动查找到。 l Druid: 数据库连接池技术(温少) 注意:配置文件的名称和位置没有要求,在代码实现里面,需要指出配置文件的路径并且加载配置文件。 l 数据库连接分析: Ø 数据库连接池,初始化连接connection,需不需要导入数据库驱动包? 回答:除了数据库连接池自身的jar以外,使用哪种数据库,需要导入数据库的jar包 Ø 数据库连接池:需不要自己初始化(创建)connection ,存到池里面? 回答:需要自己初始化连接对象,初始化的配置在配置文件里面。 Ø 数据库连接池,初始化连接connection,需不需要四个连接参数? 回答:需要四个连接参数(driverClass,jdbcUrl ,user ,password)在配置文件里面
2.spring提供的模版类:JDBCTemplate ===模版类概述: 本质也是类,作用操作数据库,非常简单方便。 为什么这么简单方便? 原生的jdbc代码操作数据库时 1.加载驱动-->2.获取连接-->3.编写sql-->4.执行sql语句的对象-->5.执行sql处理返回值-->6.释放资源 模板类代码操作数据库时 编写sql-->加载驱动-->获取连接-->执行sql处理返回值-->释放资源
|