class="java">
//业务逻辑代码片段
private String word;
private String area;
private String type;
private Integer year;
private String order;
private Integer page;
@NotNull
@Min(0)
private Integer id;
public void list(HttpServletRequest req, HttpServletResponse res) throws ... {
//获得请求参数处理工具类实例,这里直接从上下文读取,你也可以使用spring或者自行实现依赖注入
RequestParameterUtil paramUtil = (RequestParameterUtil) req.getServletContext().getAttribute("requestParameterUtil");
//获得消息对象
Messages messages = (Messages) req.getAttribute("messages");
String[] paramNames = {"word", "area", "type", "year", "order", "page"};
//请求参数工具类根据paramNames指定的参数数组利用反射依照命名约定绑定到this对象,本例为查询操作。当然,对于insert操作,绑定到javaBean对象更快捷方便。
//然后工具类自动执行java标准的基于注解的数据合法性验证validate
//bind()方法返回布尔值,标示是否存在绑定或者验证错误,messages为消息对象,保存所有分级别的消息
paramUtil.bind(req, this, paramNames, messages);
//定义命名参数形式的分页url
String paginationLink = "/xxx/yyy?zz=abc&aaa=efg&page=:page";
...
try (Connection conn = HdgangDataSource.getConnection(HostFactory.getHost())) {
//Pagination为查询分页工具类,cntRowPerPage参数为每页记录条数,第三个参数为满足条件的总记录数,这里先留空,最后一个参数指定分页命名参数
Pagination pagination = new Pagination(page, cntRowPerPage, null, paginationLink, ":page");
//DAO方法
List<Movie> movieList = MovieDAO.getList(conn, word, order, pagination);
//可以换成依赖注入。pagination 为分页对象,视图可直接配合模板一行代码渲染分页模块
req.setAttribute("movieList", movieList);
req.setAttribute("pagination", pagination);
}
//可以返回字符串消息,交由控制器处理跳转
req.getRequestDispatcher("/cult/list.jsp").forward(req, res);
}
//get set 方法省略
//DAO方法
public static List<Movie> getList(Connection conn, String word, String order, Pagination pagination)
throws ... {
//业务逻辑为mysql全文搜索,可略过不看。依据查询条件拼接复杂sql,myBatis实现的话比较别扭。
String select = "select `id`,`imdbid`,`name`,`year`,`duration`,`aliases`,`directors`,`actors`,`tags`,`intro`"
+ ",`areas`,`types`,`score`,`date`,`update`,`state` from `movie` ";
String selectCnt = "select count(*) from `movie` ";
String conditions = "";
String fulltext = "";
if (word != null && !word.trim().isEmpty()) {
word = word.trim();
fulltext = Tool.encode(word, true, "+");
conditions = " where match(`fulltext`) against(:fulltext IN BOOLEAN MODE) ";
}
String orders;
switch (order) {
case "score":
orders = " order by `score` desc ";
break;
case "sdate":
orders = " order by `date` desc ";
break;
default:
orders = " order by `update` desc,`date` desc ";
break;
}
//通过map绑定命名参数(类似于 :xxx),也支持通过javaBean绑定
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("fulltext", fulltext);
String sql0 = selectCnt + conditions + ";";
//DAO为数据库工具类,getScalar获取符合条件的记录条数
long rowTotalCnt = DAO.getScalar(conn, sql0, paramMap);
List<Movie> movieList = null;
if (rowTotalCnt > 0) {
//将查询得到的记录条数set到pagination
pagination.setRowTotalCnt(rowTotalCnt);
String sql = select + conditions + orders + " limit " + pagination.getOffset() + "," + pagination.getRowCnt() + ";";
//getBeanList 获得查询得到的分页记录,getBeanList重载支持javaBean和Map绑定命名参数
movieList = DAO.getBeanList(conn, sql, paramMap, Movie.class);
}
return movieList;
}
更多细节可参考 http://afadgaeg.iteye.com/blog/2155226
架构原则:
1、轻量级组件优于重量级框架。实现完全解耦
2、约定优于配置。实现零配置