我的java web架构方案


//业务逻辑代码片段
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);


...
try (Connection conn = HdgangDataSource.getConnection(HostFactory.getHost())) {
URL url = new URL("/cult/list.do");//url工具类,构造方法参数为请求路径,可在视图里覆盖,复杂项目不建议这样直接设定,可从控制器获取
Tool.bind(url, this, paramNames);//绑定有效的请求参数至url对象
Pagination pagination = new Pagination();//创建一个查询分页工具类实例
pagination.setRowCnt(24);//设置每页24条记录
pagination.setPageParamName("page");//设置url的分页的请求参数名
pagination.setCurrentPage(page);//设置当前页码
pagination.setUrl(url);//设置url
pagination.setEncode(res.getCharacterEncoding());//设置URL参数的默认编码

//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 ... {

//通过map绑定命名参数(类似于 :xxx),也支持通过javaBean绑定
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("fulltext", fulltext);

//依据查询条件拼接复杂sql,myBatis实现的话比较别扭。这里定义MovieSql接口,具体实现可以跨数据库。这里直接new,实际应用应该依赖注射或者根据配置文件装载和实例化。
MovieSql movieSql = new MovieSqlMysqlImpl();

String scalarSql= movieSql.getSelectScalarSql(word);
//DAO为数据库工具类,getScalar获取符合条件的记录条数
long rowTotalCnt = DAO.getScalar(conn, scalarSql, paramMap);
List<Movie> movieList = null;
if (rowTotalCnt > 0) {
//将查询得到的总记录条数set到pagination
pagination.setRowTotalCnt(rowTotalCnt);
String sql = movieSql.getSelectListSql(word,order, pagination.getOffset(),pagination.getRowCnt());
//getBeanList 获得查询得到的分页记录,getBeanList方法重载支持通过javaBean和Map绑定命名参数
movieList = DAO.getBeanList(conn, sql, paramMap, Movie.class);
}
return movieList;
}





//获取SQL语句的接口
public interface MovieSql{
public String getSelectScalarSql(String word);
public String getSelectListSql(String word,String order, int offset, int rowCnt);

...
}



//实现MovieSql接口,动态拼接sql语句。
public class MovieSqlMysqlImpl implements MovieSql{
private final String select = "select `id`,`imdbid`,`name`,`year`,`duration`,`aliases`,`directors`,`actors`,`tags`,`intro`"
+ ",`areas`,`types`,`score`,`date`,`update`,`state` from `movie` ";
private final String selectCnt = "select count(*) from `movie` ";

private String getConditionsSqlFragment(String word){
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) ";
}
return conditions;
}

private String getOrdersSqlFragment(String order){
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;
}
return orders;
}

@Override
public String getSelectScalarSql(String word){
return selectCnt +" "+ getConditionsSqlFragment(word) + ";";
}

@Override
public String getSelectListSql(String word,String order, int offset, int rowCnt){
return select +" "+ getConditionsSqlFragment(word) +" "+ getOrdersSqlFragment(order) + " limit " + offset + "," + rowCnt + ";";
}

...
}



[b]更多细节可参考[/b] [url]http://afadgaeg.iteye.com/blog/2155226[/url]

[b]架构原则[/b]:
1、轻量级组件优于重量级框架。实现完全解耦
2、约定优于配置。实现零配置
3、不要为了所谓的优雅而做不优雅的事,如过度封装和过度配置

[b]相关阅读[/b]:
php轻量化架构与编码约定 [url]http://afadgaeg.iteye.com/blog/2395077[/url]

[b]深圳求职[/b](如有违规,请版主告知,我一定配合删除):
本人现在在深圳,找寻java方向工作,如有适合岗位招聘,可联系我的邮箱:[b]2530210585@qq.com[/b] 或者手机:[b]13874372370[/b]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值