有了分頁,本節我們實現按姓名進行查詢.
# 定制V層
```
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>教師管理</title>
</head>
<body>
<h2>
輸入的關鍵字為:<s:property value="name" />
</h2>
<form>
<label>姓名:<input type="text" name="name" value="<s:property value="name" />" /></label>
<button type="submit">submit</button>
</form>
<table>
<tr>
<th>序號</th>
<th>姓名</th>
<th>用戶名</th>
<th>性別</th>
<th>郵箱</th>
</tr>
<!-- s為我們在文件頭定位的標簽前綴。iterator是struts用于循環輸出List的標簽 -->
<!-- teachers:自動調用C層的getTeachers();var=teacher:在循環體中使用的變量名 -->
<s:iterator value="teachers" var="teacher" status="status">
<tr>
<td><s:property value="#status.count" /></td>
<!-- property輸出變量 teacher為內部變量,前面加入# -->
<td><s:property value="#teacher.name" /></td>
<td><s:property value="#teacher.username" /></td>
<td><s:property value="#teacher.sexAttr" /></td>
<td><s:property value="#teacher.email" /></td>
</tr>
</s:iterator>
</table>
<h4>
{"id":3, "name":"admin"}
每頁1條:<a href="?page=1&pageSize=1">1</a> <a href="?page=2&pageSize=1">2</a>
<a href="?page=3&pageSize=1">3</a><br /> 每頁2條:<a
href="?page=1&pageSize=2">1</a> <a href="?page=2&pageSize=2">2</a> <a
href="?page=3&pageSize=2">3</a><br /> 每頁3條:<a
href="?page=1&pageSize=3">1</a> <a href="?page=2&pageSize=3">2</a> <a
href="?page=3&pageSize=3">3</a><br />
</h4>
</body>
</html>
```
#C層
```
// 查詢姓名
private String name = "";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
```
## 測試
經測試發現,如果在姓名中輸入的為英文,則會正確顯示。但如果輸入中文,則會變成亂碼。
## 再說亂碼
關于亂碼的問題,我們討論過。亂碼形成的原因大概是這樣:
1. 法張三是法國人,韓李四是韓國人。
2. 法張三找了個會英文的朋友,寫了封信,內容為"hello"
3. 韓李四,收到來信,也找了會英文的朋友,讓其幫忙譯成韓文。
這樣,張三和李四,就可以正確的通信了。我們說上述對話的『英文』,便是程序的編碼。如果法張三有一天高興找一個會中文的朋友幫忙寫了個"你好",并發送給李四,那么李四還是會按自己的想法,把會英文的朋友請過來幫忙翻譯。使用英文的語法來翻譯中文,當然就出現亂碼了。
我們在index.jsp中,將頁面的格式指定為`utf-8`,即把字符按`utf-8`的格式進行發送和顯示。數據在使用POST方法提交時,是沒有問題的,比如前面,我們開發過的數據添加。
### POST傳值
我們在V層的FORM中,增加`method="POST"`,然后再進行測試,發現傳入的中文正常顯示了,這是為什么呢?下面,我們共同來分析下亂碼產生的原因。
1. 使用POST方法提交時,數據是這樣傳輸的。
FORM表單 `->` tomcat將數據轉發給struts `->` struts將數據傳給VIEW
2. 使用GET方法提交時,數據卻是這樣傳輸的。
FORM表單 `->` GET信息轉化為URL參數 `->` tomcat將URL參數對應的數據轉發給struts `->` struts將數據傳給VIEW。
相信有了上面的數據傳輸過程,再找問題就簡單了。
我們一步步的測試:
* FORM表單 `->` GET信息轉化為URL參數
輸入中文,點submit后,我們觀察生成的URL信息。結果沒有發現亂碼。
* GET信息轉化為URL參數 `->` tomcat將URL參數對應的數據轉發給struts
我們在C層中增加如下代碼:
```
System.out.println(name);
return "success";
}
```
保存,待自動編譯完成后,刷新前臺。發現,在控制臺中,打印出了亂碼。看來問題問題出在tomcat的URL轉化上。
是的,tomcat在轉化URL的時候,默認采用的并不是utf-8編碼。通過GOOGLE:tomcat uri utf-8
找到的答案是去修改TOMCAT的配置文件。
在使用eclipse進行開發中,tomcat servers做為一個項目出現,我們打開eclipse的工作目錄,然后找到Servers,再找到我們前面新建的tomcat服務,打開server.xml, 并找到這行`<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>`修改為:`<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>`。
重啟TOMCAT后,再輸入中文,亂碼就這么被我們解決了。
** 搜索的關鍵字很重要 ** 如果,我們搜索 "tomcat get 亂碼",也會得到很多信息,但更多的大家卻傾向于使用全局過濾器的方法。雖然能夠解決亂碼的問題,但根本性的原因沒有找到,為以后項目布署時埋下了隱患。
> 生產環境下,我們則需要修改tomcat服務的config文件夾下的server.xml
# 實體類增加查詢方法
我們還是使用painate做為函數名,并加入查詢關鍵字做為參數。這種函數名不變,參數改變的方法,叫做重構。當然了,這也是面對對象的四大特征之一。
```
package entity;
// 聲明主體
@Entity
public class Teacher {
/**
* 分頁數據
* @param name 查詢的姓名
* @param page 第幾頁
* @param pageSize 每頁大小
* @return
*/
static public List<Teacher> paginate(String name, int page, int pageSize) {
// 實例化列表 teachers
List<Teacher> teachers = new ArrayList<Teacher>();
// 創建會話(這里的session也是會話的意思,我們以前接觸的http中的session,處理的是用戶與服務器的對話)
Session session = MysqlJavaee.getCurrentSession();
// 開啟事務(使用緩沖池進行數據庫的連接)
Transaction transaction = session.beginTransaction();
// 在這里,必須使用try catch finally語句。來確定會話正常關閉.
// 否則,當操作數據庫產生錯誤時,你可能需要重啟mysql服務
try {
// 查詢Teacher表,注意:是Teacher ,而不是 teacher
Query query = session.createQuery("from Teacher where name like '%" + name + "%'");
// 計算并設置第一條記錄的位置
int index = (page - 1) * pageSize;
query.setFirstResult(index);
// 每頁大小
query.setMaxResults(pageSize);
teachers = query.list();
// 提交事務
transaction.commit();
// 捕獲異常
} catch (HibernateException e) {
// 如果事務執行異常,則回滾事務
if (null != transaction) {
transaction.rollback();
}
// 打印異常
e.printStackTrace();
} finally {
// 如果session處于開啟狀態,則關閉session
if (session.isOpen()) {
// 關閉會話
session.close();
}
}
return teachers;
}
```
`from Teacher where name like '%" + name + "%'`這是標準的HQL即hibernate query languge。和標準的SQL超級像,對不對。
實現的作用是查詢與 *name name* *name*相匹配的內容。
## 測試
```
package teacher;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import db.MysqlJavaee;
import entity.Teacher;
public class IndexTest {
@Test
public void paginateByName() {
List<Teacher> teachers = Teacher.paginate("四", 1, 2);
for (Teacher teacher : teachers) {
System.out.println(teacher.toString());
}
}
```
此時,我們在數據表中,添加好自己想到的數據,并將 "四",改變為自己想測試的內容。并查看控制臺的輸出結果。
# 對接C層。
我們稍加修改
```
// 該execute方法將被自動調用, 方法的返回類型必須為String
public String execute() {
// 獲取教師列表
// 未輸入姓名,則查詢所有信息
if (name.equals("")) {
teachers = Teacher.paginate(page, pageSize);
// 輸入姓名,則進行模糊查詢
} else {
teachers = Teacher.paginate(name, page, pageSize);
}
return "success";
}
```
# 集成測試
下面,我們輸入關鍵字信息,查看效果吧。
> 前臺,我們以后將采用angularjs對表格進行處理。
> 官方文檔:[queryhql-where](https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-where)
- README
- 第一章:準備
- 第二章:Hello World!
- 第一節:查看工程文件
- 第二節:JDK、JRE與環境變量
- 第三節:index.jsp
- 第三章:Hello Struts
- 第一節:Web.xml
- 第二節:單入口
- 第三節:Hello Struts
- 第四節:觸發C層
- 第四章:建立數據表
- 第一節:建立實體類
- 第二節:測試一
- 第三節:測試二
- 第四節:引入Hibernate
- 第五節:配置Hibernate
- 第六節:建立連接
- 第七節:實體類映射數據表
- 第八節:完善數據表
- 第五章:教師管理
- 第一節:增加數據--add
- 第二節:增加數據--save
- 1 獲取傳入數據數據
- 2 數據寫入測試
- 3 對接C層
- 第三節:數據列表
- 1 獲取數據
- 2 重構代碼
- 3 C層對接--初始化
- 4 C層添加數據
- 5 V層顯示數據
- 6 獲取數據庫中數據
- 7 顯示性別
- 8 分頁
- 9 條件查詢
- 第四節:修改數據
- 1 edit
- 2 update
- 第五節:刪除數據
- 第六節:總結
- 第六章:重構C層
- 第一節:繼承ActionSupport類
- 第二節:數據驗證
- 第七章:前臺分離(前臺)
- 第一節:環境搭建
- 第二節:運行環境
- 第三節:共享開發環境
- 第四節:生產環境
- 第八章:前臺開發(前臺)
- 第一節:本地化
- 第二節:教師列表
- 1 引入M層
- 2 模擬后臺返回數據
- 3 C與M對接
- 4 C與V對接
- 第九章:前后臺對接(前后臺)
- 第一節:后臺輸出json(后臺)
- 第二節:對接前臺(全棧)
- 第二節:對接API(前臺)
- 第二節:跨域請求(后臺)
- 第三節:重構代碼(前臺)
- 第十章:重構后臺M層
- 第一節:數據訪問DAO層
- 第二節:項目整體重構
- 第十一章:用戶登陸(前后臺)
- 第一節:制定規范
- 第二節:定制測試用例
- 第三節:后臺輸入測試代碼(后臺)
- 第四節:postman(后臺)
- 第五節:新建用戶登陸模塊(前臺)
- 第六節:代碼重構(前臺)
- 第十二章:班級管理(前后臺)
- 第一節:班級列表
- 1 原型開發
- 2 制定規范
- 3 后臺對接開發
- 4 前臺對接開發
- 第二節:Add
- 1 原型開發
- 2 制定規范
- 3 后臺對接開發
- 4 前臺對接開發
- 第三節:Save
- 1 制定規范
- 2 后臺對接開發
- 3 前臺對接開發
- 第四節:Edit
- 1 原型開發
- 2 制定規范
- 3 后臺對接開發
- 4 前臺對接開發
- 第五節:Update
- 1 制定規范
- 2 后臺對接開發
- 3 前臺對接開發
- 第六節:Delete
- 1 制定規范
- 2 后臺對接開發
- 3 前臺對接開發
- 第七節:小結
- 第十三章:班級管理(API)
- 第一節:ER圖
- 第二節:create
- 1 實體層
- 2 dao層
- 3 service(server)層
- 4 action層
- 第三節:ManyToOne
- 第四節:Read
- 1 service(server)層
- 2 action層
- 第五節:update
- 1 service(server)層
- 2 action層
- 第六節:update
- 第十四章:重構服務層