分享
 
 
 

基于J2EE体系实现多层结构Blog平台(2)

王朝java/jsp·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

六、配置iBatis

接下来,使用iBatis实现O/R Mapping。首先从http://www.ibatis.com下载iBatis 2.0,将所需的jar文件复制到web/WEB-INF/lib/目录下。iBatis使用XML配置数据库表到Java对象的映射,先编写一个sql-map-config.xml:

<?xml version="1.0" encoding="utf-8" ?

<!DOCTYPE sqlMapConfig

PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"

"http://www.ibatis.com/dtd/sql-map-config-2.dtd"

<sqlMapConfig

<settings cacheModelsEnabled="false" enhancementEnabled="true"

lazyLoadingEnabled="true" maxRequests="32"

maxSessions="10" maxTransactions="5"

useStatementNamespaces="false"

/

<transactionManager type="JDBC"

<dataSource type="JNDI"

<property name="DataSource" value="jdbc/blog" /

</dataSource

</transactionManager

<!-- 如果有其他xml配置文件,可以包含进来 --

<sqlMap resource="Account.xml" /

</sqlMapConfig

将sql-map-config.xml放到web/WEB-INF/classes/目录下,iBatis就能搜索到这个配置文件,然后编写一个初始化类:

public class SqlConfig {

private SqlConfig() {}

private static final SqlMapClient sqlMap;

static {

try {

java.io.Reader reader = Resources.getResourceAsReader ("sql-map-config.xml");

sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);

} catch (Exception e) {

e.printStackTrace();

throw new RuntimeException("Error initializing SqlConfig. Cause: " + e);

}

}

public static SqlMapClient getSqlMapInstance () {

return sqlMap;

}

}

SqlMapClient封装了访问数据库的大部分操作,可以直接使用SqlConfig.getSqlMapInstance()获得这个唯一实例。

七、使用DAO模1式

为了分离逻辑层和数据库持久层,定义一系列DAO接口:AccountDao,CategoryDao,ArticleDao……其实现类对应为SqlMapAccountDao,SqlMapCategoryDao,SqlMapArticleDao……这样就使得逻辑层完全脱离了数据库访问代码。如果将来需要使用其它的O/R Mapping方案,直接实现新的DAO接口替代现有的SqlMapXxxDao即可。以SqlMapAccountDao为例,实现一个login()方法是非常简单的:

public int login(String username, String password) throws AuthorizationException {

try {

Map map = new HashMap();

map.put("username", username);

map.put("password", password);

Integer I = (Integer)sqlMap.queryForObject("login", map);

if(I==null)

throw new RuntimeException("Failed: Invalid username or password.");

return I.intValue();

}

catch(SQLException sqle) {

throw new RuntimeException("Sql Exception: " + sqle);

}

}

在Account.xml配置文件中定义login查询:

<select id="login" parameterClass="java.util.Map" resultClass="int"

select [accountId] from [Account] where

[username] = #username# and password = #password#

</select

八、逻辑层设计

由于DAO模式已经实现了所有的数据库操作,业务逻辑主要是检查输入,调用DAO接口,因此业务逻辑就是一个简单的Facade接口:

public class FacadeImpl implements Facade {

private AccountDao

accountDao;

private ArticleDao

articleDao;

private CategoryDao categoryDao;

private FeedbackDao feedbackDao;

private ImageDao

imageDao;

private LinkDao

linkDao;

private SequenceDao sequenceDao;

}

对于普通的getArticle()等方法,Facade仅仅简单地调用对应的DAO接口:

public Article getArticle(int articleId) throws QueryException {

return articleDao.getArticle(articleId);

}

对于需要身份验证的操作,如deleteArticle()方法,Facade需要首先验证用户身份:

public void deleteArticle(Identity id, int articleId) throws DeleteException {

Article article = getArticleInfo(articleId);

if(article.getAccountId()!=id.getAccountId())

throw new AuthorizationException("Permission denied.");

articleDao.deleteArticle(articleId);

}

要分离用户验证逻辑,可以使用Proxy模式,或者使用Spring的AOP,利用MethodInterceptor实现,不过,由于逻辑很简单,完全可以直接写在一块,不必使用过于复杂的设计。 至此,我们的Blog已经实现了所有的后台业务逻辑,并且提供统一的Facade接口。前台Web层仅仅依赖这个Facade接口,这样,Web层和后台耦合非常松散,即使替换整个Web层也非常容易。

九、Web层设计:使用MVC模式

对于复杂的Web层,使用MVC模式是必不可少的。虽然Spring能轻易集成Struts,WebWorks等Web框架,但Spring本身就提供了一个非常好的Web框架,能完全实现MVC模式。

Spring使用一个DispatcherServlet,所有的特定请求都被转发到DispatcherServlet,然后由相应的Controller处理,Controller返回一个ModelAndView对象(因为Java语言的方法调用只能返回一个结果,而且不支持ref参数,所以将Model和View对象合在一起返回),Model是一个Java对象,通常是Map,View是视图的逻辑名字,通常是JSP文件名,但也可以使用Velocity等作为视图。返回的View通过viewResolver得到真正的文件名。首先配置Spring的MVC,在web.xml中声明DispatcherServlet,处理所有以.c结尾的请求:

<web-app

<servlet

<servlet-namedispatcher</servlet-name

<servlet-classorg.springframework.web.servlet.DispatcherServlet</servlet-class

<load-on-startup1</load-on-startup

</servlet

<servlet-mapping

<servlet-namedispatcher</servlet-name

<url-pattern*.c</url-pattern

</servlet-mapping

</web-app

Spring会在WEB-INF下查找一个名为dispatcher-servlet.xml的文件,我们需要创建这个文件:

<?xml version="1.0" encoding="utf-8"?

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

"http://www.springframework.org/dtd/spring-beans.dtd"

<beans

</beans

用到的所有的Java Bean组件都要在这个文件中声明和配置,以下是配置URL映射的Bean:

<bean id="urlMapping"

class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"

<property name="mappings"

<props

<prop key="/article.c"articleController</prop

</props

</property

</bean

凡是匹配/article.c的Request都会被名为articleController的Bean处理,同样需要声明这个articleController:

<bean id="articleController" class="example.ViewArticleController"

</bean

ViewArticleController处理请求,然后生成Model,并选择一个View:

public class ViewArticleController implements Controller {

private Facade facade;

public void setFacade(Facade facade) { this.facade = facade; }

public ModelAndView handleRequest(HttpServletRequest request,

HttpServletResponse response) throws Exception {

// 获得参数:

int articleId = Integer.parseInt(request.getParameter("articleId"));

// 使用facade处理请求:

Article article = facade.getArticle(articleId);

// 生成Model:

Map map = new HashMap();

map.put("article", article);

// 返回Model和视图名“skin/blueskysimple/article”:

return new ModelAndView("skin/blueskysimple/article", map);

}

}

最后,skin/bluesky/article视图会将结果显示给用户。

我们注意到,ViewArticleController并不自己查找或者创建Facade,而是由容器通过setFacade(Facade)方法设置的,这就是所谓的IoC(Inversion of Control)或者Dependency Injection。容器通过

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有