ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
有了分页,本节我们实现按姓名进行查询. # 定制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)