mysql常用命令、库操作汇总
MySQL
数据库(DataBase,DB):指长期保存在计算机的存储设备上,按照一定规则组织起来,可以被各种用户或应用共享的数据集合。(7文件系统)
数据库管理系统(DataBase Management System,DBMS):指一种操作和管理数据库的大型软件,用于建立、使用和维护数据库,对数据库进行统一管理和控制,以保证数据库的安全性和完整性。用户通过数据库管理系统访问数据库中的数据。
数据库软件应该为数据库管理系统,数据库是通过数据库管理系统创建和操作的。
数据库:存储、维护和管理数据的集合。
1登录Mysql: mysql -u root -p abc
2* 卸载
1.停止mysql服务 ??net stop mysql ??????启动mysql服务 ?net start mysql
2.卸载mysql
3.找到mysql 安装目录下的 my.ini ??datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
3* 修改密码
运行cmd
* 安装成功了打开cmd ?--> mysql -uroot -p你的密码
* 修改mysql root用户密码
1) 停止mysql服务 运行输入services.msc 停止mysql服务
或者 cmd --> ?net stop mysql
2) 在cmd下 输入 mysqld --skip-grant-tables 启动服务器 光标不动 (不要关闭该窗口)
3) 新打开cmd 输入mysql -u root -p 不需要密码
use mysql;
update user set password=password('abc') WHERE User='root';
4) 关闭两个cmd窗口 在任务管理器结束mysqld 进程
5) 在服务管理页面 重启mysql 服务
密码修改完成
数据库中一行记录与对象之间的关系。 列:字段 行:一条记录(实体) ?这样就很方便用java语言获取数据
public class User{ private int id; private String name; private int age; }
三、sql概述 SQL:Structure Query Language。(结构化查询语言)
4、Sql的分类
DDL**(Data Definition Language):数据定义语言,用来定义数据库对象:库、表、列等; CREATE create、 ALTER alter、DROP drop
DML***(Data Manipulation Language):数据操作语言,用来定义数据库记录(数据); ??? INSERT insert、 UPDATE update、 DELETE delete
DCL(Data Control Language):数据控制语言,用来定义访问权限和安全级别;
DQL*****(Data Query Language):数据查询语言,用来查询记录(数据)。
1库--操作4
1增3 创建 create ?语法 ?create database 数据库名 [character set 字符集][collate ?校对规则]
(database/databases 关键字只在对数据库的操作时见到)
create database mydb1;
Create database mydb2 character set gbk;
Create database mydb3 character set gbk collate gbk_chinese_ci;
2删1 drop
前面创建的mydb3数据库 Drop database mydb3;
3改1??这里改动的是字符集 ?alter
查看服务器中的数据库,并把mydb2的字符集修改为utf8; alter database mydb2 character set utf8;
4查4 show 4
?1查看当前数据库服务器中的所有数据库show databases;
?2查看前面创建的mydb2数据库的定义信息:查数据库创建语句 Show create database mydb2;
?3查看当前使用的数据库 语法select database();
5切换数据库use mydb2;
2表--操作4
在创建表之间一定要指定数据库. use 数据库名 ???最后一个字段不加 逗号
*语法:
create table 表名(
字段1 字段类型,
字段2 字段类型,
...
字段n 字段类型
);
1 常用数据类型:10
int:整型
float:浮点型:float(5,2)--> 999.99, -999.99 表示浮点型数长度为5 小数位为2 ?一般不需要这样指定长度。
double:浮点型,例如double(5,2)表示最多5位,其中必须有2位小数,即最大值为999.99;
char:固定长度字符串类型; char(10) ?'abc ??????' ??申请的速度快 ?但是费内存
varchar:可变长度字符串类型;varchar(10) 'abc' ?这个与char相比较 ?比如给定的长度是10 ?但是就用了5 那5个就会不分配 省内存
text:字符串类型;
blob:字节类型;
date:日期类型,格式为:yyyy-MM-dd;
time:时间类型,格式为:hh:mm:ss
timestamp:时间戳类型 yyyy-MM-dd hh:mm:ss ?会自动赋值
datetime:日期时间类型 yyyy-MM-dd hh:mm:ss-
decimal(7,2), 数的长度是7,有两位是小数点
2 约束种类4
1 not null; 非空 ??
2 unique;唯一约束, 后面的数据不能和前面重复
3 primary key;主键约束(非空+唯一); ?id:作为数据的唯一标识,通常给id int类型设置主键约束,auto_increment ?null
4 auto_increment;自动增长列 ,一定是和主键一起使用的。
3 增1
2.1.创建表 对表结构的操作(table/tables关键字只会出现在对表结构的操作sql语句中)
不能创建同名称的表 ??创建表的时候必须有字段 ??没字段就是一个空表 没有意义
删除表 ?要是删除表的最后一个字段 ?只能用drop删除 ??用删除列的方式不能删除表的最后一个字段 那样那个表就是一个空表了 没有意义
create table student(
id int primary key auto_increment,
name varchar(10),
score double,
address varchar(10)
);
添加主建约束的方式
第一种添加方式:第一种添加方式:此种方式优势在于,可以创建联合主键
CREATE TABLE student(Id int primary key,Name varchar(50));
第二种添加方式:
CREATE TABLE student(id int, Name varchar(50), Primary key(id) );
CREATE TABLE student(id int,Name varchar(50),Primary key(id,name));
第三种添加方式:
CREATE TABLE student(Id int,Name varchar(50)); ALTER TABLE student ??ADD ?PRIMARY KEY (id);
创建 索引
普通索引 ??添加INDEX
ALTER TABLE `table_name` ADD INDEX index_name ( `column` ) ?这是修改然后加上索引
直接通过create index的方式
CREATE FULLTEXT INDEX ft_email_name ON `student` (`name`)
也可以在创建索引的时候指定索引的长度:
CREATE FULLTEXT INDEX ft_email_name ON `student` (`name`(20)) 直接创建索引
?
主键索引 ??添加PRIMARY KEY
ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
唯一索引 ???添加UNIQUE
ALTER TABLE `table_name` ADD UNIQUE ( `column` )
全文索引 ???添加FULLTEXT
ALTER TABLE `table_name` ADD FULLTEXT ( `column`)
如何添加多列索引
ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
?
4 删1
1 删除表 drop table 表名;
5 改4 add ?change大 ?modify小 rename
?1增加列 alter table 表名 add 字段名 类型(长度) 约束;
?2修改字段 名称 类型 约束。alter table 表名 change 旧字段名 新字段名 类型 约束; 换成同一个名字也可以
?3修改列的类型和约束 alter table 表名 modify 字段名 类型 约束;
?4删除列 alter table 表名 drop 字段名;
?5 修改表名 rename table 旧表名 to 新表名
6 查3
1 查看当前数据库下的所有表show tables; ??显示所有的表名字
2 查看当前数据库某个表的结构 desc 表名; 显示表中 所有的字段 和属性
3 查看employee的表结构 ?show create table employee
3 数据--操作4 增改都不出现table
1增2
1增加数据 insert into 表名(字段1,字段2,字段3) values(值1,值2,值3);
2 insert into 表名 values(值1,值2,值3,值4);有几个字段就有几个值,如果不想给字段赋值,也要写空
注意:
- 没有赋值的列,系统自动赋为null
- 列名与列值的类型、个数、顺序要一一对应。
- 值不要超出列定义的长度。
- 如果插入空值,请使用null
- 插入的日期和字符串,使用引号括起来
2删2 delete where
1 delete from star;删除数据(一次至少删除一条数据,不能删除某条数据的某个字段) delete from 表名 [where 条件];不写条件表示将所有数据全部删除 ?表结构还在;删除后的数据可以找回
2 trancate 表名;删除表,trancate table star;并新建一张一样结构和名字的该表。
区别 - DELETE 删除表中的数据,表结构还在;删除后的数据可以找回
- TRUNCATE 删除是把表直接DROP掉,然后再创建一个同样的新表。删除的数据不能找回。执行速度比DELETE快。
3改1 update set where
1更新数据 update 表名 set 字段1=值1,字段2=值2 [where 条件];不写条件表示将所有数据字段1的值改成值1,字段2的值改成值2
?可以写成 ??字段1= 字段1+2000; 可以是+-*/ ??但是不能是+= ??前面的类型只能是数 ?要是字符串只显示后面的数值
日期查询
定义和用法
DATE_FORMAT() 函数用于以不同的格式显示日期/时间数据。
语法
DATE_FORMAT(date,format)
date?参数是合法的日期。format?规定日期/时间的输出格式。
可以使用的格式有:
格式 |
描述 |
%a |
缩写星期名 |
%b |
缩写月名 |
%c |
月,数值 |
%D |
带有英文前缀的月中的天 |
%d |
月的天,数值(00-31) |
%e |
月的天,数值(0-31) |
%f |
微秒 |
%H |
小时 (00-23) |
%h |
小时 (01-12) |
%I |
小时 (01-12) |
%i |
分钟,数值(00-59) |
%j |
年的天 (001-366) |
%k |
小时 (0-23) |
%l |
小时 (1-12) |
%M |
月名 |
%m |
月,数值(00-12) |
%p |
AM 或 PM |
%r |
时间,12-小时(hh:mm:ss AM 或 PM) |
%S |
秒(00-59) |
%s |
秒(00-59) |
%T |
时间, 24-小时 (hh:mm:ss) |
%U |
周 (00-53) 星期日是一周的第一天 |
%u |
周 (00-53) 星期一是一周的第一天 |
%V |
周 (01-53) 星期日是一周的第一天,与 %X 使用 |
%v |
周 (01-53) 星期一是一周的第一天,与 %x 使用 |
%W |
星期名 |
%w |
周的天 (0=星期日, 6=星期六) |
%X |
年,其中的星期日是周的第一天,4 位,与 %V 使用 |
%x |
年,其中的星期一是周的第一天,4 位,与 %v 使用 |
%Y |
年,4 位 |
%y |
年,2 位 |
实例
下面的脚本使用 DATE_FORMAT() 函数来显示不同的格式。我们可以使用 NOW() 来获得当前的日期/时
将数据库中存放的年月日时分秒字符串如20150119221048转换为2015-01-19 22:10:48
[sql]?view plain?copy?print?
1.?select??seq_no,show_mode,dev_id,dev_type,dev_attr,content_attr,???
2.?????????content_path,file_name,date_format(start_time,?'%Y-%m-%d?%H:%i:%s'),date_format(end_time,?'%Y-%m-%d?%H:%i:%s'),???
3.?????????regular_time,order_level,operator_level,order_state?from??order_execute_info??????
4.?????????where?dev_type?=?'0011'?order?by?dev_id?asc;??
?
?
?
4查11 select ?from where like
注意: 聚合函数前面不能有字段名,除非是用于分组的字段名 ??聚合函数不能用在 where后面
语法:先后顺序select [列名,列名] [*] [聚合函数][distinct 字段] from 表名 [WHERE --> group by -->having--> order by] ??
?
?
?
SQL UNION 操作符
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。
SQL UNION 语法
SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2
注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SQL UNION ALL 语法
SELECT column_name(s) FROM table_name1
UNION ALL
SELECT column_name(s) FROM table_name2
另外,UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
使用 UNION 命令
实例
列出所有在中国和美国的不同的雇员名:
SELECT E_Name FROM Employees_China
UNION
SELECT E_Name FROM Employees_USA
UNION ALL
UNION ALL 命令和 UNION 命令几乎是等效的,不过 UNION ALL 命令会列出所有的值。
?
?
?
字段1 表示显示那个字段
顺序: select...from...where...group by...having...order by
from 表名 [where 条件]----->[group by 字段]----->[having 条件(分组后的条件)]----->[order by];
先分组 分组后聚合函数统计每组的数量
有分组 字段哪里就不能写*号
1 查询所有的列的记录 ?????select * from 表名;
2 查询某张表特定列的记录??select 字段名1,字段名2 from 表名;
3 去重查询 (distinct 字段) ??select distinct 字段名 from 表名; ?去重字段名只能写一个 ?要是,字段名2 ??后面的字段只是显示出来不具有去重原理
这是筛选某个字段重复 ?去除重复记录(两行或两行以上记录中系列的上的数据都相同) 上面可以多个字段,查询多个字段的值不同时重复
例如- 把年龄重复的给筛选 ?要查询的字段的数据一模一样才能去重
4 ?别名查询 (字段 as ?别名, as可以省略)??select 字段名1 as 姓名 from 表名; ?可以写多个 ?但是必须带引号
只是为了展示得更容易看懂一点,其实没啥作用- 查询明星名称和价格,明星价格通过别名‘身价’来显示
5 运算查询(+,-,*,/等)??select 字段名+10 ?from 表名; - 把明星名称,
和明星年龄+10查询出来 要是字符串+10 就只显示后面的10 没有意义运算查询字段字段之间是可以的?显示要求的新字段
6 条件查询7都是在where后面用的
l?注意 between...and...: 包含临界值 eg: between 3000 and 6000相当于: 3000<=price<=6000
l?1 In ??2 between and ?3 is null ?is not null ???4 and ?5 or ??6 not ?7通配符 like ?’%_’
l?- 查询id在1,5,10,15范围内的明星 select * from star where id in(1,5,10,15)
7 模糊查询,like和通配符一起使用: %;多位(0~n)_; 一位
8 排序; order by 列名 asc(默认升序可以不写) ?desc(降序)???????排序语句放在查询语句的最后面!
????1 Order by price 直接升序 ??order by price asc, age; ?2先升序 如果价格一样 按照age升序 ???3 order by asc, age desc; ?先升序如果价格一样按照 age 降序
?
9 聚合函数?(聚合函数前不能有字段名,如果一定要有,那么该字段名只能是用来分组的字段名)聚合函数是用来做纵向运算的函数 ?
如果前面有字段了只显示第一个字段的值 后面显示筛选值, ?后面可以有 as “最大值”
1.?count(*|字段);统计指定列不为NULL的记录行数 ??????,
2.?如果要统计表中的总记录数,那么count( *|不能为空的字段名)
3.?sum();计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0
4.?max();筛选指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算 abc的排序
5.?min();筛选指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算 如果有2个最小值一样 就显示出来第一个
6.?avg();计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0
10 分组查询,单独使用group by,只显示各个组的第一条数据()
?- group by结合group_concat()使用,可以展示每一组的数据集合,group_concat()中不能写*
??- select type,group_concat(name) from start group by type;分组查询select后面一定要跟上分组的字段名
解释 type 表示显示分组后 第一个name字段的 type ?????group_concat(name) 多显示组 这组字段为group_concat(name) 把所有人的姓名显示出来
查询所有的明星,按照type分组
select * from star group by type; ?//只显示每组中的第一条信息
select type,group_concat(*) from star group by type; //错误的写法
Select name from star group by type ?// 显示每组中的第一个姓名
select type,group_concat(name) from star group by type; //显示每组中每个人的姓名
?
- group by结合聚合函数使用(聚合函数前写得字段名必须是用于分组的字段名) ??用聚合函数都是用于数理统计的数, ?字段类型都是数据类型
??- 统计每一组的数据个数 ?select type,count(*) from product group by type;
??- 统计每一组的数据的总价格 ?select type,sum(price) from product group by type;
??- 统计每一组的数据中价格最小的那个 ???select type,min(price) from product group by type;
- 根据明星类别分组,统计不同明星类别的个数
- 根据明星类别分组,统计不同明星类别的总价格
11 分组后筛选(having)
- 根据明星类别分组,统计不同明星类别的个数,并且该明星类别数量大于2的
注意:
- having是分组后筛选
where和having的区别
- 1.having是在分组后对数据进行过滤.where是在分组前对数据进行过滤
- 2.having后面可以使用聚合函数(统计函数)where后面不可以使用聚合函数
- 3.having后面加的条件一定要与分组有关。
-?4.WHERE是分组前记录的条件,如果某行记录没有满足WHERE子句的条件,那么这行记录不会参加分组;而HAVING是对分组后数据的约束。
?
自己 Select *, price>3000 from star1; 查询 身价大于3000的 后面会加一行 ??前面加的这个price>3000 是自加字段 这是一个boolean值 ?数据都显示的boolea值
?
比如:
一般条件放到 where后面 ?需要分组后的条件放到 having后面
select type,count(*) from star group by type having count(*)>2;
?分组后统计 每组的长度大于2
select type,count(*) from star where count(*)>2 group by type;
?Where后面不能加聚合函数 ?这个错误
select type,count(*) from star where age>30 group by type;
先把大于30岁的筛选出来再分组
select type,count(*) from star group by type having age>30;
自己理解 这个是年龄>30岁和这个分组没有关系 ?相当于冲突了 ?这个错误 ??一般后面跟聚合函数 ?与分组有关的条件
这样加的条件就和后面的没有关系了
小知识:
在mysql中,字符串类型和日期类型都要用单引号括起来。'tom' ?'2015-09-04'
空值:null
?
语法:
SELECT selection_list /*要查询的列名称*/
??FROM table_list /*要查询的表名称*/
??WHERE condition /*行条件*/
??GROUP BY grouping_columns /*对结果分组*/
??HAVING condition /*分组后的行条件*/
??ORDER BY sorting_columns /*对结果分组*/
??LIMIT offset_start, row_count /*结果限定*/
?
4 数据的完整性3
作用:保证用户输入的数据保存到数据库中是正确的。确保数据的完整性 = 在创建表时给表中添加约束
完整性的分类:> 实体完整性 ?> 域完整性 ?> 引用完整性
1、实体完整性
实体:即表中的一行(一条记录)代表一个实体(entity) 实体完整性的作用:标识每一行数据不重复。
约束类型: 主键约束(primary key) ?唯一约束(unique) ?自动增长列(auto_increment)
给主键添加自动增长的数值,列只能是整数类型,但是如果删除之前增长的序号,后面再添加的时候序号不会重新开始,而是会接着被删除的那一列的序号
CREATE TABLE student(Id int primary key auto_increment,Name varchar(50));
INSERT INTO student(name) values(‘tom’);
2、域完整性
域完整性的作用:限制此单元格的数据正确,不对照此列的其它单元格比较域代表当前单元格
域完整性约束:数据类型 非空约束(not null) 默认值约束(default) Check约束(mysql不支持) check();
1.1 数据类型:(数值类型、日期类型、字符串类型)1.2 非空约束:not null
1.3 默认值约束 default
CREATE TABLE student(Id int pirmary key,Name varchar(50) not null,Sex varchar(10) default ‘男’);
insert into student1 values(1,'tom','女');
insert into student1 values(2,'jerry',default);
3、引用完整性 添加外键
表和表之间存在一种关系,但是这个关系需要谁来维护和约束?
1外键约束外键作用:??保证引用完整性,也就是说数据的准确
注意??外键列的类型一定要和参照的主键的类型一致
l?1 省略外键名字 系统会自动为外键起名字 - alter table 表 add [constraint?外键名] foreign key(字段) references 表(字段);
l?2 给外键起一个名字 alter table product add constraint fk_p2c foreign KEY (p_pno) references category(c_cno);
l?3 删除外键去除关系 alter table product drop foreign key fk_p2c;
l?3 要是没有写外键名字 就要到数据库操作软件里面去找(资料) 外键的名字 ??然后删除
l?3 创建数据库的时候外键的名字不能相同
- 给商品表添加外键? alter table product add foreign key(cno) references category(cid);
1一对多(掌握) ?在多的一方创建一个字段作为外键,指向一的一方主键
2多对多(掌握) ?新建一张第三方表,至少包含两个字段,都作为外键,分别指向各自的主键
3一对一(了解) ?先当做一对多,在外键字段添加唯一约束。
5多表查询6
1?交叉查询???若干表没有条件的连接在一起
select a.*,b.* from a,b ;或者 select *from a,b;- 交叉查询其实是一种错误.数据有很多无用数据,叫笛卡尔积.
- 假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。可以扩展到多个集合的情况。
- 交叉查询产生这样的结果并不是我们想要的,那么怎么去除错误的,不想要的记录呢,当然是通过条件过滤。通常要查询的多个表之间都存在关联关系,那么就通过关联关系去除笛卡尔积。
2?内连接查询(重点)
1 隐式内连接select a.*,b.* from a,b where 连接条件 或者:select * from a, b where 连接条件
2 显示内连接select a.*,b.* from a [inner] join b on 连接条件或者:select *from a [inner] join b on 连接条件 where 其它条件
- 使用主外键关系做为条件来去除无用信息.抓住主外键的关系,用主外键作为连接条件 ?b表里面的外键=a表里面主键
- 显示里面的,on只能用主外键关联作为条件,如果还有其它条件,后面加where
3 外连接(重点)
1左外连接 以join左边的表为主表,展示主表的所有数据,根据条件查询连接右边表的数据,若满足条件则展示,若不满足则以null显示
select a.*,b.* from a left [outer] join b on 条件??或者: select *from a表 left [outer] join b表 on 条件
2右外连接 以join右边的表为主表,展示它的所有数据,根据条件查询join左边表的数据,若满足则展示,若不满足则以null显示
select a.*,b.* from a right [outer] join b on 条件?或者:??select *from 表a right [outer] join 表b on 条件
4 子查询?
- 一个select语句中包含另一个完整的select语句。
- 子查询就是嵌套查询,即SELECT中包含SELECT,如果一条语句中存在两个,或两个以上SELECT,那么就是子查询语句了。
1步骤解析??子查询这个iPhone 必须是唯一 ?否则产生错误, 子查询可以和 内外连接一起使用
- 第一步:查询Iphone5s的商品价格select price from product where pname = 'Iphone5';
- 第二步:查询价格高iPhone5s的商品信息 select *from product where price >(第一步语句作为条件)
2 例子
- 查询和方便面是同一类别的商品信息 SELECT *from product where cno = (SELECT cno from Product where pname ='方便面') and pname <> '方便面';
- 查询类别是手机数码的所有商品信息 select *from product where cno = ?(SELECT cid FROM category where cname ='手机数码');
5 联合查询(了解)
- 合并结果集就是把两个select语句的查询结果合并到一起
1语法- union:去除重复记录,例如:SELECT * FROM t1 UNION SELECT * FROM t2
- union all:不去除重复记录,例如:SELECT * FROM t1 UNION ALL SELECT * FROM t2
6 分页查询(掌握)
Limit优点 ??查到需要多少页数的数据后 ?就不再向后查询
- limit a,b; - a:从哪里开始(从0开始计数的)?偏移量 - b:一页显示数据的数量 ??固定值 前端或者安卓,ios
????a = (curPage-1)*b;// curPage当前页数 ?
一页显示3条数据: ?第1页: a = 0; b ?= 3;
第2页: a?= 3; b = 3;
第3页:a = 6; ?b ?= 3;
第四页:a=9,b=3.
8 JDBC的概念?day10
学习目的 ; 1自己创建jdbcUtils ??2用dbcp创建 dbcpUtils ???3用C3p0创建 C3P0Utils ??4直接使用框架DBUtils 操作数据库
在上面建的类都是?有这三个方法 ??1注册驱动 ?2获得链接 ??5关闭资源?
*单一职责、开放封闭、依赖倒置、迪米特法则、里氏替换、接口隔离
1 什么是JDBC - JDBC:java database connectivity sun公司为了简化和统一java连接数据库,定义的一套规范(API)
2 JDBC和数据库驱动的关系 - 接口(JDBC)与实现(驱动jar包)的关系
1开发第一个JDBC程序`开发步骤
① - 注册驱动(要引入驱动jar包)
1 registerDriver(Driver driver) ;注册驱动,Driver类中包含一个静态代码块
翻阅源码发现,通过API的方式注册驱动,Driver会new两次,所有推荐这种写法: Class.forName("com.mysql.jdbc.Driver");
② - 获得连接
1.2 getConnection(String url, String user, String password) ;与数据库建立连接
Jdbc:mysql://localhost:3306/web06_1; ??jdbc;协议 mysql:子协议 localhost:主机名 3306:端口号 web06_1:数据库名 ??eg:https://www.baidu.com
③ - 创建执行sql语句的对象
- 接口的实现在数据库驱动中。所有与数据库交互都是基于连接对象的。
2.1createStatement() ;创建执行sql语句对象
2.2prepareStatement(String sql) ;创建预编译执行sql语句的对象?.setInt(1,1) 设置第一个问号 ??setString(2,”李四”)设置第二个问号 ?setnull(3,null) 设置第三个问号为null
④ - 执行sql语句,处理结果
.java.sql.Statement接口
- 接口的实现在数据库驱动中
- 操作sql语句,并返回相应结果对象
1 ?Statement; 执行sql语句对象
- ResultSet ?executeQuery(String sql) 根据查询语句返回结果集。只能执行select语句。
- int executeUpdate(String sql) 根据执行的DML(insert update delete)语句,返回受影响的行数。
- boolean execute(String sql) ?此方法可以执行任意sql语句。返回boolean值,表示是否返回的是ResultSet结果集。仅当执行select语句,且有返回结果时返回true, 其它语句都返回false;
2 得到结果集 java.sql.ResultSet接口 封装结果集,查询结果表的对象?用循环while 得到结果
- 提供一个游标,默认游 ????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????指向结果集第一行之前。 把所有查询结果放到这个盒子里面 这是个集合或者什么 - 调用一次next(),游标向下移动一行。
- 提供一些get方法。
4.2ResultSet接口常用API
- boolean next() ;将光标从当前位置向下移动一行
- int getInt(int colIndex)以int形式获取ResultSet结果集当前行指定列号值
- int getInt(String colLabel)以int形式获取ResultSet结果集当前行指定列名值
- float getFloat(int colIndex)以float形式获取ResultSet结果集当前行指定列号值
- float getFloat(String colLabel)以float形式获取ResultSet结果集当前行指定列名值
- String getString(int colIndex)以String 形式获取ResultSet结果集当前行指定列号值
- String getString(String colLabel)以String形式获取ResultSet结果集当前行指定列名值
- Date getDate(int columnIndex); ?以Date 形式获取ResultSet结果集当前行指定列号值
- Date getDate(String columnName);以Date形式获取ResultSet结果集当前行指定列名值
⑤ - 关闭资源
- void close()关闭ResultSet 对象
2单元测试介绍
1. 介绍:JUnit是一个Java语言的单元测试框架。属于第三方工具,一般情况下需要导入jar包,不过,多数Java开发环境 已经集成了JUnit作为单元测试工具
2. 编写测试类,简单理解可以用于取代java的main方法
3. 在测试类方法上添加注解@Test
4. 注解修饰的方法要求:public void 方法名() {…} ,方法名自定义建议test开头,没有参数。
5 添加eclipse中集成的Junit库,鼠标点击“@Test”,使用快捷键“ctrl + 1”,点击“Add Junit …”
6 使用:选中方法右键,执行当前方法;选中类名右键,执行类中所有方法(方法必须标记@Test)
7 常见使用错误,如果没有添加“@Test”,使用“Junit Test”进行运行,将抛异常
1 @Test 一定要写,并且就是@Test ?2方法一定要是public ?3不要返回值
?
3增强版本
1注册驱动加强
静态代码块 ?只要改类加载(改类种有语句运行,就运行这个)
1修改发现源码也是注册驱动这是这个代码 防止驱动开两次 就用反射 DriverManager.registerDriver(new Driver()); Class.forName("com.mysql.jdbc.Driver");
2执行sql语句的加强
2发现用Statement执行sql代码的时候 ?当输入的有 or id=1 ?就能正常通过 ??说明这个可以重改你的sql代码
String str = "select * from star1 where name='"+username+"'and price='"+password+"'";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(str);
ResultSet resultSet = statement.executeQuery(str);
?
prepareStatement这个类extend Statement 类 这个首先把sql代码预编译 每个问号都是占位符 ?用户不能修改sql语句 ?这连个都是接口
String str = "select * from star1 where name= ? and price= ?";
PreparedStatement prepareStatement = connection.prepareStatement(str);
prepareStatement.setString(1, username);
prepareStatement.setInt(2, 5000);
ResultSet resultSet = prepareStatement.executeQuery();
3硬编码读取配置文件
1用字节流 2用类加载器 都是读到properties对象种 ??3种是直接从包下得到资源包 ?都是key value的形式
在静态块中来读流,读取配置文件中的数据
Properties properties = new Properties();
将数据加载进properties对象
1第一种读取配置文件的方法加载到properties中 (只能在java工程中用,对于web工程路径要改变)
FileInputStream in = new FileInputStream(new File("src/jdbcconfig.properties"));
2 第二种读取配置文件的方法 ?获取类的加载器只能用于获取src下面的文件
ClassLoader classLoader = JDBCUtil.class.getClassLoader();
InputStream ?in = classLoader.getResourceAsStream("jdbcconfig.properties"); ?//得到资源把资源转化成流
properties.load(in); ?//从输入流中读取到properties里面
要从properties对象中获取数据
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
driverStr = properties.getProperty("driverStr");
3第三种读取配置文件的方法 ?只能用于获取src下面的 以.properties结尾的文件
ResourceBundle bundle = ResourceBundle.getBundle("jdbcconfig");
url = bundle.getString("url");
user = bundle.getString("user");
password = bundle.getString("password");
driverStr = bundle.getString("driverStr");
9 JDBC连接池
1.为什么使用连接池重写工具类
- Connection对象在JDBC使用的时候就会去创建一个对象,使用结束以后就会将这个对象给销毁了.每次创建和销毁对象都是耗时操作.需要使用连接池对其进行优化.程序初始化的时候,初始化多个连接,将多个连接放入到池(集合)中.每次获取的时候,都可以直接从连接池中进行获取.使用结束以后,将连接归还到池中.
.0队列和堆栈的区别
- 队列:先进先出,从头部移出数据,从尾部添加数据。吃了拉出来 - 堆栈:后进先出,从尾部添加数据,从尾部移出数据。吃了吐出来
1装饰着
1 编写连接池条件:1.装饰者和被装饰者实现的是同一个接口(或者继承了同一个类) 2.装饰者里面要拿到被装饰者类的引用
自己理解: 同一个父亲 ??1里面一个子类有全套的实现方法 ????2另一个子类改变第一个子类的某个方法 ??达到不同的效果
2 装饰着的理解: 把类1中的参数传到 类2中(这种传递的是引用类型,是实参,两个类公用的同一个参数,无论那个类里面对这个参数进行更改,这两个类都的参数都更改)
3 传参问题?直接匿名函数有参构造传值, ?2个功能 ?1向集合里面添加对象, 2匿名对象传对象, 3匿名对象传 本身增加的集合
现在传输的是个实际参数 ?是地址值 ??不管前后加了多少 ?我那个类里面就有多少. ??目的只是传输的地址值 不是传输的数量
4 使用连接池的步骤编码
//声明一个连接池,存放连接
static LinkedList
//类加载完毕,池子中就会有5个连接
static{
for(int i=0;i<5;i++){
try {
pool.add(new MyConnection(JDBCUtil.getConnection(), pool));
} catch (SQLException e) {
e.printStackTrace();
}
}
}
5 编写连接池遇到的问题
- 如果新建了connection,用完之后怎么判别是原池子中的connection(需要放回去),还是新建的connection(需要销毁)。
解决办法(自定义一个Connection,重写close方法)
- 继承 条件:可以控制父类的构造
- 装饰者模式 目的:改写已存在的类的某个方法或某些方法,装饰设计模式(包装模式)
1. 编写一个类实现一个接口,为被包装类
2. 编写一个类,实现与被包装类相同的接口。(具备相同的行为)
3. 定义一个被包装类类型的变量。
4. 定义构造方法,把被包装类类的对象注入,给被包装类变量赋值。
5. 对于不需要改写的方法,调用被包装类类原有的方法。
6. 对于需要改写的方法,写自己的代码。
- 动态代理
2 datasource接口概述
- Java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商(用户)需要让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池! - 常见的连接池:DBCP、C3P0。 ??自己写用DriverManager 自己创建链接 ???用连接池就用DataSource
3 DBCP 增删改查
1使用步骤 ???总共有3个类组成 ??
1测试执行sql语句类
2 自己创建的DBCPUtil类 用于创建链接 得到连接池 ?关闭资源
3 DBCPUtil jar包导入两个
:Apache推出的Database Connection Pool 核心API: - basicDatasource - basicDatasourceFactory
2老师使用步骤
1- 添加jar包 ?commons-dbcp-1.4.jar ?commons-pool-1.5.6.jar
2- 添加配置文件到src目录
3- 编写数据源工具类
????4.1通过配置文件来编写public class DBCPUtils {
static DataSource ds;
static { //只需要初始化一次
try {
Properties properties = new Properties();
ClassLoader classLoader = DBCPUtil.class.getClassLoader();
InputStream in = classLoader.getResourceAsStream("dbcpconfig.properties");
properties.load(in);
//得到dbcp对象
ds= BasicDataSourceFactory.createDataSource(properties);
} catch (xception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 创建连接
public static Connection getConnection() throws SQLException {
return ds.getConnection;
}
// 释放资源
public static void release(ResultSet resultSet, Statement statement, Connection connection) {
}
4.2 通过硬编码来表写(不需要配置文件.了解一下)
DataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
basicDataSource.setUrl("jdbc:mysql://localhost:3306/day01_1");
basicDataSource.setUsername("root");
basicDataSource.setPassword("123456");
4 C3P0 增删改查
开源免费的连接池!目前使用它的开源项目有:Spring、Hibernate等。使用第三方工具需要导入jar包,c3p0使用时还需要添加配置文件c3p0-config.xml
只要创建对象 就自动读取配置文件
1使用步骤 4
1- 添加jar包
2- 编写配置文件c3p0-config.xml,放在src中(注:文件名一定不要写错)
3. 通过配置文件来编写 ?创建c3p0对象 ?对象自动会寻找读取配置文件 ??3创建对象
public class C3P0Utils {
//1创建一个连接池对象 自动链接里面的c3p0-config.xml文件
static DataSource ds = new ComboPooledDataSource();
//2从池中获得一个连接
public static Connection getConnection() throws SQLException{
return ds.getConnection();
}
//3释放资源
public static void closeAll(ResultSet rs,Statement stmt,Connection conn){
}
3 通过硬编码来编写(不需要配置文件.了解一下)
DataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass("com.mysql.jdbc.Driver"); // loads the jdbc driver
cpds.setJdbcUrl("jdbc:mysql://localhost:3306/day01_1");
cpds.setUser("root");
cpds.setPassword("ai1996");
5 DBCP与C3P0区别优缺点
: dbcp线程池不能自动获取配置文件 ?要用上面3种方法读取 ??C3P0能自动读取 ?C3P0更强大
6 DBUtils完成CRUD
1 概述
1. DBUtils是java编程中的数据库操作实用工具,小巧简单实用。 第一个操作数据库框架(jar),
2. DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码。
3. Dbutils三个核心功能介绍
?
QueryRunner中提供对sql语句操作的API. ?update(), query()
ResultSetHandler接口,用于定义select操作后,怎样封装结果集.
DbUtils类,它就是一个工具类,定义了关闭资源与事务处理的方法
?
3.2QueryRunner核心类
- QueryRunner(DataSource ds) ,提供数据源(连接池),DBUtils底层自动维护连接connection
- update(String sql, Object... params) ,执行更新数据 insert update delete ?参数就是一个数组,参数个数取决于语句中?的个数
- query(String sql, ResultSetHandler
- batch(sql, object[][] params) 批量添加数据 ??把数据写到二维数组中 ?每个一维数组 为每一行数据--update是只增加一个数据
?
3.3ResultSetHandler结果集处理类
Handler类型说明 ?????????????????????????????????????
ArrayHandler ???? 将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值
ArrayListHandler 将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。
BeanHandler?????? 将结果集中第一条记录封装到一个指定的javaBean中。 ???????????
BeanListHandler?? 将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中
ColumnListHandler 将结果集中指定的列的字段值,封装到一个List集合中 ?????????????
KeyedHandler将结果集中每一条记录封装到Map
MapHandler ???将结果集中第一条记录封装到了Map
MapListHandler 将结果集中每一条记录封装到了Map
ScalarHandler???它是用于单个数据。例如select ?count(*) from 表操作。
2使用步骤
1获取线程池对象(c3p0,dbcp)创建对象
2 获取dbutils对象 ?创建dbutils对象 直接把线程池传递过去
3 写sql语句 底层用prepareStatement查询 String sql = "select nickname from user where id=?"; Object[] param = {7};
4 用dbutils对象的方法 操作数据库
1当更新时 用update ??返回int类型 ?受影响的行数
l?1 new beanListHardler<>(User.class) ?查多列 就是集合(不管这个列里面有多少个数据)
l?2 New beanHardler<>(User.class) ????查一列 ?就是一个对象接收
l?3 New ScalarHardler() ?????????????查一个数据 ?用obje查询 ct 变量接收
注意当你写的查询语句 是多列 ?一列 ?一个 可以分别使用上面三个查询语句 并接受 从大到小都没有错 ?当查询多列用一个变量接收就只得到一个
?
10 Xml和反射
1 XML文档声明
Web.xml中servlet标签和servlet-mapping标签中的servlet-name值应该一致,否则启动服务器会抛出异常
1.文档声明必须为结束;2.文档声明必须从文档的0行0列位置开始;
3.文档声明只有三个属性:
a)versioin:指定XML文档版本。必须属性,因为我们不会选择1.1,只会选择1.0;
b)encoding:指定当前文档的编码。可选属性,默认值是utf-8;
c)standalone:指定文档独立性。可选属性,默认值为yes,表示当前文档是独立文档。如果为no表示当前文档不是独立的文档,会依赖外部文件。
2元素
1.元素是XML文档中最重要的组成部分,2.元素体:元素体可以是元素,也可以是文本,例如:你好
3.空元素:空元素只有开始标签,而没有结束标签,但元素必须自己闭合,例如:
4.元素命名:
a)区分大小写
b)不能使用空格,不能使用冒号:
c)不建议以XML、xml、Xml开头
6.良好的XML文档,必须有一个根元素。
3 属性
1.属性是元素的一部分,它必须出现在元素的开始标签中
2.属性的定义格式:属性名=属性值,其中属性值必须使用单引或双引
3.一个元素可以有0~N个属性,但一个元素中不能出现同名属性
4.属性名不能使用空格、冒号等特殊字符,且必须以字母开头
l注释 XML的注释与HTML相同,即以“”结束。注释内容会被XML解析器忽略!
l转义字符 XML中的转义字符与HTML一样。
因为很多符号已经被XML文档结构所使用,所以在元素体或属性值中想使用这些符号就必须使用转义字符,例如:“<”、“>”、“’”、“””、“&”。
l5 转译多个 CDATA区
3 DTD重点要求
开发中,我们很少自己编写DTD约束文档,通常情况我们都是通过框架提供的DTD约束文档,编写对应的XML文档。常见框架使用DTD约束有:struts2、hibernate等。 通过提供的DTD“web-app_2_3.dtd”编写XML
4元素声明
空格 ?表示有没有都可以
定义元素语法:
元素名:自定义
元素描述包括:符号和数据类型
常见符号:? * + () | ,
常见类型:#PCDATA 表示内容是文档,不能是子标签
?
5属性声明
属性的语法:
属性名 属性类型 约束
属性名 属性类型 约束
...
>
元素名:属性必须是给元素添加,所有必须先确定元素名
属性名:自定义
属性类型:ID、CDATA、枚举 …
ID : ID类型的属性用来标识元素的唯一性
CDATA:文本类型
枚举:(e1 | e2 | ...) 多选一
约束:
#REQUIRED:说明属性是必须的;
#IMPLIED:说明属性是可选的;
l实例
给web-app元素添加 version属性,属性值必须是文本,且可选。
6 Schema约束
1.2.3.1什么是Schema
Schema是新的XML文档约束;
Schema要比DTD强大很多,是DTD 替代者;
Schema本身也是XML文档,但Schema文档的扩展名为xsd,而不是xml。
Schema 功能更强大,数据类型更完善
Schema 支持名称空间
2 DOM4j框架使用步骤
1获取单个和多个标签
SAXReader reader =new SAXReader(); //1得到dom4j的对象
Document read = reader.read("src/book.xml");//2根据对象 读取xml到dom中
Element root = read.getRootElement(); //3得到根目录 String name = root.getName(); //获取跟目录的名字
1得到多个子标签
List
Iterator iterator = root.elementIterator(); //4得到根目录下的所有子目录迭代器
Iterator iterator = root.elementIterator("书"); ?得到根目录下所有的书 子标签 ?
2得到一个多级子标签
Element element = (Element) root.selectSingleNode("/书架/书[2]/作者"); ?得到一个多级子标签
3得到多个多级标签
List
List
2操作属性
1获取属性值 ??根据属性名 ?获取属性值
Attribute attribute = element.attribute("出版社"); ?//获取属性名
String value = attribute.getValue();//获取属性值
Object data = attribute.getData();
3操作文本
1获取文本 element2.getText()
String text = root.element("报纸").element("新闻").getText(); ?//从多级标签中 ?得到文本
String elementText = element.elementText("书名"); ?从标签 直接得到文本
3 反射
作用
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法。通过反射甚至可以调用到private方法。
- 生成动态代理
1 获得字节码的3种
1种方式 * 第一种获取类的字节码对象方式 ?使用object里面的getClass()方法
?* 通过对象名.getClass()获取 不常用 你都不知道对象名是什么 ?怎么建对象 能建对象也就不用用反射了
Person p = new Person();
Class clazz = p.getClass(); //获取到正在运行的类的字节码对象\
2种方式 * 通过类名.class获取
Class clazz = Person.class;
3种方式 通过Class类的静态方法.forName(包名.类名); ?* 应用: 加载数据库驱动的时 ??* 推荐使用:常用
Class clazz = Class.forName("java.lang.String");
2 获取构造方法3
打印出来的构造方法 都是实体的全限定名称 修饰符+ 全类名+参数列表(全称)1 public reflect.Student(java.lang.String,int)?2 public reflect.Student()
1获取所有构造方法??这都是你利用Class里面的方法
//第一步:获取到类的字节码对象
Class clazz = Class.forName("com.heima.domain.Person");
//第二步:调用getConstructors获取类字节码对象的所有构造方法
Constructor
//第三步:遍历构造方法数组
for(Constructor con : cons) {
//System.out.println(con);
System.out.println("构造方法名:" + con.getName());
2 获取单个构造方法 ?这都是你利用Class里面的方法 ?有参数
//第一步:获取类的字节码对象
Class clazz = Class.forName("com.heima.domain.Person");
//第二步:获取有参数构造方法
Constructor
//第三步:创建对象
Object obj = con.newInstance("超哥",18,'男');
//第四步:向下转型
Person p = (Person)obj;
System.out.println(p.getName());
3 获取无参数的构造方法 ?无参数
//第一步:获取类的字节码对象
Class clazz = Class.forName("com.heima.domain.Person");
//第二步:获取构造方法
Constructor
//第三步:使用构造方法对象创建一个对象
Object obj = con.newInstance();
//第四步:向下转型
Person p = (Person)obj;
p.eat(); p.sleep();
4- public Constructor[] getDeclaredConstructors() - 返回此 Class 对象表示的类声明的所有构造方法,包括私有构造方法。
5- public Constructor
?
3 获取对象 操作对象3
1 使用构造方法对象创建一个有参对象 无惨对象 Student student = constructor.newInstance("张三",28);
2通过字节码文件对象创建独享 ??这个只能用字节码对象创建无惨的 对象 ?对于有参的对象都必须用 构造函数去创建
Student student = clazz.newInstance();
4 获取成员变量 操作成员变量3
打印所有的 成员变量 ?打印出来都是全包名 修饰符+全类型+全包名 public java.lang.String com.itheima.reflect.Student.name
对于设置成员变量值 ?可以先判断成员变量是什么类型 再设置什么类型的值 ?判断
1得到所有公共成员变量Field[] field=clazz.getFields() ?- public Field[] getFields() - 返回此Class 对象所表示的实体的所有 成员变量包括继承的。 1得到所有包括私有- public Field[] getDeclaredFields() - 返回此 Class 对象所表示的实体的所有属性,包括私有属性,但不包括继承父类的属性。
2得到成员变量的名- public String getName() ?- 返回此 Class 对象所表示的实体的全限定名称。
l?对于构造方法对象.getName() 得到全类名 reflect.Student ?2对于成员变量 只有名字
3得到成员变量值 Field[] fields = clazz.getFields(); ??Object object = field.get(student);
4设置变量值 ?field.set(student,"李四");
- public String getSimpleName() ?- 返回此 Class 对象所表示的实体的全限定名称。
5获取方法 操作方法4
1得到所有的公有方法- public Method[] getMethods() - 返回此 Class 对象所表示的实体的所有公共属性,包括父类的。
1得到所有的方法包括私有- public Method[] getDeclaredMethods() - 返回此 Class 对象表示的实体的所有方法,包括私有方法,但不包括继承父类的方法。
1获取指定公有方法- public Method getMethod(String name, Class... parameterTypes) - 返回此 Class 对象所表示的实体的指定公共成员方法,- name 指定方法名称,parameterTypes指定方法参数类型 字节码文件类型 例如 ?Method method = clazz.getMethod("sayHello", String.class,int.class);
1获取指定私有方法 方法名为study ???Method method2 = clazz.getDeclaredMethod("study");
?
2调用方法 method2.invoke(clazz.newInstance()); 对于调用的是静态的方法 括号里面可以写(null) 静态方法调用不用对象
?
3去除方法的私有权限调用方法method2.setAccessible(true);然后调用方法 method2.invoke(clazz.newInstance());
?
4得到方法名method.getName ??????if (method.getName().equals("show"))
- public Class[] getInterfaces() - 确定此 Class 对象所表示的类实现的接口。
后面几个几乎用不到
- public ClassgetSuperclass() - 返回此 Class 对象所表示的实体的超类的 Class。
- public Package getPackage() ?- 获取此类的包。 【String [Package].getName()】
- public int getModifiers() ?- 返回此类或接口以整数编码的 Java 语言修饰符。
?【String Modifier.toString(int)】
- public boolean isArray() ?- 判定此 Class 对象是否表示一个数组类。
- public ClassgetComponentType() ?- 返回表示数组组件类型的 Class。
成员变量(Field)获取和设置
- get(Object o); - 得到具体对象的该属性的值
- set(Object o, Object value); - 设置具体对象的该属性的值
方法(Method)调用 - invoke(Object o,Object... args) - o是调用该方法的对象,args是调用该方法时传入的参数