153、Spring支持的事务管理类型有哪些?你在项目中使用哪种方式?
答:Spring支持编程式事务管理和声明式事务管理。许多Spring框架的用户选择声明式事务管理,因为这种方式和应用程序的关联较少,因此更加符合轻量级容器的概念。声明式事务管理要优于编程式事务管理,尽管在灵活性方面它弱于编程式事务管理,因为编程式事务允许你通过代码控制业务。事务分为全局事务和局部事务。全局事务由应用服务器管理,需要底层服务器JTA支持(如WebLogic、WildFly等)。局部事务和底层采用的持久化方案有关,例如使用JDBC进行持久化时,需要使用Connetion对象来操作事务;而采用Hibernate进行持久化时,需要使用Session对象来操作事务。Spring提供了如下所示的事务管理器。
事务管理器实现类 | 目标对象 |
---|---|
DataSourceTransactionManager | 注入DataSource |
HibernateTransactionManager | 注入SessionFactory |
JdoTransactionManager | 管理JDO事务 |
JtaTransactionManager | 使用JTA管理事务 |
PersistenceBrokerTransactionManager | 管理Apache的OJB事务 |
这些事务的父接口都是PlatformTransactionManager。Spring的事务管理机制是一种典型的策略模式,PlatformTransactionManager代表事务管理接口,该接口定义了三个方法,该接口并不知道底层如何管理事务,但是它的实现类必须提供getTransaction()方法(开启事务)、commit()方法(提交事务)、rollback()方法(回滚事务)的多态实现,这样就可以用不同的实现类代表不同的事务管理策略。使用JTA全局事务策略时,需要底层应用服务器支持,而不同的应用服务器所提供的JTA全局事务可能存在细节上的差异,因此实际配置全局事务管理器是可能需要使用JtaTransactionManager的子类,如:WebLogicJtaTransactionManager(Oracle的WebLogic服务器提供)、UowJtaTransactionManager(IBM的WebSphere服务器提供)等。编程式事务管理如下所示。
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
|
<?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:p=
"http://www.springframework.org/schema/p"
xmlns:p=
"http://www.springframework.org/schema/context"
xsi:schemaLocation="http:
//www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http:
//www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-
package
=
"com.jackfrued"
/>
<bean id=
"propertyConfig"
class
="org.springframework.beans.factory.config.
PropertyPlaceholderConfigurer">
<property name=
"location"
>
<value>jdbc.properties</value>
</property>
</bean>
<bean id=
"dataSource"
class
=
"org.apache.commons.dbcp.BasicDataSource"
>
<property name=
"driverClassName"
>
<value>${db.driver}</value>
</property>
<property name=
"url"
>
<value>${db.url}</value>
</property>
<property name=
"username"
>
<value>${db.username}</value>
</property>
<property name=
"password"
>
<value>${db.password}</value>
</property>
</bean>
<bean id=
"jdbcTemplate"
class
=
"org.springframework.jdbc.core.JdbcTemplate"
>
<property name=
"dataSource"
>
<ref bean=
"dataSource"
/>
</property>
</bean>
<!-- JDBC事务管理器 -->
<bean id=
"transactionManager"
class
="org.springframework.jdbc.datasource.
DataSourceTransactionManager
" scope="
singleton">
<property name=
"dataSource"
>
<ref bean=
"dataSource"
/>
</property>
</bean>
<!-- 声明事务模板 -->
<bean id=
"transactionTemplate"
class
="org.springframework.transaction.support.
TransactionTemplate">
<property name=
"transactionManager"
>
<ref bean=
"transactionManager"
/>
</property>
</bean>
</beans>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@Repository
public
class
EmpDaoImpl
implements
EmpDao {
@Autowired
private
JdbcTemplate jdbcTemplate;
@Override
public
boolean
save(Emp emp) {
String sql =
"insert into emp values (?,?,?)"
;
return
jdbcTemplate.update(sql, emp.getId(), emp.getName(), emp.getBirthday()) ==
1
;
}
}
|
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
|
@Service
public
class
EmpServiceImpl
implements
EmpService {
@Autowired
private
TransactionTemplate txTemplate;
@Autowired
private
EmpDao empDao;
@Override
public
void
addEmp(
final
Emp emp) {
txTemplate.execute(
new
TransactionCallbackWithoutResult() {
@Override
protected
void
doInTransactionWithoutResult(TransactionStatus txStatus) {
empDao.save(emp);
}
});
}
}
|
声明式事务如下图所示,以Spring整合Hibernate 3为例,包括完整的DAO和业务逻辑代码。
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
|
<?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:p=
"http://www.springframework.org/schema/p"
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-3.2.xsd
http:
//www.springframework.org/schema/context
http:
//www.springframework.org/schema/context/spring-context-3.2.xsd
http:
//www.springframework.org/schema/aop
http:
//www.springframework.org/schema/aop/spring-aop-3.2.xsd
http:
//www.springframework.org/schema/tx
http:
//www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<!-- 配置由Spring IoC容器托管的对象对应的被注解的类所在的包 -->
<context:component-scan base-
package
=
"com.jackfrued"
/>
<!-- 配置通过自动生成代理实现AOP功能 -->
<aop:aspectj-autoproxy />
<!-- 配置数据库连接池 (DBCP) -->
<bean id=
"dataSource"
class
=
"org.apache.commons.dbcp.BasicDataSource"
destroy-method=
"close"
>
<!-- 配置驱动程序类 -->
<property name=
"driverClassName"
value=
"com.mysql.jdbc.Driver"
/>
<!-- 配置连接数据库的URL -->
<property name=
"url"
value=
"jdbc:mysql://localhost:3306/myweb"
/>
<!-- 配置访问数据库的用户名 -->
<property name=
"username"
value=
"root"
/>
<!-- 配置访问数据库的口令 -->
<property name=
"password"
value=
"123456"
/>
<!-- 配置最大连接数 -->
<property name=
"maxActive"
value=
"150"
/>
<!-- 配置最小空闲连接数 -->
<property name=
"minIdle"
value=
"5"
/>
<!-- 配置最大空闲连接数 -->
<property name=
"maxIdle"
value=
"20"
/>
<!-- 配置初始连接数 -->
<property name=
"initialSize"
value=
"10"
/>
<!-- 配置连接被泄露时是否生成日志 -->
<property name=
"logAbandoned"
value=
"true"
/>
<!-- 配置是否删除超时连接 -->
<property name=
"removeAbandoned"
value=
"true"
/>
<!-- 配置删除超时连接的超时门限值(以秒为单位) -->
<property name=
"removeAbandonedTimeout"
value=
"120"
/>
<!-- 配置超时等待时间(以毫秒为单位) -->
<property name=
"maxWait"
value=
"5000"
/>
<!-- 配置空闲连接回收器线程运行的时间间隔(以毫秒为单位) -->
<property name=
"timeBetweenEvictionRunsMillis"
value=
"300000"
/>
<!-- 配置连接空闲多长时间后(以毫秒为单位)被断开连接 -->
<property name=
"minEvictableIdleTimeMillis"
value=
"60000"
/>
</bean>
<!-- 配置Spring提供的支持注解ORM映射的Hibernate会话工厂 -->
<bean id=
"sessionFactory"
class
=
"org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
>
<!-- 通过setter注入数据源属性 -->
<property name=
"dataSource"
ref=
"dataSource"
/>
<!-- 配置实体类所在的包 -->
<property name=
"packagesToScan"
value=
"com.jackfrued.entity"
/>
<!-- 配置Hibernate的相关属性 -->
<property name=
"hibernateProperties"
>
<!-- 在项目调试完成后要删除show_sql和format_sql属性否则对性能有显著影响 -->
<value>
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
</value>
</property>
</bean>
<!-- 配置Spring提供的Hibernate事务管理器 -->
<bean id=
"transactionManager"
class
=
"org.springframework.orm.hibernate3.HibernateTransactionManager"
>
<!-- 通过setter注入Hibernate会话工厂 -->
<property name=
"sessionFactory"
ref=
"sessionFactory"
/>
</bean>
<!-- 配置基于注解配置声明式事务 -->
<tx:annotation-driven />
</beans>
|
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
|
/**
* 数据访问对象接口(以对象为单位封装CRUD操作)
* @author 骆昊
*
* @param <E> 实体类型
* @param <K> 实体标识字段的类型
*/
public
interface
BaseDao <E, K
extends
Serializable> {
/**
* 新增
* @param entity 业务实体对象
* @return 增加成功返回实体对象的标识
*/
public
K save(E entity);
/**
* 删除
* @param entity 业务实体对象
*/
public
void
delete(E entity);
/**
* 根据ID删除
* @param id 业务实体对象的标识
* @return 删除成功返回true否则返回false
*/
public
boolean
deleteById(K id);
/**
* 修改
* @param entity 业务实体对象
* @return 修改成功返回true否则返回false
*/
public
void
update(E entity);
/**
* 根据ID查找业务实体对象
* @param id 业务实体对象的标识
* @return 业务实体对象对象或null
*/
public
E findById(K id);
/**
* 根据ID查找业务实体对象
* @param id 业务实体对象的标识
* @param lazy 是否使用延迟加载
* @return 业务实体对象对象
*/
public
E findById(K id,
boolean
lazy);
/**
* 查找所有业务实体对象
* @return 装所有业务实体对象的列表容器
*/
public
List<E> findAll();
/**
* 分页查找业务实体对象
* @param page 页码
* @param size 页面大小
* @return 查询结果对象
*/
public
QueryResult<E> findByPage(
int
page,
int
size);
/**
* 分页查找业务实体对象
* @param queryBean 查询条件对象
* @param page 页码
* @param size 页面大小
* @return 查询结果对象
*/
public
QueryResult<E> findByPage(QueryBean queryBean,
int
page,
int
size);
}
|
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
|
/**
* BaseDao的缺省适配器
* @author 骆昊
*
* @param <E> 实体类型
* @param <K> 实体标识字段的类型
*/
public
abstract
class
BaseDaoAdapter<E, K
extends
Serializable>
implements
BaseDao<E, K> {
@Override
public
K save(E entity) {
return
null
;
}
@Override
public
void
delete(E entity) {
}
@Override
public
boolean
deleteById(K id) {
E entity = findById(id);
if
(entity !=
null
) {
delete(entity);
return
true
;
}
return
false
;
}
@Override
public
void
update(E entity) {
}
@Override
public
E findById(K id) {
return
null
;
}
@Override
public
E findById(K id,
boolean
lazy) {
return
null
;
}
@Override
public
List<E> findAll() {
return
null
;
}
@Override
public
QueryResult<E> findByPage(
int
page,
int
size) {
return
null
;
}
@Override
public
QueryResult<E> findByPage(QueryBean queryBean,
int
page,
int
size) {
return
null
;
}
}
|
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
/**
* 基于Hibernate的BaseDao实现类
* @author 骆昊
*
* @param <E> 实体类型
* @param <K> 主键类型
*/
@SuppressWarnings
(value = {
"unchecked"
})
public
abstract
class
BaseDaoHibernateImpl<E, K
extends
Serializable>
extends
BaseDaoAdapter<E, K> {
@Autowired
protected
SessionFactory sessionFactory;
private
Class<?> entityClass;
// 业务实体的类对象
private
String entityName;
// 业务实体的名字
public
BaseDaoHibernateImpl() {
ParameterizedType pt = (ParameterizedType)
this
.getClass().getGenericSuperclass();
entityClass = (Class<?>) pt.getActualTypeArguments()[
0
];
entityName = entityClass.getSimpleName();
}
@Override
public
K save(E entity) {
return
(K) sessionFactory.getCurrentSession().save(entity);
}
@Override
public
void
delete(E entity) {
sessionFactory.getCurrentSession().delete(entity);
}
@Override
public
void
update(E entity) {
sessionFactory.getCurrentSession().update(entity);
}
@Override
public
E findById(K id) {
return
findById(id,
false
);
}
@Override
public
E findById(K id,
boolean
lazy) {
Session session = sessionFactory.getCurrentSession();
return
(E) (lazy? session.load(entityClass, id) : session.get(entityClass, id));
}
@Override
public
List<E> findAll() {
return
sessionFactory.getCurrentSession().createCriteria(entityClass).list();
}
@Override
public
QueryResult<E> findByPage(
int
page,
int
size) {
return
new
QueryResult<E>(
findByHQLAndPage(
"from "
+ entityName , page, size),
getCountByHQL(
"select count(*) from "
+ entityName)
);
}
@Override
public
QueryResult<E> findByPage(QueryBean queryBean,
int
page,
int
size) {
if
(queryBean
instanceof
HQLQueryBean) {
HQLQueryBean hqlQueryBean = (HQLQueryBean) queryBean;
return
new
QueryResult<E>(
findByHQLAndPage(hqlQueryBean.getQueryString(), page, size, hqlQueryBean.getParameters()),
getCountByHQL(hqlQueryBean.getCountString(), hqlQueryBean.getParameters())
);
}
return
null
;
}
/**
* 根据HQL和可变参数列表进行查询
* @param hql 基于HQL的查询语句
* @param params 可变参数列表
* @return 持有查询结果的列表容器或空列表容器
*/
protected
List<E> findByHQL(String hql, Object... params) {
return
this
.findByHQL(hql, getParamList(params));
}
/**
* 根据HQL和参数列表进行查询
* @param hql 基于HQL的查询语句
* @param params 查询参数列表
* @return 持有查询结果的列表容器或空列表容器
*/
protected
List<E> findByHQL(String hql, List<Object> params) {
List<E> list = createQuery(hql, params).list();
return
list !=
null
&& list.size() >
0
? list : Collections.EMPTY_LIST;
}
/**
* 根据HQL和参数列表进行分页查询
* @param hql 基于HQL的查询语句
* @page 页码
* @size 页面大小
* @param params 可变参数列表
* @return 持有查询结果的列表容器或空列表容器
*/
protected
List<E> findByHQLAndPage(String hql,
int
page,
int
size, Object... params) {
return
this
.findByHQLAndPage(hql, page, size, getParamList(params));
}
/**
* 根据HQL和参数列表进行分页查询
* @param hql 基于HQL的查询语句
* @page 页码
* @size 页面大小
* @param params 查询参数列表
* @return 持有查询结果的列表容器或空列表容器
*/
protected
List<E> findByHQLAndPage(String hql,
int
page,
int
size, List<Object> params) {
List<E> list = createQuery(hql, params)
.setFirstResult((page -
1
) * size)
.setMaxResults(size)
.list();
return
list !=
null
&& list.size() >
0
? list : Collections.EMPTY_LIST;
}
/**
* 查询满足条件的记录数
* @param hql 基于HQL的查询语句
* @param params 可变参数列表
* @return 满足查询条件的总记录数
*/
protected
long
getCountByHQL(String hql, Object... params) {
return
this
.getCountByHQL(hql, getParamList(params));
}
/**
* 查询满足条件的记录数
* @param hql 基于HQL的查询语句
* @param params 参数列表容器
* @return 满足查询条件的总记录数
*/
protected
long
getCountByHQL(String hql, List<Object> params) {
return
(Long) createQuery(hql, params).uniqueResult();
}
// 创建Hibernate查询对象(Query)
private
Query createQuery(String hql, List<Object> params) {
Query query = sessionFactory.getCurrentSession().createQuery(hql);
for
(
int
i =
0
; i < params.size(); i++) {
query.setParameter(i, params.get(i));
}
return
query;
}
// 将可变参数列表组装成列表容器
private
List<Object> getParamList(Object... params) {
List<Object> paramList =
new
ArrayList<>();
if
(params !=
null
) {
for
(
int
i =
0
; i < params.length; i++) {
paramList.add(params[i]);
}
}
return
paramList.size() ==
0
? Collections.EMPTY_LIST : paramList;
}
}
|
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
|
/**
* 查询条件的接口
* @author 骆昊
*
*/
public
interface
QueryBean {
/**
* 添加排序字段
* @param fieldName 用于排序的字段
* @param asc 升序还是降序
* @return 查询条件对象自身(方便级联编程)
*/
public
QueryBean addOrder(String fieldName,
boolean
asc);
/**
* 添加排序字段
* @param available 是否添加此排序字段
* @param fieldName 用于排序的字段
* @param asc 升序还是降序
* @return 查询条件对象自身(方便级联编程)
*/
public
QueryBean addOrder(
boolean
available, String fieldName,
boolean
asc);
/**
* 添加查询条件
* @param condition 条件
* @param params 替换掉条件中参数占位符的参数
* @return 查询条件对象自身(方便级联编程)
*/
public
QueryBean addCondition(String condition, Object... params);
/**
* 添加查询条件
* @param available 是否需要添加此条件
* @param condition 条件
* @param params 替换掉条件中参数占位符的参数
* @return 查询条件对象自身(方便级联编程)
*/
public
QueryBean addCondition(
boolean
available, String condition, Object... params);
/**
* 获得查询语句
* @return 查询语句
*/
public
String getQueryString();
/**
* 获取查询记录数的查询语句
* @return 查询记录数的查询语句
*/
public
String getCountString();
/**
* 获得查询参数
* @return 查询参数的列表容器
*/
public
List<Object> getParameters();
}
|
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
|
package
com.jackfrued.comm;
import
java.util.List;
/**
* 查询结果
* @author 骆昊
*
* @param <T> 泛型参数
*/
public
class
QueryResult<T> {
private
List<T> result;
// 持有查询结果的列表容器
private
long
totalRecords;
// 查询到的总记录数
public
QueryResult() {
}
/**
* 构造器
* @param result 持有查询结果的列表容器
* @param totalRecords 查询到的总记录数
*/
public
QueryResult(List<T> result,
long
totalRecords) {
this
.result = result;
this
.totalRecords = totalRecords;
}
public
List<T> getResult() {
return
result;
}
public
void
setResult(List<T> result) {
this
.result = result;
}
public
long
getTotalRecords() {
return
totalRecords;
}
public
void
setTotalRecords(
long
totalRecords) {
this
.totalRecords = totalRecords;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public
interface
DeptDao
extends
BaseDao<Dept, Integer> {
/**
* 分页查询顶级部门
* @param page 页码
* @param size 页码大小
* @return 查询结果对象
*/
public
QueryResult<Dept> findTopDeptByPage(
int
page,
int
size);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package
com.jackfrued.dao.impl;
import
java.util.List;
import
org.springframework.stereotype.Repository;
import
com.jackfrued.comm.QueryResult;
import
com.jackfrued.dao.BaseDaoHibernateImpl;
import
com.jackfrued.dao.DeptDao;
import
com.jackfrued.entity.Dept;
@Repository
public
class
DeptDaoImpl
extends
BaseDaoHibernateImpl<Dept, Integer>
implements
DeptDao {
private
static
final
String HQL_FIND_TOP_DEPT =
" from Dept as d where d.superiorDept is null "
;
@Override
public
QueryResult<Dept> findTopDeptByPage(
int
page,
int
size) {
List<Dept> list = findByHQLAndPage(HQL_FIND_TOP_DEPT, page, size);
long
totalRecords = getCountByHQL(
" select count(*) "
+ HQL_FIND_TOP_DEPT);
return
new
QueryResult<>(list, totalRecords);
}
}
|
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
|
package
com.jackfrued.comm;
import
java.util.List;
public
class
PageBean<T> {
private
static
final
int
DEFAUL_INIT_PAGE =
1
;
private
static
final
int
DEFAULT_PAGE_SIZE =
10
;
private
static
final
int
DEFAULT_PAGE_COUNT =
5
;
private
List<T> data;
// 分页数据
private
PageRange pageRange;
// 页码范围
private
int
totalPage;
// 总页数
private
int
size;
// 页面大小
private
int
currentPage;
// 当前页码
private
int
pageCount;
// 页码数量
/**
* 构造器
* @param currentPage 当前页码
* @param size 页码大小
* @param pageCount 页码数量
*/
public
PageBean(
int
currentPage,
int
size,
int
pageCount) {
this
.currentPage = currentPage >
0
? currentPage :
1
;
this
.size = size >
0
? size : DEFAULT_PAGE_SIZE;
this
.pageCount = pageCount >
0
? size : DEFAULT_PAGE_COUNT;
}
/**
* 构造器
* @param currentPage 当前页码
* @param size 页码大小
*/
public
PageBean(
int
currentPage,
int
size) {
this
(currentPage, size, DEFAULT_PAGE_COUNT);
}
/**
* 构造器
* @param currentPage 当前页码
*/
public
PageBean(
int
currentPage) {
this
(currentPage, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_COUNT);
}
/**
* 构造器
*/
public
PageBean() {
this
(DEFAUL_INIT_PAGE, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_COUNT);
}
public
List<T> getData() {
return
data;
}
public
int
getStartPage() {
return
pageRange !=
null
? pageRange.getStartPage() :
1
;
}
public
int
getEndPage() {
return
pageRange !=
null
? pageRange.getEndPage() :
1
;
}
public
long
getTotalPage() {
return
totalPage;
}
public
int
getSize() {
return
size;
}
public
int
getCurrentPage() {
return
currentPage;
}
/**
* 将查询结果转换为分页数据
* @param queryResult 查询结果对象
*/
public
void
transferQueryResult(QueryResult<T> queryResult) {
long
totalRecords = queryResult.getTotalRecords();
data = queryResult.getResult();
totalPage = (
int
) ((totalRecords + size -
1
) / size);
totalPage = totalPage >=
0
? totalPage : Integer.MAX_VALUE;
this
.pageRange =
new
PageRange(pageCount, currentPage, totalPage);
}
}
|
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
|
package
com.jackfrued.comm;
public
class
PageRange {
private
int
startPage;
// 起始页码
private
int
endPage;
// 终止页码
/**
* 构造器
* @param pageCount 总共显示几个页码
* @param currentPage 当前页码
* @param totalPage 总页数
*/
public
PageRange(
int
pageCount,
int
currentPage,
int
totalPage) {
startPage = currentPage - (pageCount -
1
) /
2
;
endPage = currentPage + pageCount /
2
;
if
(startPage <
1
) {
startPage =
1
;
endPage = totalPage > pageCount ? pageCount : totalPage;
}
if
(endPage > totalPage) {
endPage = totalPage;
startPage = (endPage - pageCount >
0
) ? endPage - pageCount +
1
:
1
;
}
}
public
int
getStartPage() {
return
startPage;
}
public
int
getEndPage() {
return
endPage;
}
}
|
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
|
package
com.jackfrued.biz;
import
com.jackfrued.comm.PageBean;
import
com.jackfrued.entity.Dept;
/**
* 部门业务逻辑接口
* @author 骆昊
*
*/
public
interface
DeptService {
/**
* 创建新的部门
* @param department 部门对象
* @return 创建成功返回true否则返回false
*/
public
boolean
createNewDepartment(Dept department);
/**
* 删除指定部门
* @param id 要删除的部门的编号
* @return 删除成功返回true否则返回false
*/
public
boolean
deleteDepartment(Integer id);
/**
* 分页获取顶级部门
* @param page 页码
* @param size 页码大小
* @return 部门对象的分页器对象
*/
public
PageBean<Dept> getTopDeptByPage(
int
page,
int
size);
}
|
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
|
@Service
@Transactional
// 声明式事务的注解
public
class
DeptServiceImpl
implements
DeptService {
@Autowired
private
DeptDao deptDao;
@Override
public
boolean
createNewDepartment(Dept department) {
return
deptDao.save(department) !=
null
;
}
@Override
public
boolean
deleteDepartment(Integer id) {
return
deptDao.deleteById(id);
}
@Override
public
PageBean<Dept> getTopDeptByPage(
int
page,
int
size) {
QueryResult<Dept> queryResult = deptDao.findTopDeptByPage(page, size);
PageBean<Dept> pageBean =
new
PageBean<>(page, size);
pageBean.transferQueryResult(queryResult);
return
pageBean;
}
}
|