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位偏移量。