JavaEE中分层解耦合与事物控制-方案
转载请注明出处:
http://blog.csdn.net/u010825468/article/details/49434803
0、写在前面
很多年前,依靠李兴华的《Java WEB开发实战经典》一书,开启了Java WEB之旅,个人认为这本书作为JavaEE入门非常不错,李兴华的视频讲的也很不错,或许大家现在都在看《*疯狂讲义》或是培训机构的教学视频,但经典始终是经典。
我在学习完JavaEE后没有真正从事过JavaEE开发的正式工作,大多只是平常自己写点东西,或是帮别人写点小应用之类的,两年后大学毕业,我也正式的转入了Android开发阵营,我对Android开发的理解大致为:如果我不在Android上做深入了解与学习,其实我就是个写前台的。但是好在有WEB的基础与WEB锻炼的Java技能,开发Android其实非常简单。
1、为什么要分层
学习过JavaEE基础的人都知道MVC,这是传统的JavaEE的设计模式,MVC即将工程或者说代码分成Model、View、Controller三层。Model即模型层,一般包括Java Bean以及这些bean对应的数据库的原子性操作方法(一般的CRUD、getAll、findByXXX、delByXXX),而这些数据库操作就是我们熟悉的DAO。我们一般将bean包命名为VO或者domain,dao操作包命名为dao。View即显示层,在JavaEE中可以将其看作Jsp,用于和用户产生动态交互的界面,是通过服务器编译才能进行显示的,关于Jsp的更多我们在后面详解。Controller即控制层,用来控制业务的流转,比如一个servlet,能够接受用户通过View提交的数据,然后根据自己的业务规则去调用不同的service(service属于控制层,是对每一个具体业务操作事物的封装,通过service调用dao),因此Controller是介于Model和View之间的桥梁,也是业务流转的核心。
解释了MVC,那我们为什么需要对代码结构进行分层呢?主要有以下几个方面的考虑:
- 解耦和:我们将一个业务流转和数据库操作分离开来,既符合面向对象的编程原则,又将代码逻辑整理的很清楚,在调试过程中也能方便改正BUG,体现了高内聚,低耦合的思想;
- 业务拆分:有时候我们一个接口需要处理的业务很复杂,通过分层能够将业务分为具体的某一类业务,然后对这一类业务的具体处理逻辑拆分为多次调用dao进行完成,让复杂的逻辑简单化了;
- 便于接口升级:各层之间通过接口进行解耦操作,也就是将接口和具体实现进行了分离,这样可以方便的实现或替换掉具体实现;
- 提高代码服用率:作为一个程序猿,我们不应该造重复的轮子,在一个系统中Model层是对数据库的原子性操作,复用性最高。假如我们更换了数据库,只要保证访问数据的接口方法不发生变化,我们也能够很快的实现对不同数据库的操作。
2、我的分层模式
个人一般将代码结构分为DAO、Service、Controller、View四层,dao和service都使用接口和真是实现类的方式,DAO、Service、Controller之间通过工厂类和配置文件进行解耦和。
3、Demo
在这个demo中我使用了struts2.3、c3p0、dbutils等常用的工具。包结构如下:
1.domain包里都是javabean,这里就不给代码了;
2.dao包里是对数据库的基础操作方法,其中有一个名为Dao的接口,只作为一个标识(后面在工厂类用到),没有定义方法和变量,以UserDao为例,UserDao接口继承自Dao(所有的dao类接口都需要继承自Dao),UserDaoImpl为真实实现类,继承自UserDaoDao。
public interface UserDao extends Dao {
/**
* 根据用户名查找用户
* @param username 用户名
* @return 找到的用户bean,如果没找到返回null
*/
User findUserByUName(String username);
/**
* 增加用户
* @param user 封装了用户信息的bean
*/
void addUser(User user);
/**
* 根据用户名 密码 查找用户
* @param username 用户名
* @param password 密码
* @return 找到的用户 ,如果找不到返回null
*/
User findUserByUNameAndPsw(String username, String password);
----------
}
public class UserDaoImpl implements UserDao {
@Override
public User findUserByUName(String username) {
String sql = "select * from users where userName = ?";
try {
QueryRunner runner = new QueryRunner(DaoUtils.getSource());
return runner.query(sql, new BeanHandler<User>(User.class), username);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Override
public void addUser(User user) {
String sql = "insert into users values (null,?,?)";
try {
QueryRunner runner = new QueryRunner(DaoUtils.getSource());
runner.update(sql, user.getUserName(), user.getPassword());
} catch (SQLException e) {
e.printStackTrace();
throw new Runti