java笔记:自己动手写javaEE框架(一)--数据访问层DAO以及DAO的单元测试
2011-10-09 23:25
806 查看
写这篇博客前,我有个技术难题想请教大家,不知道谁有很好的建议,做过互联网的童鞋应该都知道,有点规模的大公司都会做用户行为分析系统,而且有些大公司还会提供专业的用户行为分析解决方案例如:百度分析,google analysis。用户行为分析就是当用户访问某个网站的页面,会有专门系统记录用户的相关信息以及使用状况,然后分析这些数据用来指导网站的运营,我们现在遇到一个问题:如果某的访客访问了www.a.com页面,我们怎么知道这个用户访问过www.b.com页面,a页面和b页面毫无关系,比如:某个未知访客访问QQ主页,他只要打开了QQ页面我就知道他是否访问过sina的页面,听说有人把这个做出来了,但是我还没想到,哪位高手能想到解决方案吗?
说到用户行为分析,这个对于互联网公司来说相当的重要系统,以后有时间我会开一个系列从技术到业务的角度讲讲用户行为分析系统是啥样子,大伙好好交流下。感兴趣的童鞋多多关注哈。
转入正题前还闲话几句,本来开博客是想系统研究javascript技术,但是最近工作比较忙,而且大量工作都是java开发任务(我们公司前端工程师太不专业了,哎),因此javascript现在只得暂停下,毕竟晚上的时间还是太少。因此我想就我现在做的技术开一个新系列:自己动手写javaEE框架,这个和我现在工作有关比较好收集资料,这个系列我的想法很大,我想写如下内容:
1. struts2+ibatis+spring+js
2. springmvc+ibatis+spring+js
3. flex+ibatis+spring
如果以上写完还有时间的话,我会把ibatis换成hibernate,也许还会自己封装一个js框架或者更加深入讲解flex技术。哎,东西挺多了,能写完不???天知道了。
由于内容比较多,我的博客里只做简单讲解,不做深入分析。好下面开始了。
我第一个写的是struts2+ibatis+spring+js。框架结构是页面+action+service+dao+数据库,数据库为oracle(公司电脑装的是oracle)或者mysql(家里电脑装的是mysql)。
今天任务是搭建好spring框架,spring里面集成好ibatis框架,然后编写dao层,最后一个重要任务是加入junit测试框架,方便以后开发的单元测试(junit测试框架是本博文的亮点,我想许多做java童鞋看完本篇博客还是很有启发的,因为我发现很多朋友都不太会做跟spring相关的单元测试,这个会了能提升不少开发效率)。我是按下面步骤写的:
1. 首先是工程结构如下图:
2.使用到的jar包如下:
3. 我首先写的是web.xml,代码如下:
这里面主要是向工程里装载spring框架。
4. 下面我在conf包下面建立constants.properties文件,这个文件用来放置一些经常会变化的配置信息,例如:数据库配置信息、文件的路径等等,内容如下:
5. 接下来写的是applicationContext.xml文件,这里首先是扫描spring组件和导入constants.properties文件的内容,接下来配置数据源(oracle或mysql),然后在spring里装载ibatis框架和定义ibatis操作模板类,最后定义事物管理,这些做javaee开发的工程师都很清楚,我就不具体讲解,实际使用copy就行了。内容如下:
6. 接着我在文件路径cn/com/sharpxiajun/dao/sqlmap/下编写了USERS.xml配置文件,内容如下:
里面我只写了一个查询方法,parameterClass="java.util.Map"代表传入参数是map,resultClass="java.util.HashMap"表示返回的结果是一个map,这里正好应用了我前一篇博文里面谈到的各个逻辑层用map来做为传输的介质。
7. 然后我在路径cn.com.sharpxiajun.dao下编写接口UsersDao,内容如下:
在路径cn.com.sharpxiajun.dao.impl下实现了UsersDaoImpl接口,代码如下:
@Scope("prototype"):多线程, 生成多个实例。
@Repository("usersDao")将UsersDaoImpl注册为spring的bean对象,Repository标签只用于dao层,因为Repository标签里面还封装了dao层抛出的异常类型。
8. 写好了dao层我接下来编写了SqlMapConfig.xml文件,内容如下:
9. 最后我们编写该UserDao单元测试类,代码如下:
运行结果如下:
写完了,写的累死人了,这里用junit做spring组件的单元测试非常有用,希望很多做java的童鞋可以试试,另外我写的junit测试类是用注解的方式,这是junit4里才有的,有兴趣的童鞋可以学习下哈。
说到用户行为分析,这个对于互联网公司来说相当的重要系统,以后有时间我会开一个系列从技术到业务的角度讲讲用户行为分析系统是啥样子,大伙好好交流下。感兴趣的童鞋多多关注哈。
转入正题前还闲话几句,本来开博客是想系统研究javascript技术,但是最近工作比较忙,而且大量工作都是java开发任务(我们公司前端工程师太不专业了,哎),因此javascript现在只得暂停下,毕竟晚上的时间还是太少。因此我想就我现在做的技术开一个新系列:自己动手写javaEE框架,这个和我现在工作有关比较好收集资料,这个系列我的想法很大,我想写如下内容:
1. struts2+ibatis+spring+js
2. springmvc+ibatis+spring+js
3. flex+ibatis+spring
如果以上写完还有时间的话,我会把ibatis换成hibernate,也许还会自己封装一个js框架或者更加深入讲解flex技术。哎,东西挺多了,能写完不???天知道了。
由于内容比较多,我的博客里只做简单讲解,不做深入分析。好下面开始了。
我第一个写的是struts2+ibatis+spring+js。框架结构是页面+action+service+dao+数据库,数据库为oracle(公司电脑装的是oracle)或者mysql(家里电脑装的是mysql)。
今天任务是搭建好spring框架,spring里面集成好ibatis框架,然后编写dao层,最后一个重要任务是加入junit测试框架,方便以后开发的单元测试(junit测试框架是本博文的亮点,我想许多做java童鞋看完本篇博客还是很有启发的,因为我发现很多朋友都不太会做跟spring相关的单元测试,这个会了能提升不少开发效率)。我是按下面步骤写的:
1. 首先是工程结构如下图:
2.使用到的jar包如下:
3. 我首先写的是web.xml,代码如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>ssiprj</display-name> <!-- spring配置文件位置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:conf/applicationContext*.xml</param-value> </context-param> <!-- 将spring框架装载进我们的工程里 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
这里面主要是向工程里装载spring框架。
4. 下面我在conf包下面建立constants.properties文件,这个文件用来放置一些经常会变化的配置信息,例如:数据库配置信息、文件的路径等等,内容如下:
#db.driverClass = oracle.jdbc.driver.OracleDriver #db.user = sharpxiajun #db.password = sharpxiajun #db.jdbcUrl = jdbc:oracle:thin:@127.0.0.1:1521:orcl db.driverClass = com.mysql.jdbc.Driver db.user = root db.password = root db.jdbcUrl = jdbc\:mysql\://localhost\:3306/sq_xidi?useUnicode\=true&characterEncoding\=utf-8
5. 接下来写的是applicationContext.xml文件,这里首先是扫描spring组件和导入constants.properties文件的内容,接下来配置数据源(oracle或mysql),然后在spring里装载ibatis框架和定义ibatis操作模板类,最后定义事物管理,这些做javaee开发的工程师都很清楚,我就不具体讲解,实际使用copy就行了。内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"> <!-- 扫描该路径下的spring组件 --> <context:component-scan base-package="cn.com.sharpxiajun"/> <!-- 读取资源文件 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:conf/constants.properties</value> </list> </property> </bean> <!-- 配置数据源 --> <!-- <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${db.driverClass}"/> <property name="jdbcUrl" value="${db.jdbcUrl}"/> <property name="user" value="${db.user}"/> <property name="password" value="${db.password}"/> </bean>--> <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${db.driverClass}"/> <property name="url" value="${db.jdbcUrl}"/> <property name="username" value="${db.user}"/> <property name="password" value="${db.password}"/> </bean> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation"> <value>classpath:conf/SqlMapConfig.xml</value> </property> <property name="dataSource" ref="myDataSource"/> </bean> <bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate"> <property name="sqlMapClient"> <ref local="sqlMapClient"/> </property> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource"> <ref local="myDataSource"/> </property> </bean> </beans>
6. 接着我在文件路径cn/com/sharpxiajun/dao/sqlmap/下编写了USERS.xml配置文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"> <sqlMap namespace="USERS"> <select id="queryUserList" parameterClass="java.util.Map" resultClass="java.util.HashMap"> select t.username,t.password,t.enabled from users t </select> </sqlMap>
里面我只写了一个查询方法,parameterClass="java.util.Map"代表传入参数是map,resultClass="java.util.HashMap"表示返回的结果是一个map,这里正好应用了我前一篇博文里面谈到的各个逻辑层用map来做为传输的介质。
7. 然后我在路径cn.com.sharpxiajun.dao下编写接口UsersDao,内容如下:
package cn.com.sharpxiajun.dao; import java.util.List; import java.util.Map; public interface UsersDao { public static final String QUERY_USERS_SQL = "USERS.queryUserList"; public List<Map<String, Object>> queryUserList(Map<String, Object> map) throws Exception; }
在路径cn.com.sharpxiajun.dao.impl下实现了UsersDaoImpl接口,代码如下:
package cn.com.sharpxiajun.dao.impl; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Scope; import org.springframework.orm.ibatis.SqlMapClientTemplate; import org.springframework.stereotype.Repository; import cn.com.sharpxiajun.dao.UsersDao; @SuppressWarnings("unchecked") @Scope("prototype") @Repository("usersDao") public class UsersDaoImpl implements UsersDao { @Autowired @Qualifier("sqlMapClientTemplate") private SqlMapClientTemplate sqlMapClientTemplate = null; public List<Map<String, Object>> queryUserList(Map<String, Object> map) throws Exception { return sqlMapClientTemplate.queryForList(QUERY_USERS_SQL, map); } }
@Scope("prototype"):多线程, 生成多个实例。
@Repository("usersDao")将UsersDaoImpl注册为spring的bean对象,Repository标签只用于dao层,因为Repository标签里面还封装了dao层抛出的异常类型。
8. 写好了dao层我接下来编写了SqlMapConfig.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd"> <sqlMapConfig> <settings cacheModelsEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="true" errorTracingEnabled="true" maxRequests="64" maxSessions="20" maxTransactions="10" useStatementNamespaces="true"/> <sqlMap resource="cn/com/sharpxiajun/dao/sqlmap/USERS.xml"/> </sqlMapConfig>
9. 最后我们编写该UserDao单元测试类,代码如下:
package cn.com.sharpxiajun.junittest.dao; import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.transaction.TransactionConfiguration; import cn.com.sharpxiajun.dao.UsersDao; import junit.framework.TestCase; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:conf/applicationContext.xml"}) @TransactionConfiguration(defaultRollback = false) public class UsersDaoImplTest extends AbstractTransactionalJUnit4SpringContextTests{ @Autowired private UsersDao usersDao; public UsersDaoImplTest() { System.out.println("初始化测试类...."); } @Before public void setUp() throws Exception { System.out.println("测试开始...."); } @After public void tearDown() throws Exception { System.out.println("测试结束!!"); } @Test public void testQueryUserList() { Map<String, Object> map = new HashMap<String, Object>(); try { List<Map<String, Object>> list = usersDao.queryUserList(map); System.out.println(list); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
运行结果如下:
初始化测试类.... 2011-10-9 23:22:22 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [conf/applicationContext.xml] 2011-10-9 23:22:23 org.springframework.context.support.AbstractApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.GenericApplicationContext@290fbc: startup date [Sun Oct 09 23:22:23 CST 2011]; root of context hierarchy 2011-10-9 23:22:23 org.springframework.core.io.support.PropertiesLoaderSupport loadProperties 信息: Loading properties file from class path resource [conf/constants.properties] 2011-10-9 23:22:23 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons 信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@d16fc1: defining beans [usersDao,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,propertyConfigurer,myDataSource,sqlMapClient,sqlMapClientTemplate,transactionManager]; root of factory hierarchy 2011-10-9 23:22:23 org.springframework.test.context.transaction.TransactionalTestExecutionListener startNewTransaction 信息: Began transaction (1): transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@1b7c76]; rollback [false] 测试开始.... [{enabled=false, username=admin, password=admin}, {enabled=false, username=test, password=test}] 测试结束!! 2011-10-9 23:22:23 org.springframework.test.context.transaction.TransactionalTestExecutionListener endTransaction 信息: Committed transaction after test execution for test context [[TestContext@12b19c5 testClass = UsersDaoImplTest, locations = array<String>['classpath:conf/applicationContext.xml'], testInstance = cn.com.sharpxiajun.junittest.dao.UsersDaoImplTest@a8e586, testMethod = testQueryUserList@UsersDaoImplTest, testException = [null]]]
写完了,写的累死人了,这里用junit做spring组件的单元测试非常有用,希望很多做java的童鞋可以试试,另外我写的junit测试类是用注解的方式,这是junit4里才有的,有兴趣的童鞋可以学习下哈。
相关文章推荐
- java笔记:自己动手写javaEE框架(二)--业务层Service以及Service单元测试
- java笔记:自己动手写javaEE框架(四)--Spring事务管理学习
- java笔记:自己动手写javaEE框架(三)--引入SQL监控技术P6spy
- 自己动手设计java web框架(二)-自定义注解以及通过反射获取注解
- java笔记:自己动手写javaEE框架(七)--使用JSON和Ajax技术
- java笔记:自己动手写javaEE框架(六)--引入struts2框架
- java笔记:自己动手写javaEE框架(八)--为jqgrid换换皮肤然后加到我的框架里
- java笔记:自己动手写javaEE
- 【JAVA笔记——器】MyBatis映射以及DAO文件生成工具源码
- java笔记:自己动手写javaEE框架(五)--Spring事务管理学习
- java笔记:自己动手写javaEE框架(五)--Spring事务管理学习
- SSH 框架学习之初识Java中的Action、Dao、Service、Model—————————–学到就要查,自己动手动脑!!!
- [自己动手]用Java的反射实现DAO
- 学习笔记之自己动手写WEB服务器
- 最近仔细研究了一下Java的NIO以及线程并发,搞清了点思路,特作笔记如下(NIO篇)
- java properties 的六种读取方法 以及一种自己最方便的实现
- Java动态代理以及InvocationHandler中invoke()方法笔记
- Java笔记18:JUnit单元测试
- 7月22日总结的自己在java中犯的错误以及注意事项
- Java学习笔记45(多线程二:安全问题以及解决原理)