Struts2
Servlet
小的Java程序,运行在服务器端,接收和响应从客户端发送过来的请求
流程分析:
Servlet生命周期?
Servlet配置自动加载?(理解)
1.服务器在启动的时候,Servlet实例不会被创建的!第一次访问的时候才会创建Servlet的实例对象。
2.通过一种配置文件,让Tomcat服务器在启动的时候就创建Servlet的实例对象
* 在<servlet>标签的中间添加一段配置
* <load-on-startup>0或者值是正整数</load-on-startup>
3.值越小,优先级越高!
Action访问Servlet API有哪几种方式,简单的介绍一下?
1.在Action类中也可以获取到Servlet一些常用的API,有如下三种方式获取
* 完全解耦合的方式
* 使用接口注入的方式
* 使用ServletActionContext中静态方法直接访问Servlet的API
* 需求:提供JSP的表单页面的数据,在Action中使用Servlet的API接收到,然后保存到三个域对象中,最后再显示到JSP的页面上。
* 提供JSP注册的页面,演示下面这三种方式:
<h3>注册页面</h3>
<form action="${ pageContext.request.contextPath }/xxx.action" method="post">
姓名:<input type="text" name="username" /><br/>
密码:<input type="password" name="password" /><br/>
<input type="submit" value="注册" />
</form>
2.完全解耦合的方式
* 如果使用该种方式,Struts2框架中提供了一个类,ActionContext类,该类中提供一些方法,通过方法获取Servlet的API
* 一些常用的方法如下:
* static ActionContext getContext() -- 获取ActionContext对象实例
* java.util.Map<java.lang.String,java.lang.Object> getParameters() -- 获取请求参数,相当于request.getParameterMap();
* java.util.Map<java.lang.String,java.lang.Object> getSession() -- 获取的代表session域的Map集合,就相当于操作session域。
* java.util.Map<java.lang.String,java.lang.Object> getApplication() -- 获取代表application域的Map集合
* void put(java.lang.String key, java.lang.Object value) -- 注意:向request域中存入值。
3.使用接口注入的方式
* Struts2框架中提供了一些接口,编写的Action类可以是去实现这些接口,然后实现这些接口中的方法,这些方法都是把一些Servlet的常用对象通过参数的方式传递进来。
* 常用的接口如下:
* ServletRequestAware -- 注入request
* ServletContextAware -- 注入ServletContext
* ServletResponseAware -- 注入response.
4.使用ServletActionContext中静态方法直接访问Servlet的API
* Struts2框架提供了一个类,ServletActionContext,该类中提供了一些静态的方法
* 具体的方法如下
* getPageContext();
* getRequest()
* getResponse();
* getServletContext();
①.方式一:使用ActionContext对象(在Action中解耦合方式间接访问Servlet API)
在struts2中Action API已经与Servlet API 解耦合(没有依赖关系),开发简单,便于测试。
Servlet API 常见操作 : 表单提交请求参数获取,向request、session、application三个范围存取数据
②.方式二:使用接口注入的方式操作Servlet API(藕合)
通过Aware接口,在构造Action时,自动注入需要操作Servlet对象(需要哪个对象就实现哪个Aware接口)
③.方式三:在Action中直接通过 ServletActionContext 获得Servlet API
静态方法返回request,不会有线程问题(使用了ThreadLocal来实现的)
总结:理论来说,第一种方式最好,实现了解耦和,但是第三种我们使用最为简单,企业中没有很大的限制,自己熟悉哪种就使用哪种。
Struts2详细运行流程
从图15可以看出,一个请求在Struts2框架中的处理大概分为以下几个步骤:
1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求;
2、这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin);
3、接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求是否需要调用某个Action;
4、如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy;
5、ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类;
6、ActionProxy创建一个ActionInvocation的实例。
7、ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8、一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper。
请求首先通过Filter chain,Filter主要包括ActionContextCleanUp,它主要清理当前线程的ActionContext和Dispatcher;FilterDispatcher主要通过AcionMapper来决定需要调用哪个Action。
ActionMapper取得了ActionMapping后,在Dispatcher的serviceAction方法里创建ActionProxy,ActionProxy创建ActionInvocation,然后ActionInvocation调用Interceptors,执行Action本身,创建Result并返回,当然,如果要在返回之前做些什么,可以实现PreResultListener。
部分类介绍
①ActionMapper
ActionMapper其实是HttpServletRequest和Action调用请求的一个映射,它屏蔽了Action对于Request等java Servlet类的依赖。Struts2中它的默认实现类是DefaultActionMapper,ActionMapper很大的用处可以根据自己的需要来设计url格式,它自己也有Restful的实现,具体可以参考文档的docs\actionmapper.html。
②ActionProxy&ActionInvocation
Action的一个代理,由ActionProxyFactory创建,它本身不包括Action实例,默认实现DefaultActionProxy是由ActionInvocation持有Action实例。ActionProxy作用是如何取得Action,无论是本地还是远程。而ActionInvocation的作用是如何执行Action,拦截器的功能就是在ActionInvocation中实现的。
③ConfigurationProvider&Configuration
ConfigurationProvider就是Struts2中配置文件的解析器,Struts2中的配置文件主要是尤其实现类XmlConfigurationProvider及其子类StrutsXmlConfigurationProvider来解析。
Struts2请求流程
1、客户端发送请求
2、请求先通过ActionContextCleanUp-->FilterDispatcher
ActionContextCleanUp:主要清理当前线程的ActionContext和Dispatcher
3、FilterDispatcher通过ActionMapper来决定这个Request需要调用哪个Action
4、如果ActionMapper决定调用某个Action,FilterDispatcher把请求的处理交给ActionProxy,这儿已经转到它的Delegate--Dispatcher来执行
5、ActionProxy根据ActionMapping和ConfigurationManager找到需要调用的Action类
6、ActionProxy创建一个ActionInvocation的实例
7、ActionInvocation调用真正的Action,当然这涉及到相关拦截器的调用
8、Action执行完毕,ActionInvocation创建Result并返回,当然,如果要在返回之前做些什么,可以实现PreResultListener。添加PreResultListener可以在Interceptor中实现。
源代码分析
①启动服务器(tomcat)将会自动加载配置文件,加载过程如下:
服务器启动,init()方法被执行
②客户端初始化一个指向Servlet容器(WEB容器)的请求;
③这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:(SiteMesh Plugin)。
④接着StrutsPrepareAndExecuteFilter被调用,StrutsPrepareAndExecuteFilter询问ActionMapper来决定这个请求是否需要调用某个Action。
⑤如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy。ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类
⑥ActionProxy创建一个ActionInvocation的实例。ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。拦截器默认执行<default-interceptor-ref name="defaultStack"/>defaultStack里面有一系列的interceptor。
⑦一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2框架中继承的标签。在这个过程中需要涉及到ActionMapper,响应的返回是通过我们在web.xml中配置的过滤器
⑧如果ActionContextCleanUp是当前使用的,则FilterDispatecher将不会清理threadlocal ActionContext;如果ActionContextCleanUp不使用,则将会去清理threadlocals。
Jquery easyui
UI框架采用jquery easyui
优点:
使用方法:
1.在jsp或html中加入css、js。
2.定义布局。
组件介绍:
Layout组件:实现页面布局。
Accordion组件:实现菜单折叠效果。
其中调用accordion的add方法实现动态添加折叠菜单。
一级菜单使用accordion的title。
二级菜单使用自定义的html。
Tabs组件:实现打开多个标签窗口。
Tab必须使用js去渲染组件,渲染div。
效果:
注意:
在tab标签中显示iframe,iframe要比frameset灵活,可以放在body中任意位置!!
实现欢迎页面:
进入first.jsp,自动添加一个tab。tab的内容就是一个欢迎页面。
Datagrid组件:实现数据列表。
效果:
弹出窗口:window
消息提示:messager
数据库(mysql)
概述
1.
数据库:数据仓库,保存数据的。是一个文件系统,也是使用文件的方式来保存数据的,但是访问数据(添加数据据、查询、修改数数据)必须要使用标准SQL语句来访问,操作。
2.
开发任何的应用会有数据库。
3.
学习的都是关系型的数据库,存储都是实体与实体之间的关系。
*
实体:User对象代表就是一个实体。
4.
常见的数据库
* Oracle --
大型的应用,收费的。
* MySQL --
小型的数据库,免费开源的!被Oracle收购了,现在学习都是5.x的版本,但是从6.x版本开始收费了。
* Oracle
(SUN 服务器 Oracle MySQL)
* SQLServer --
微软
* DB2 -- IBM
的公司,银行的企业。
* SyBASE --
应用的比较小,PowerDigener数据库建模的软件。
数据库的SQL语句(CURD)
创建数据库
1.
语法
* create database
数据库名称;(掌握)
* create database
数据库名称 character set 编码;(默认是utf8)
* create database
数据库名称 character set 编码 collate 校对规则;(校对规范也有默认值)
2.
校对规则
*
和编码成对出现的。
*
使用默认的校对就可以了。
3.
练习
*
创建一个名称为mydb1的数据库。
* create database mydb1;
*
创建一个使用utf8字符集的mydb2数据库。
* create database mydb2 character set ‘utf8‘;
*
创建一个使用utf8字符集,并带校对规则的mydb3数据库。
* create database mydb3 character set ‘utf8‘ collate ‘utf8_bin‘;
删除数据库
1.
删除数据库
* drop database
数据库名称;
2.
练习
*
查看当前数据库服务器中的所有数据库
* show databases;
*
查看前面创建的mydb2数据库的定义信息
* show create database mydb2;
*
删除前面创建的mydb1数据库
* drop database mydb1;
修改数据库
1.
修改数据库
* alter database
数据库名称 character set ‘编码‘ collate 校对规则;
查看数据库
1.
显示所有的数据库(掌握)
* show databases;
2.
显示数据库的定义的信息
* show create database
数据库名称;
3.
切换(使用)数据库(掌握)
* use
数据库名称;
4.
查看当前正在使用的数据库
* select database();
表结构的SQL语句(CURD)
创建表结构
1.
创建表的语法
create table
表名(
字段1 字段类型(长度),
字段2 字段类型(长度),
字段3 字段类型(长度)
);
2.MySQL
常用的数据类型(掌握)
*
字符串型(掌握)
* VARCHAR --
代表数据的长度是可变的。假如把username长度设置8,传入一个hello,把字段的长度自动变成5.
* CHAR --
代表数据的长度是不可变的。假如把username使用char(8),传入一个hello,剩余位置使用空格补全。
*
创建表结构
create table table1(
username varchar(20),
password char(15)
);
*
大数据类型(了解)
* BLOB --
字节(mp3 电影 图片)
* TEXT --
字符(文本txt)
*
数值型(掌握)
* TINYINT
* SMALLINT
* INT --
代表int
* BIGINT --
代表long类型
* FLOAT
* DOUBLE
create table table1(
uid int, --
如果省略不写了,默认的长度是11
username varchar(20),
password char(15)
);
*
逻辑性(了解)
* BIT
是1或者0
*
日期型(掌握)
* DATE --
只有日期(年月日)
* TIME --
只有时间(时分秒)
* DATETIME --
有年月日和时分秒,如果传入的null,值就是null
* TIMESTAMP --
有年月日和时分秒(如果传入的值是null,数据库默认获取当前的系统时间,作为值)
3.
创建表结构的练习
create database day05;
use day05;
create table employee(
id int,
name varchar(20),
gender char(5),
birthday date,
entryDate date,
job varchar(30),
sal double,
resume text
);
删除表结构
1.
删除表结构
* drop table
表名称;
修改表结构
1.
添加一个新的字段
* alter table
表名称 add 字段名称 数据类型(长度) 约束;
2.
修改字段的数据类型、长度或者约束
* alter table
表名称 modify 字段名称 数据类型(长度) 约束;
3.
删除某一个字段
* alter table
表名称 drop 字段名称;
4.
修改字段的名称
* alter table
表名称 change 旧字段 新字段 数据类型(长度) 约束;
5.
修改表的名称
* rename table
旧表名 to 新表名;
6.
练习
*
在上面员工表的基本上增加一个image列。
* alter table employee add image varchar(30);
*
修改job列,使其长度为60。
* alter table employee modify job varchar(60);
*
删除gender列。
* alter table employee drop gender;
*
表名改为user。
* rename table employee to user;
*
列名name修改为username
* alter table user change name username varchar(30);
查看表结构
1.
查询所有的表结构,前提条件,先切换到数据库中。
* show tables;
2.
查询表结构的详细的信息
* desc
表名称;
3.
查看表结构定义的信息
* show create table
表名称;
总结:表结构的增删改查
1.
创建表结构
*
语句
create table
表名称(
字段 类型(长度),
字段 类型(长度)
);
2.
查看表
* show tables;
* desc
表名称; -- 查看表的详细的信息
3.
删除表
* drop table
表名称;
4.
修改
* alter table
表名称
* add --
添加列
* modify --
修改某列的类型或者长度或者约束
* drop --
删除某列
* change --
修改字段的名称
* rename table
旧表名 to 新的表名;
数据的SQL语句(CURD)
插入数据(insert)
1.
添加数据,使用insert关键字来添加数据
* insert into
表 (字段1,字段2,字段3) values (值1,值2,值3); -- 向表中的指定的字段中添加值
* insert into
表 values (值1,值2,值3,值4...); -- 向表中的所有的字段添加值
2.
注意实现
*
插入的数据与字段数据的类型相同
*
数据的大小应该在规定的范围内
*
数据中的数据的列的位置和字段位置的相同的
*
字符串和日期类型的数据,必须要使用单引号括起来
3.
向员工表中添加数据 v
* insert into user (username,job) values (‘tom‘,‘it‘);
* insert into user values (2,‘tom2‘,‘2011-12-31‘,‘2015-4-10‘,‘it‘,8000,‘haha‘,‘hehe‘);
* insert into user values (3,‘
美美‘,‘2011-12-31‘,‘2015-4-10‘,‘it‘,8000,‘haha‘,‘hehe‘);
* insert into user values (4,‘
小风‘,‘2001-12-31‘,‘2015-4-10‘,‘it‘,5000,‘haha‘,‘hehe‘);
* insert into user values (5,‘
芙蓉‘,‘1983-12-31‘,‘2015-4-10‘,‘it‘,15000,‘haha‘,‘hehe‘);
* insert into user values (6,‘
熊大‘,‘2001-12-31‘,‘2015-4-10‘,‘it‘,7000,‘haha‘,‘hehe‘);
* insert into user values (7,‘
熊二‘,‘2001-12-31‘,‘2015-4-10‘,‘it‘,500,‘haha‘,‘hehe‘);
插入中文数据乱码
1.
插入中文,会产生乱码的问题。
2.
怎么产生?怎么解决?
*
解决的方案,修改MySQL客户端的编码就可以了。改成GBK
3.
修改MySQL客户端的编码
*
先把MySQL服务器停止
*
找到MySQL安装的路径,找到my.ini的配置文件
*
修改客户端的编码,改成gbk
[client]
port=3306
[mysql]
default-character-set=gbk
*
重启动MySQL的服务
删除数据(delete)
1.
删除语句的语法
* delete from
表 where 条件;
*
如果不加where ,默认删除所有的数据
*
如果添加where条件,删除符合条件的数据
2.
删除所有的数据
* delete from
表;
*
一行一行的数据。
*
支持事务的操作。事务是数据库中的特性。
* truncate
表;
*
先把整个表删除掉(数据也删除了),创建一个与原来一模一样的表。
3.
练习
*
删除表中名称为‘tom‘的记录。
* delete from user where username = ‘tom‘;
*
删除表中所有记录。
*
添加事务
* start transaction;
* delete from user where username = ‘tom2‘;
* rollback;
*
使用truncate删除表中记录。
* truncate user;
修改数据(update)
1.
修改数据,使用update关键字来完成修改数据
* update
表名称 set 字段1=值1,字段2=值2 where 条件;
*
修改字段1和字段2的值
*
如果没有where的关键字,说明修改的默认所有的记录
*
如果有where的关键字,修改的是符合条件的记录
2.
注意
*
如果要是没有where的条件子句,默认是修改所有的数据。
*
如果有where的条件子句,修改的符合条件的数据。
3.
练习
*
将所有员工薪水修改为5000元。
* update user set sal = 5000;
*
将姓名为‘熊大‘的员工薪水修改为3000元。
* update user set sal = 3000 where username = ‘
熊大‘;
*
将姓名为‘熊二‘的员工薪水修改为4000元,job改为ccc。
* update user set sal = 4000,job=‘ccc‘ where username = ‘
熊二‘;
*
将小凤的薪水在原有基础上增加1000元。
* update user set sal = sal + 1000 where username = ‘
小风‘;
查询数据(select)
语法:
* select * from
表; -- 默认查询所有的字段的数据
* select
字段1,字段2,字段3 from 表; -- 查询指定的字段的数据
* DISTINCT --
去除掉重复的关键字
*
可以对查询的列进行运算
*
查询语句中可以使用as的关键字,起别名。
*
别名的真正的用法,采用的多表的查询,为了区分每张表,表起个别名。
* as
的关键字可以省略不写。中间需要使用空格
*
一般都是给表来起别名
* select s.username,s.math from stu s;
* select s.username,u.username from stu s,user u
*
使用where的条件语句,进行查询条件的过滤
练习1:
创建表,做练习
create table stu(
id int,
username varchar(20),
math int,
english int,
chinese int
);
insert into stu values (1,‘
美美‘,18,97,35);
insert into stu values (2,‘
小凤‘,98,97,95);
insert into stu values (3,‘
小花‘,88,90,77);
insert into stu values (4,‘
熊大‘,79,89,95);
insert into stu values (5,‘
熊二‘,15,11,89);
练习2:
*
查询表中所有学生的信息。
* select * from stu;
* select username,math,english,chinese from stu;
*
查询表中所有学生的姓名和对应的英语成绩。
* select username,english from stu;
*
过滤表中重复数据。
* select DISTINCT english from stu;
*
在所有学生分数上加10分特长分
* select username,math+10,english+10,chinese+10 from stu;
*
统计每个学生的总分。
* select username,(math+english+chinese) from stu;
*
使用别名表示学生分数。
* select username,(math+english+chinese) as t from stu;
*
查询姓名为美美的学生成绩
* select * from stu where username = ‘
美美‘;
*
查询英语成绩大于90分的同学
* select username,english from stu where english > 90;
*
查询总分大于200分的所有同学
* select username,(math+english+chinese) from stu where (math+english+chinese) > 150;
* select username,(math+english+chinese) as t from stu where t > 150; --
错误的
where子句后可以使用的符号
1.
常用的符号
* > < <= >= = <>
(不等于)
* in --
代表的范围。
* select * from stu where math = 88; --
查询一条数据,条件是数学=88
* select * from stu where math in (18,88,90); --
查询的结果可能是多条数据,数学的成绩需要在in值的范围内
* like --
模糊查询
* like
关键字的值的写法
* select * from stu where username like ‘
张_‘; -- 使用_占位符,结果:张飞 张三 张X 张翼德(不符合)
* select * from stu where username like ‘
张%‘; -- 使用%占位符,结果是姓张的,张飞 张三 张翼德 只要姓张的都可以。
* like ‘%
张‘; -- 结果:以张结尾的。飞张 医德张 解放路时间分离张
* like ‘%
张%‘; -- 结果:只要包含张就可以 张 张飞 医德张 司法局水利局张是浪费加适量
*
总结like的关键字
*
条件需要使用单引号
*
需要使用占位符
* _ --
代表的一个位置
* % --
代表的多个位置
* and --
与
* or --
或
* not --
非
* between … and
2.
练习
*
查询英语分数在 60-90之间的同学。
* select username,english from stu where english > 60 and english < 90;
* select username,english from stu where english between 60 and 90;
*
查询数学分数为89,90,91的同学。
* select username,math from stu where math in (88,90,91);
*
查询所有姓小的学生成绩。
* select * from stu where username like ‘
小%‘;
*
查询数学分>80,语文分>80的同学。
* select * from stu where math > 80 and chinese > 80;
* select * from stu where math > 80 or chinese > 80;
3.
总结查询的语句
* select
字段1,字段2 | * from 表 where 条件的过滤;
使用order by对结果进行排序
1.
语法
* order by
字段 asc | desc;
* asc --
代表升序(默认值)
* desc --
代表降序
2.
注意
* order by
自己放在select的语句末尾。
* select * from xx where xx order by xx;
3.
练习
*
对数学成绩排序后输出。
* select username,math from stu order by math asc; --
默认是升序
* select username,math from stu order by math desc;
*
对总分排序按从高到低的顺序输出
* select username,(math+english+chinese) from stu order by (math+english+chinese) desc;
* select username,(math+english+chinese) as t from stu order by t desc;
*
对学生成绩按照英语进行降序排序,英语相同学员按照数学降序
* select username,english,math from stu order by english desc,math desc;
* select username,english,math from stu order by english desc,math asc;
*
对姓小的学生语文成绩升序排序输出
* select username,chinese from stu where username like ‘
小%‘ order by chinese asc;
聚集函数
1.
什么是聚集函数:Excel表格。求数量,求和,平均值,最大值,最小值。
2.
聚集函数操作的都是某一列的数据。
3.
聚集函数
* count() --
求数量
* select count(*) | count(
列名) from 表; -- 某一列数据行的总数
*
练习
*
统计一个班级共有多少学生?
* select count(*) from stu;
* select count(id) from stu;
*
统计数学成绩大于90的学生有多少个?
* select count(math) from stu where math > 60;
* select username,count(math) from stu where math > 60; --
不会这样查询
*
统计总分大于220的人数有多少?
* select count(*) from stu where (math+english+chinese) > 220;
* sum() --
求某一列数据的和
* sum
注意:没有sum(*),求的某一列,sum对数值类型起作用。
*
练习
*
统计一个班级数学总成绩?
* select sum(math) from stu;
*
统计一个班级语文、英语、数学各科的总成绩
* select sum(chinese),sum(english),sum(math) from stu;
*
统计一个班级语文、英语、数学的成绩总和
* select sum(chinese)+sum(english)+sum(math) from stu;
* select sum(chinese+english+math) from stu;
*
统计一个班级语文成绩平均分
* select sum(chinese)/count(*) from stu;
*
注意的地方
* sum
函数可以忽略null值。
*
编写一条修改语句
* update stu set math = null where username = ‘
小花‘;
* avg() --
求平均分
* select avg(
字段) from stu;
*
练习
*
求一个班级语文平均分?
* select avg(chinese) from stu;
*
求一个班级总分平均分
* select avg(math+english+chinese) from stu;
*
最大值和最小值
* max() min()
*
练习
*
求班级最高分和最低分
* select max(math+english+chinese) from stu;
* select min(math+english+chinese) from stu;
4.
总结
*
聚集函数,是函数,不要忘记编写()
*
计算都是某一列的数据
*
聚集函数
* count() --
求数量
* sum() --
求和
* avg() --
平均值
* max() --
最大值
* min() --
最小值
分组查询
1.
分组产生效果?聚集函数与分组效果。
2.select * from stu; --
查询所有的数据。默认是一组。
3.
可以使用关键字 group by sex 根据字段进行分组。
4.
练习
create table orders(
id int,
product varchar(20),
price float
);
insert into orders(id,product,price) values(1,‘
电视‘,900);
insert into orders(id,product,price) values(2,‘
洗衣机‘,100);
insert into orders(id,product,price) values(3,‘
洗衣粉‘,90);
insert into orders(id,product,price) values(4,‘
电视‘,900);
insert into orders(id,product,price) values(5,‘
洗衣粉‘,90);
insert into orders(id,product,price) values(6,‘
洗衣粉‘,90);
5.
练习
*
对订单表中商品归类后,显示每一类商品的总价?
* select product,sum(price) from orders group by product; --
已经把原来的一组的数据,现在分成了三组。在统计数据的时候,以组为单位
*
查询购买了几类商品,并且每类总价大于100的商品?
* select product,sum(price) from orders group by product having sum(price) > 100;
*
查询购买了几类商品,并且商品的价格需要大于100,每类总价大于100的商品?
* select product,sum(price) from orders where price > 100 group by product having sum(price) > 100;
*
注意
*
使用where的条件,如果有分组,where的条件是分组之前的条件。
*
新的关键字,having关键字进行分组的条件过滤。
6.
总结
* where
关键字后不能使用聚集函数,而having可以使用聚集函数!!
总结:查询语句
1.
查询的语句
* select ... from ... where ... group by ... having ... order by
单表的约束
主键
1.
可以把某一列字段声明主键,这一列的数据有如下特点
*
非空
*
唯一
*
被引用 -- 当前主键的列,作为一条记录的标识。
2.
声明主键
*
使用关键字 primary key 声明某一个字段为主键。
3.
测试主键
*
创建新的数据
create database day06;
use day06;
create table person(
id int primary key,
username varchar(20)
);
*
添加数据
* insert into person values (1,‘
美美‘);
* insert into person values (2,‘
小风‘);
4.
主键的自动增长
*
主键的值特点,可以把主键的值交给数据库去维护。
*
自动增长只能使用int 和 bigint 类型
*
通过关键字 auto_increment
*
演示自动增长
drop table person;
create table person(
id int primary key auto_increment,
username varchar(20)
);
*
添加数据的时候
* insert into person values (null,‘
美美‘);
* insert into person values (null,‘
小风‘);
* insert into person values (2,‘
小花‘);
*
如果删除了一条记录
* delete from person where id = 2;
5.
总结
*
开发中,主键基本上是必须要设置的。
唯一和非空
1.
唯一的约束
*
可以把某个字段声明成唯一的值。
*
使用该关键字 unique
2.
非空
*
可以把某个字段声明成非空的
*
值是不能为空值。
*
使用关键字 not null
3.
练习
create table person(
id int primary key auto_increment,
username varchar(30) unique,
email varchar(30) not null
);
create table orders();
多表的约束
外键
0.
外键的约束:目的保证表结构中的数据的完整性!!
1.
模拟的过程
2.
有一个部门表,还有一个员工表。一个部门下有多个个员工。
3.
创建表结构
create table dept(
did int primary key auto_increment,
dname varchar(30)
);
create table emp(
eid int primary key auto_increment,
ename varchar(30),
sal double,
dno int
);
create table emp(
eid int primary key auto_increment,
ename varchar(30),
sal double,
dno int,
foreign key (dno) references dept (did);
);
*
向部门表中添加一些数据
* insert into dept values (1,‘
研发部‘);
* insert into dept values (2,‘
人事部‘);
*
想添加几个员工?员工属于哪一个部门?
* insert into emp values (1,‘
美美‘,5000,2); -- 美美员工属于人事部
* insert into emp values (2,‘
小凤‘,6000,2);
* insert into emp values (3,‘
熊大‘,16000,1);
* insert into emp values (4,‘
熊二‘,16005,1);
*
想直接删除掉部门?
* delete from dept where did = 1;
*
部门可以被删除,需要使用外键对两张表做约束!!
*
直接删除掉部门,程序是可以删除的,但是不合理。通过设置外键的约束来避免这一类的问题的发生。
*
保证数据的完整性!!
*
外键多表的关系
*
使用关键字 foreign key (dno) references dept (did);
*
相当于 dno字段作为emp表的外键,值是从dept表中did取值。
*
演示
*
修改emp表的信息
* alter table emp add foreign key (dno) references dept (did);
*
再删除某个部门,如果该部门下有员工,删除是不成功!如果没有员工,可以删除部门的。
* delete from dept where did = 1;
多表的设计
1.
多表的设计存在3种方式
*
一对多
*
在多方表中,创建一个新的字段,作为当前表的外键,指向一方表的主键。
*
多对多
*
先创建一张中间表,中间表中至少包含2个字段,两个字段作为当前中间表的外键,指向原来多对多表的主键。
*
一对一
*
一对一,一般不处理,放在同一张表中就可以。
2.
学习:理论,怎么样来创建表结构(建表原则)。
多表设计练习
多表的查询(去掉重复的数据)
1.
笛卡尔积
*
两个结果的乘积
2.编写SQL语句
* select * from emp,dept; --
产生的结果就是笛卡尔积。
内联接
1.
内连接分成两种方式
*
普通内连接
*
关键字是 select * from 表1 inner join 表2 on 条件
* select * from dept inner join emp on dept.did = emp.dno;
*
隐式内链接(使用的比较多)
*
使用select * from 表1,表2 where 条件
* select * from dept,emp where dept.did = emp.dno;
* select * from dept as d,emp as e where d.did = e.dno;
* select * from dept d,emp e where d.did = e.dno;
* select d.*,e.ename,e.sal from dept d,emp e where d.did = e.dno;
外联接
1.
外链接又分成左外链接和右外链接
*
左外链接
*
使用关键字 select * from 表1 left outer join 表2 on 条件
* outer
关键字省略不写
* select * from dept left outer join emp on dept.did = emp.dno;
* select * from dept left join emp on dept.did = emp.dno;
*
右外链接
*
使用关键字 select * from 表1 right outer join 表2 on 条件
* outer
关键字省略不写
* select * from dept right outer join emp on dept.did = emp.dno;
总结
1.
笛卡尔积
*
两个结果的乘积,数据是重复,目的:去除掉重复的数据
2.
需要使用多表的查询
*
内连接
*
普通内连接
*
表1 inner join 表2 on 主键和关键关联
*
隐式内连接
* select * from
表1,表2 where 条件;
*
外连接
*
左外连接
*
表1 left outer join 表2 on
*
右外连接
*
表1 right outer join 表2 on
内联接和外联接的区别
0.
如果数据正常的话,不管是内连接和外连接,查询的结果都是一样的。
1.
先向部门的表中添加一些数据
* insert into dept values (3,‘
行政部‘);
* insert into dept values (4,‘
销售部‘);
2.
员工表中添加一些数据
* insert into emp values (5,‘
冠希‘,4500,null);
* insert into emp values (6,‘
柏芝‘,6500,null);
3.
查询的测试
*
内链接
* select * from dept d,emp e where d.did = e.dno;
*
查询的结果都是主外键关联的数据
*
左链接
* select * from dept left outer join emp on dept.did = emp.dno;
*
把左表中所有的数据全部都查询出来和有关联的数据
*
右链接
* select * from dept right outer join emp on dept.did = emp.dno;
*
把右表中所有的数据全部都查询出来和有关联的数据
4.
总结
*
内连接查询的结果都是有关系的数据
*
左链接,先看SQL语句中哪个表是左表,把左表中的所有的数据全部都查询出来,和有关系的数据也会查询出来。
*
右链接,先SQL语句中哪个表是右表,把右表中所有的数据全部查询出来,和有关系数据查询出来。
子查询
1.
子查询,嵌套查询,一个select语句不能查询出结果的,可以通过多个select语句来查询结果。
2.
例子:查询出英语成绩大于英语平均分的同学?
*
先计算出英语的平均分(select avg(english) from stu;)
*
再编写select语句
* select username,english from stu where english > (select avg(english) from stu);
3.
运算的符号
* > < >= <= <>
* >any select * from stu where english >any
子查询的结果可能是 4, 5, 6 >any结果大于最小的就满足条件
* >all select * from stu where english >all
子查询的结果可能是 4, 5, 6 >all结果大于最大的就满足条件
练习
1.
根据上午的部门表和员工的表来练习的。
*
查看小凤所属的部门名称和员工名称?
*
查询 -- 部门名称和员工名称
*
几张表 -- 目标名称是从部门表查询,员工名称是员工查询。2张表
*
条件 -- 笛卡尔积(去除掉笛卡尔积),ename=‘小风‘
*
编写SQL语句
* select d.dname,e.ename from dept d,emp e where d.did = e.dno and e.ename = ‘
小凤‘;
*
统计每个部门的人数(按照部门名称统计)
*
查询 -- 部门的人数,部门的名称
*
几张表 -- 两张表
*
条件 -- 笛卡尔积(去除掉笛卡尔积),按部门分组
* SQL
语句
* select d.dname,count(*) from dept d,emp e where d.did = e.dno group by d.dname;
*
统计部门的平均工资(按部门名称统计)
* select d.dname,avg(e.sal) from dept d,emp e where d.did = e.dno group by d.dname;
*
统计部门的平均工资大于公司平均工资的部门
*
查询 -- 查询部门
*
两张表
*
条件 -- 笛卡尔积(去除掉笛卡尔积),要大于公司的平均工资(先计算出来),说明子查询
* SQL
语句
* select d.dname,avg(e.sal) from dept d,emp e where d.did = e.dno group by d.dname having avg(e.sal) > (select avg(sal) from emp);
项目
数据列表加载流程:
统一使用pojo转json输出给datagrid:
用户列表查询:
需求:
功能描述及功能操作流程。
操作流程:
1、用户点击菜单,进入用户查询页面
2、进入用户查询页面,默认查询到所有用户,默认显示了第一页的内容
3、用户输入查询条件,查询用户信息
datagrid执行流程
Rownum的使用?
分别说说MySQL和oracle的分页?
oracle使用rownum加上嵌套子查询完成分页功能
SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
WHERE ROWNUM <= 40
)
WHERE RN >= 21
MySQL使用的是limit函数
SELECT * FROM table LIMIT 5,10; //查询的是第6条到第15条数据,注意,10位偏移量。