有了分页,本节我们实现按姓名进行查询.
# 定制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
- 第十四章:重构服务层