hibernate+spring架构有感

来源:互联网 发布:怎么避免mac涂层脱落 编辑:程序博客网 时间:2024/06/04 19:57

前言:

众所周知,一个web项目的架构非常重要,一个优秀的架构不仅让系统能够顺畅的运行,同时也能够极大的提高程序员对web工程的认知以及掌握。

架构分层:

一般来说一个学完Struts+Hibernate+Spring的人都能够说出来大致的框架,一般分为实体层: 叫做bean, model, domain等等,但是都代表着同一种意思,都是实体对象的象征。持久化接口层: 一般叫做Dao,这里面会把对数据库的一般操作抽象定义出来成为接口层(增删改查等等)。持久化实现层: 一般叫做DaoImpl,这里面会对接口层进行实现,负责真正的持久化访问功能。业务逻辑层:一般较作service层,业务逻辑层组件依赖于底层的Dao组件(也就是HIbernteaDao层),该层专注于提供业务逻辑功能,不涉及持久化访问。键值层: 一般较作vo层,亦或是dto曾,代表的是,该曾定义的对象,仅仅是作为数据传输所使用的。web层: 一般也就叫做web层,是前台访问与调用业务逻辑组件的地方,也是操作最为复杂的核心地带。这里完成前台的操作以及响应。加载中...之所以今天会写这篇博客,就是因为这个album的小项目对自己的架构概念有了新的感觉。可以很清楚的看到album包的分层。其中 Z喎�"http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcmcuYWxidW0uYmVhbiC21NOm18XKtczlsuNvcmcuYWxidW0uc2VydmljZbbU06bXxdK1zvHC37ytsuO1xLPpz/OjrLb4b3JnLmFsYnVtLnNlcnZpY2UuaW1wbMrH0rXO8cLfvK2y47XE1ebV/cq1z9ZvcmcuYWx1Ym0udm+21NOm18W8/CYjMjA1NDA7suNvcmcuYWxidW0ud2VittTTptfFd2VisuNvcmcuY29tbW9uLmRhb7rNb3JnLmFsYnVtLmRhb7bU06bXxUhpYmVybmF0Zb3Tv9qy429yZy5jb21tb24uZGFvLmltcGy6zW9yZy5hbGJ1bS5kYW8uaW1wbLbU06bXxUhpYmVybnRhZbXEyrXP1rLjoaMg1eLA79Pryc/OxMu1tcTT0Mv5srvSu9bCo6zPws7Eu+G4+LP2y7XD96GjCgo8L2Jsb2NrcXVvdGU+CjxibG9ja3F1b3RlPgo8aDQ+PHN0cm9uZz631rLjtPrC68/qveKjujwvc3Ryb25nPjwvaDQ+CjxibG9ja3F1b3RlPgo8aDU+YmVhbrLjo7o8L2g1Pgo8L2Jsb2NrcXVvdGU+CjxibG9ja3F1b3RlPgo8YmxvY2txdW90ZT4KPHA+08nT2rn909q88rWlvs2yu9TZ1eLA78z5s/Y8L3A+CjwvYmxvY2txdW90ZT4KPGg1PrPWvsO7r7LjOjwvaDU+CjwvYmxvY2txdW90ZT4KPC9ibG9ja3F1b3RlPgo8YmxvY2txdW90ZT4KPGJsb2NrcXVvdGU+CjxibG9ja3F1b3RlPgo8cD4oMSm5stDUtcQ8YnI+CjwvcD4KPHA+1eLA76OsuPzOqrzyveC31sP3tcS9q7TLsuO31r3izqpjb21tb24uZGFvo6i0+rHtubLQ1NO109C1xKOpus1hbGJ1bS5kYW+jqLTLz+7Ev7WltsDTtdPQtcSjqTwvcD4Kb3JnLmNvbW1vbi5kYW8uQmFzZURhbyC0y7Lj1tCw/MCowctISWJlcm5hdGW21Mr9vt2/4rXEuPfW1rv5tKG1xLPWvsO7r7LZ1/ejrLT6wuvI58/CPHByZSBjbGFzcz0="brush:java;">/** * 通用DAO组件的接口,这七个通用方法是所有DAO组件都应该提供的 * @author administrator * */ public interface BaseDao { /** * 根据ID加载实体 * @param entityClazz 实体类 * @param entityId 实体ID */ T get(Class entityClazz, Serializable entityId); /** * 保存实体 * @param entity 实体 */ Serializable save(T entity); /** * 更新实体 * @param entity 实体 */ void update(T entity); /** * 删除实体 * @param entity 实体 */ void delete(T entity); /** * 根据ID删除实体 * @param entityClazz 实体类 * @param entityId 实体Id */ void delete(ClassentityClazz, Serializable entityId); /** * 根据ID数组删除实体 * @param entityClazz 实体类 * @param entityIds 实体Id数组 */ void delete(ClassentityClazz, Serializable[] entityIds); /** * 获取所有实体 * @param entityClazz 实体类 */ List getAll(Class entityClazz); /** * 获取实体总数 * @param entityClazz 实体类 * @return */ Long getCount(Class entityClazz); } 接下来是org.common.dao.impl.BaseDaoHibernate4,它是对各种操作的基础性的实现,以下是代码
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/**
 * 通用DAO组件的实现类
 * @author administrator
 *
 * @param <t>
 */
publicclass BaseDaoHiberante4<t> implementsBaseDao<t> {
 
    /**
     * DAO组件进行持久化操作底层依赖的sessionFactory组件
     */
    privateSessionFactory sessionFactory;
     
     
    /**
     * 无参构造器
     */
    publicBaseDaoHiberante4() {
        // TODO Auto-generated constructor stub
    }
 
    @SuppressWarnings("unchecked")
    @Override
    publicT get(Class<t> entityClazz, Serializable entityId) {
        // TODO Auto-generated method stub
        return(T) this.getSessionFactory().getCurrentSession().get(entityClazz, entityId);
         
    }
 
    @Override
    publicSerializable save(T entity) {
        // TODO Auto-generated method stub
        returnthis.getSessionFactory().getCurrentSession().save(entity);
    }
 
    @Override
    publicvoid update(T entity) {
        // TODO Auto-generated method stub
        this.getSessionFactory().getCurrentSession().saveOrUpdate(entity);
    }
 
    @Override
    publicvoid delete(T entity) {
        // TODO Auto-generated method stub
        this.getSessionFactory().getCurrentSession().delete(entity);
    }
 
    @Override
    publicvoid delete(Class<t> entityClazz, Serializable entityId) {
        // TODO Auto-generated method stub
        delete(entityClazz,newSerializable[]{entityId});
    }
 
    @Override
    publicvoid delete(Class<t> entityClazz, Serializable[] entityIds) {
        // TODO Auto-generated method stub
        // 遍历删除
        for(Serializable serializable : entityIds) {
            delete(get(entityClazz, serializable));
        }
         
    }
     
    @Override
    publicList<t> getAll(Class<t> entityClazz) {
        // TODO Auto-generated method stub
        returnfind("select en from " + entityClazz.getSimpleName() + " en");
    }
 
    @SuppressWarnings("rawtypes")
    @Override
    publicLong getCount(Class<t> entityClazz) {
        // TODO Auto-generated method stub
        List list = find("select count(*) from " + entityClazz.getSimpleName());
        // 查询得到的实体总数,增加合法性的判断
        if(list != null&& list.size() == 1) {
            return(Long)list.get(0);
        }
        return(long)0;
    }
 
    /**
     * 根据HQL语句查询实体
     * @param hql
     * @return
     */
    @SuppressWarnings("unchecked")
    protectedList<t> find(String hql) {
        return(List<t>)this.getSessionFactory().getCurrentSession().createQuery(hql).list();
    }
     
    /**
     * 根据带占位符参数HQL语句查询实体
     * @param hql
     * @param params
     * @return
     */
    @SuppressWarnings("unchecked")
    protectedList<t> find(String hql, Object...params){
        // 创建查询
        Query query = this.getSessionFactory().getCurrentSession().createQuery(hql);
        // 为包含占位符的HQL语句设置参数
        for(inti = 0, len = params.length; i < len ; i++) {
            query.setParameter(i, params[i]);
        }
        return(List<t>)query.list();
         
    }
     
    /**
     * 使用HQL语句进行分页查询操作
     * @param hql    需要查询的HQL语句
     * @param pageNo 查询第pageNo页记录
     * @param pageSize 每页需要显示的记录数
     * @return
     */
    @SuppressWarnings("unchecked")
    protectedList<t> findByPage(String hql, intpageNo, intpageSize) {
        // 创建查询
        returnthis.getSessionFactory().getCurrentSession().createQuery(hql).setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).list();
    }
     
    /**
     * 使用HQL语句进行分页查询操作
     * @param hql    需要查询的HQL语句
     * @param pageNo 查询第pageNo页记录
     * @param pageSize 每页需要显示的记录数
     * @param params    如果hql带占位符参数,params用于传入占位符
     * @return
     */
    @SuppressWarnings("unchecked")
    protectedList<t> findByPage(String hql, intpageNo, intpageSize, Object...params) {
        // 创建查询
        Query query = this.getSessionFactory().getCurrentSession().createQuery(hql);
        for(inti = 0, len = params.length; i < len; i++) {
            query.setParameter(i, params[i]);
        }
        // 执行分页,并返回查询结果
        returnquery.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).list();
         
    }
     
    publicSessionFactory getSessionFactory() {
        returnsessionFactory;
    }
 
    publicvoid setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
 
}
<preclass="brush:java;"> 上述代码有过学习经验的都应该搞定,此处就不再详加解释</pre><br>
<preclass="brush:java;"></pre>
</t></t></t></t></t></t></t></t></t></t></t></t></t></t></t>

(2)特殊性的

由于项目为alubm,为了更加贴合项目本身,又有了,org.album.dao和org.album.dao.impl,以下是代码

UserDao.java,仅仅是由于项目实际对其的接口进行乐扩充

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * User的Dao
 * @author administrator
 *
 */
publicinterface UserDao extendsBaseDao<user> {
     
    /**
     * 根据用户名查找用户
     * @param name  需要查找的用户的用户名
     * @return      查找到的用户
     */
    User findByName(String name);
}</user>
接下来是,org.album.dao.impl.UserDaoHibernate.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
 * UserDao组件的实现类代码
 * @author administrator
 *
 */
publicclass UserDaoHibernate extendsBaseDaoHiberante4<user> implementsUserDao{
 
    @Override
    publicUser findByName(String name) {
        // TODO Auto-generated method stub
        List<user> users = find("select u from User u where u.name = ?", name);
        if(users != null&& users.size() == 1) {
            returnusers.get(0);
        }
        returnnull;
    }
 
     
}</user></user>

Service层:

在Service层中,也分为了,接口与实现的分开,更大限度的解偶,以下是org.album.service.AlbumService.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/**
 * 业务逻辑组件依赖于底层的DAO组件,由DAO组件负责提供持久化的访问功能
 * ,而业务逻辑组件则专注于提供业务逻辑功能
 * @author administrator
 *
 */
publicinterface AlbumService {
 
    /**
     * 验证用户登录是否成功。
     * @param name  登录的用户名
     * @param pass  登录的密码
     * @return      用户登录的结果,成功返回true,否则返回false
     */
    booleanuserLogin(String name, String pass);
     
    /**
     * 注册新用户
     * @param name  新注册用的用户名
     * @param pass  新注册用户的密码
     * @return      新注册用户的主键
     */
    intregistUser(String name, String pass);
     
    /**
     * 添加照片
     * @param user  添加相片的用户
     * @param title 添加相片的标题
     * @param fileName  新增相片在服务器上的名称
     * @return      新添加相片的主键
     */
    intaddPhoto(String user, String title, String fileName);
     
    /**
     * 根据用户获得该用户的所有相片
     * @param user      当前用户
     * @param pageNo    页码
     * @return          返回属于该用户/指定页的相片
     */
    List<photoholder> getPhotoByUser(String user, intpageNo);
     
    /**
     * 验证用户名是否可用,即数据库里是否已经存在该用户名
     * @param name  需要校验的用户名
     * @return      如果该用户名可用,返回true,否则返回false
     */
    booleanvalidateName(String name);
     
}
</photoholder>

接下来是对其的实现,AlbumServiceImpl.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
 * @author administrator
 *
 */
publicclass AlbumServiceImpl implementsAlbumService {
 
    /**
     * 业务组件所依赖的DAO组件
     */
    privateUserDao userDao = null;
     
    /**
     * 业务组件所依赖的DAO组件
     */
    privatePhotoDao photoDao = null;
     
    @Override
    publicboolean userLogin(String name, String pass) {
        try{
            // 使用UserDao根据用户名查询用户
            User user = userDao.findByName(name);
            if(user != null&& user.getPass().equals(pass)) {
                returntrue;
            }
            returnfalse;
        }catch(Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            thrownew AlbumException("处理用户登录出现异常");
        }
    }
 
    @Override
    publicint registUser(String name, String pass) {
        // TODO Auto-generated method stub
        try{
            // 创建一个新的User实例
            User user = newUser();
            user.setName(name);
            user.setPass(pass);
            // 持久化数据
            userDao.save(user);
            returnuser.getId();
        }catch(Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            thrownew AlbumException("新用户注册出现异常");
        }
    }
 
    @Override
    publicint addPhoto(String user, String title, String fileName) {
        // TODO Auto-generated method stub
        try{
            // 创建一个新的Photo实例
            Photo photo = newPhoto();
            photo.setTitle(title);
            photo.setFileName(fileName);
            photo.setUser(userDao.findByName(user));
            // 持久化Photo实例
            photoDao.save(photo);
            returnphoto.getId();
        }catch(Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            thrownew AlbumException("添加相片过程中出现异常!");
        }
    }
 
    @Override
    publicList<photoholder> getPhotoByUser(String user, intpageNo) {
        // TODO Auto-generated method stub
        try{
            List<photo> photos = photoDao.findByUser(userDao.findByName(user), pageNo);
            List<photoholder> result = newArrayList<photoholder>();
            for(Photo photo : photos) {
                result.add(newPhotoHolder(photo.getTitle(), photo.getFileName()));
            }
            returnresult;
        }catch(Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            thrownew AlbumException("查询相片列表的过程中出现异常");
        }
    }
 
    @Override
    publicboolean validateName(String name) {
        // TODO Auto-generated method stub
        try{
            // 根据用户名查询对应的User实例
            User  user = userDao.findByName(name);
            if(user != null) {
                returnfalse;
            }
            returntrue;
        }catch(Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            thrownew AlbumException("验证用户名是否存在的过程中出现异常");
        }
    }
     
    publicUserDao getUserDao() {
        returnuserDao;
    }
 
    publicvoid setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
 
    publicPhotoDao getPhotoDao() {
        returnphotoDao;
    }
 
    publicvoid setPhotoDao(PhotoDao photoDao) {
        this.photoDao = photoDao;
    }
}
</photoholder></photoholder></photo></photoholder>

键值层:

键值层仅仅是作为数据传输所使用的,以下是org.album.vo

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
 * @author administrator
 *
 */
publicclass PhotoHolder {
 
    /**
     * 相片的名称
     */
    privateString title;
     
    /**
     * 相片在服务器上的文件名
     */
    privateString fileName;
     
    /**
     * 无参构造器
     */
    publicPhotoHolder(){
         
    }
     
    /**
     * 初始化全部属性的构造器
     * @param title
     * @param fileName
     */
    publicPhotoHolder(String title, String fileName) {
        this.title = title;
        this.fileName = fileName;
    }
 
    publicString getTitle() {
        returntitle;
    }
 
    publicvoid setTitle(String title) {
        this.title = title;
    }
 
    publicString getFileName() {
        returnfileName;
    }
 
    publicvoid setFileName(String fileName) {
        this.fileName = fileName;
    }
}

web层:

此处是,前台请求与业务逻辑交汇的地方。是业务逻辑的处理就不再贴出

0 0
原创粉丝点击