hibernate

Chinasb's Blog

首页
Google App Engine
Ralasafe
开发手册
Spring注解大全
OFC2
NoSQL实战
蚂蚁运动
Browsing: / Home / 2011 / 六月 / spring2.5整合hibernate3.3的泛型Dao并加入spring jdbc的支持
Print Email Shortlink
spring2.5整合hibernate3.3的泛型Dao并加入spring jdbc的支持
BY ETHAN ON 2011 年 06 月 01 日 IN JAVA
原文链接:http://blog.csdn.net/tom_221x/archive/2009/08/22/4473873.aspx

以前写的一个改进版泛型dao,在这里 。基本实现了0代码编写dao。现在又加入了spring jdbc的支持,使得dao即可以用实体对象进行数据存取,有可以用jdbc的底层化操作删除,更新。结构见图:




具体代码和上图对应:

DaoTest.java

01
package com.test;
02
import javax.annotation.Resource;
03
import org.junit.Test;
04
import org.junit.runner.RunWith;
05
import org.springframework.test.context.ContextConfiguration;
06
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
07
import com.hibernate.entityclass.Daotest;
08
import com.tinylight.dao.base.IBaseDao;
09
@RunWith(SpringJUnit4ClassRunner.class)
10
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
11
public class DaoTest {
12

13
@Resource(name="demoDao")
14
private IBaseDao<Daotest,Integer> demoDao;
15

16
@Test
17
public void test(){
18

19
}
20
}
BaseDao.java

001
/**
002
*
003
*/
004
package com.tinylight.dao.base;
005
import java.io.Serializable;
006
import java.util.Iterator;
007
import java.util.List;
008
import org.hibernate.Query;
009
import org.hibernate.SQLQuery;
010
import org.hibernate.Session;
011
import org.hibernate.StatelessSession;
012
import org.springframework.orm.hibernate3.HibernateTemplate;
013
import com.tinylight.dao.hibernate.GenericDao;
014
import com.tinylight.dao.hibernate.GenericEntityDao;
015
import com.tinylight.dao.jdbc.SimpleJdbcDao;
016
import com.tinylight.dao.support.Page;
017
/**
018
* @author scott.Cgi
019
* @since 2009-5-12
020
* 提供dao的所有操作<br>
021
* 实现类由spring注入:<br>
022
* {@link com.tinylight.dao.hibernate.GenericEntityDao}
023
* {@link com.tinylight.dao.hibernate.GenericDao}
024
* {@link com.tinylight.dao.jdbc.SimpleJdbcDao}
025
*/
026
public class BaseDao<T,PK extends Serializable> implements IBaseDao<T,PK>{
027
protected Class<T> entityClass;// DAO所管理的Entity类型.
028
private GenericEntityDao<T,PK> gedao;
029
private GenericDao gdao;
030
private SimpleJdbcDao sjdao;
031

032
public Class<T> getEntityClass() {return entityClass;}
033
public void setEntityClass(Class<T> entityClass) {this.entityClass = entityClass;}
034

035
public GenericEntityDao<T, PK> getGedao() {return gedao;}
036
public void setGedao(GenericEntityDao<T, PK> gedao) {this.gedao = gedao;}
037

038
public GenericDao getGdao() {return gdao;}
039
public void setGdao(GenericDao gdao) {this.gdao = gdao;}
040

041
public SimpleJdbcDao getSjdao() {return sjdao;}
042
public void setSjdao(SimpleJdbcDao sjdao) {this.sjdao = sjdao;}
043
/**
044
*让spring提供构造函数注入
045
*/
046
public BaseDao(Class<T> type) {
047
this.entityClass = type;
048
}
049

050
public BaseDao(){}
051

052
public void clear() {
053
gdao.clear();
054
}
055

056
public Query createQuery(String hql, Object... values) {
057
return gdao.createQuery(hql, values);
058
}
059

060
public void delete(T entityObject) {
061
gedao.delete(entityObject);
062
}
063

064
public void deleteById(PK id) {
065
gedao.deleteById(id);
066
}
067

068
public void evict(T entityObject) {
069
gedao.evict(entityObject);
070
}
071

072
public List<T> find(String hql, Object... values) {
073
return gdao.find(hql, values);
074
}
075

076
public List<T> findByNamedParams(String hql, String[] paramNames,
077
Object... values) {
078
return gdao.findByNamedParams(hql, paramNames, values);
079
}
080

081
public void flush() {
082
gdao.flush();
083
}
084

085
public List<T> getAll() {
086
return gedao.getAll();
087
}
088

089
public T getById(PK id) {
090
return gedao.getById(id);
091
}
092

093
public Session getNativeHibernateSession() {
094
return gdao.getNativeHibernateSession();
095
}
096

097
public StatelessSession getNativeStatelessHibernateSession() {
098
return gdao.getNativeStatelessHibernateSession();
099
}
100

101
public HibernateTemplate getSpringHibernateTemplate() {
102
return gdao.getSpringHibernateTemplate();
103
}
104

105
public Iterator<T> iterator(String hql, Object... values) {
106
return gdao.iterator(hql, values);
107
}
108

109
public SimpleJdbcDao jdbc() {
110
return sjdao;
111
}
112

113
public T load(PK id) {
114
return gedao.load(id);
115
}
116

117
public void load(T entityObject, PK id) {
118
gedao.load(entityObject, id);
119
}
120

121
public T merge(T entityObject) {
122
return gedao.merge(entityObject);
123
}
124

125
public SQLQuery nativeSqlQuery(String sql) {
126
return gdao.nativeSqlQuery(sql);
127
}
128

129
public Page<T> pagedQuery(String countHql,String hql, int pageNo, int pageSize,
130
Object... values) {
131
return gdao.pagedQuery(countHql,hql, pageNo, pageSize, values);
132
}
133

134
public Page<T> pagedQueryByStartNo(String countHql,String hql, int startNo, int pageSize,
135
Object... values) {
136
return gdao.pagedQueryByStartNo(countHql,hql, startNo, pageSize, values);
137
}
138

139
public void refresh(T entityObject) {
140
gedao.refresh(entityObject);
141
}
142

143
public void save(T entityObject) {
144
gedao.save(entityObject);
145
}
146

147
}
IBaseDao.java

001
/**
002
*
003
*/
004
package com.tinylight.dao.base;
005
import java.io.Serializable;
006
import java.util.Iterator;
007
import java.util.List;
008
import org.hibernate.Query;
009
import org.hibernate.SQLQuery;
010
import org.hibernate.Session;
011
import org.hibernate.StatelessSession;
012
import org.springframework.orm.hibernate3.HibernateTemplate;
013
import com.tinylight.dao.jdbc.SimpleJdbcDao;
014
import com.tinylight.dao.support.Page;
015
/**
016
* @author scott.Cgi
017
* @since 2009-5-12
018
*
019
*/
020
public interface IBaseDao<T,PK extends Serializable> {
021
/**
022
* 根据主键类型的id获取实体对象,立即执行查询返回对象,数据库没有匹配则返回null
023
*/
024
public T getById(PK id);
025

026
/**
027
* 获取实体类型的全部对象
028
*/
029
public List<T> getAll();
030

031
/**
032
* 获取实体对象的代理,如果数据库没有匹配则异常,实体类有关联其它对象则延时加载
033
* @param id
034
* @return
035
*/
036
public T load(PK id);
037

038
/**
039
* 把数据加载到指定的非持久化实例上
040
* @param entityObject
041
* @param id
042
*/
043
public void load(T entityObject,PK id);
044

045
/**
046
* 删除对象.
047
*/
048
public void delete(T entityObject);
049

050
/**
051
* 根据id删除对象
052
* @param id
053
*/
054
public void deleteById(PK id);
055

056
/**
057
* 强迫装载对象和它的集合,使用了触发器的数据字段比较适合使用
058
* @param entityObject
059
*/
060
public void refresh(T entityObject);
061

062
/**
063
* 消除与 Hibernate Session 的关联
064
* @param entityObject
065
*/
066
public void evict(T entityObject);
067

068
/**
069
* 保存对象.<br>
070
* 如果对象已在本session中持久化了,不做任何事。<br>
071
* 如果另一个seesion拥有相同的持久化标识,抛出异常。<br>
072
* 如果没有持久化标识属性,调用save()。<br>
073
* 如果持久化标识表明是一个新的实例化对象,调用save()。<br>
074
* 如果是附带版本信息的(version或timestamp)且版本属性表明为新的实例化对象就save()。<br>
075
* 否则调用update()重新关联托管对象
076
* @param entityObject
077
*/
078
public void save(T entityObject);
079

080
/**
081
* 如果对象已在本session中持久化了,覆盖原有的<br>
082
* 如果session中没有对应对象,从数据库加载<br>
083
* 如果是脱管对象,则什么都不做
084
* @param entityObject
085
* @return
086
*/
087
public T merge(T entityObject);
088

089
/**
090
* 根据hql查询,直接使用HibernateTemplate的find函数.
091
* @param <T>
092
* @param hql
093
* @param values
094
* @return
095
*/
096
public List<T> find(String hql, Object... values);
097

098
/**
099
* 根据命名参数查询
100
* @param <T>
101
* @param hql 带有命名参数的hql语句
102
* @param paramNames 命名参数的名字
103
* @param values 命名参数的值<br>
104
* <b>例如:</b><br>
105
* findByNamedParams("from Test where t1 = :t",new String[]{"t"},tValue);
106
* @return
107
*/
108
public List<T> findByNamedParams(String hql,String[] paramNames,Object...values);
109

110
/**
111
* 创建Query对象.<br>
112
* 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
113
* @param hql
114
* @param values
115
* @return
116
*/
117
public Query createQuery(String hql,Object... values);
118

119
/**
120
* 执行一些必须的sql语句把内存中的对象同步到数据库中
121
*/
122
public void flush();
123

124
/**
125
* 清除对象缓存
126
*/
127
public void clear();
128

129
/**
130
* 返回iterator接口类型的结果
131
* @param <T>
132
* @param hql
133
* @param values
134
* @return
135
*/
136
public Iterator<T> iterator(String hql,Object...values);
137

138
/**
139
* @return 当前上下文的原生Hibernate session对象,依然受到spring事务管理不需要手动close
140
*/
141
public Session getNativeHibernateSession();
142

143
/**
144
* @return 当前上下文的原生Hibernate StatelessSession对象<br>
145
* 此对象不级联关联实例,忽略集合不触发Hibernate事件模型和拦截器,没有一级缓存,没有持久化上下文,接近JDBC.
146
*/
147
public StatelessSession getNativeStatelessHibernateSession();
148

149
/**
150
* 执行本地查询获得SQLQuery对象<br>
151
* 可以调用addEntity(*.class).list();获得对应实体list集合<br>
152
* addEntity.add(*.class).addJoin(*.class).list();获得一对多代理对象<br>
153
* 更多用法见google
154
* @param sql
155
* @return
156
*/
157
public SQLQuery nativeSqlQuery(String sql);
158

159
/**
160
* @param <T>
161
* @param countHql 计算数据总条数的hql语句(就是带count(*)的hql)
162
* @param hql
163
* @param pageNo 页面号
164
* @param pageSize 页面容量
165
* @param values
166
* @return
167
*/
168
public Page<T> pagedQuery(String countHql,String hql, int pageNo, int pageSize, Object... values);
169

170
/**
171
* @param <T>
172
* @param countHql 计算数据总条数的hql语句(就是带count(*)的hql)
173
* @param hql
174
* @param startNo 分页从哪一条数据开始
175
* @param pageSize 页面容量
176
* @param values
177
* @return
178
*/
179
public Page<T> pagedQueryByStartNo(String countHql,String hql, int startNo, int pageSize, Object... values);
180

181
/**
182
* @return 获得spring的HibernateTemplate拥有更多的功能
183
*/
184
public HibernateTemplate getSpringHibernateTemplate();
185

186
/**
187
* @return 获得jdbc操作的超绚酷dao
188
*/
189
public SimpleJdbcDao jdbc();
190
}
GenericDao.java

001
/**
002
*
003
*/
004
package com.tinylight.dao.hibernate;
005
import java.util.Iterator;
006
import java.util.List;
007
import org.hibernate.Query;
008
import org.hibernate.SQLQuery;
009
import org.hibernate.Session;
010
import org.hibernate.StatelessSession;
011
import org.springframework.orm.hibernate3.HibernateTemplate;
012
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
013
import com.tinylight.dao.support.Page;
014
/**
015
* 继承自spring的HibernateDaoSupport<br>
016
* 提供了和具体实体类无关的数据库操作
017
* @author scott.Cgi
018
* @since 2009-5-10
019
*
020
*/
021
public class GenericDao extends HibernateDaoSupport {
022

023
/**
024
* 根据hql查询,直接使用HibernateTemplate的find函数.
025
* @param <T>
026
* @param hql
027
* @param values
028
* @return
029
*/
030
@SuppressWarnings("unchecked")
031
public <T> List<T> find(String hql, Object... values) {
032
return this.getHibernateTemplate().find(hql, values);
033
}
034

035
/**
036
* 根据命名参数查询
037
* @param <T>
038
* @param hql 带有命名参数的hql语句
039
* @param paramNames 命名参数的名字
040
* @param values 命名参数的值<br>
041
* <b>例如:</b><br>
042
* findByNamedParams("from Test where t1 = :t",new String[]{"t"},tValue);
043
* @return
044
*/
045
@SuppressWarnings("unchecked")
046
public <T> List<T> findByNamedParams(String hql,String[] paramNames,Object...values){
047
return this.getHibernateTemplate().findByNamedParam(hql, paramNames, values);
048
}
049

050
/**
051
* 创建Query对象.<br>
052
* 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
053
* @param hql
054
* @param values
055
* @return
056
*/
057
public Query createQuery(String hql,Object... values) {
058
//这里的false表示不创建session保证,当前操作在spring同一个事务的管理下
059
Query query = this.getSession(false).createQuery(hql);
060
if (values != null) {
061
for (int i = 0; i < values.length; i++) {
062
query.setParameter(i, values[i]);
063
}
064
}
065
return query;
066
}
067

068
/**
069
* 执行一些必须的sql语句把内存中的对象同步到数据库中
070
*/
071
public void flush() {
072
this.getHibernateTemplate().flush();
073
}
074

075
/**
076
* 清除对象缓存
077
*/
078
public void clear() {
079
this.getHibernateTemplate().clear();
080
}
081

082
/**
083
* 返回iterator接口类型的结果
084
* @param <T>
085
* @param hql
086
* @param values
087
* @return
088
*/
089
@SuppressWarnings("unchecked")
090
public <T> Iterator<T> iterator(String hql,Object...values){
091
return this.getHibernateTemplate().iterate(hql, values);
092
}
093

094
/**
095
* @return 当前上下文的原生Hibernate session对象,依然受到spring事务管理不需要手动close
096
*/
097
public Session getNativeHibernateSession(){
098
return this.getSessionFactory().getCurrentSession();
099
}
100

101
/**
102
* @return 当前上下文的原生Hibernate StatelessSession对象<br>
103
* 此对象不级联关联实例,忽略集合不触发Hibernate事件模型和拦截器,没有一级缓存,没有持久化上下文,接近JDBC.
104
*/
105
public StatelessSession getNativeStatelessHibernateSession(){
106
return this.getSessionFactory().openStatelessSession();
107
}
108

109
/**
110
* 执行本地查询获得SQLQuery对象<br>
111
* 可以调用addEntity(*.class).list();获得对应实体list集合<br>
112
* addEntity.add(*.class).addJoin(*.class).list();获得一对多代理对象<br>
113
* 更多用法见google
114
* @param sql
115
* @return
116
*/
117
public SQLQuery nativeSqlQuery(String sql){
118
return this.getSession(false).createSQLQuery(sql);
119
}
120

121
/**
122
* @param <T>
123
* @param countHql 计算数据总条数的hql语句(就是带count(*)的hql)
124
* @param hql
125
* @param pageNo 页面号
126
* @param pageSize 页面容量
127
* @param values
128
* @return
129
*/
130
@SuppressWarnings("unchecked")
131
public <T> Page<T> pagedQuery(String countHql,String hql, int pageNo, int pageSize, Object... values) {
132
// Count查询
133
List<T> countlist = this.getHibernateTemplate().find(countHql, values);
134
long totalCount = (Long) countlist.get(0);
135
if (totalCount < 1)
136
return new Page<T>();
137
// 当前页的开始数据索引
138
long startIndex = Page.getStartOfPage(pageNo, pageSize);
139
Query query = this.createQuery(hql, values);
140
List<T> list = query.setFirstResult((int) startIndex).setMaxResults(pageSize).list();
141
return new Page<T>(startIndex, totalCount, pageSize, list);
142
}
143

144
/**
145
* @param <T>
146
* @param countHql 计算数据总条数的hql语句(就是带count(*)的hql)
147
* @param hql
148
* @param startNo 分页从哪一条数据开始
149
* @param pageSize 页面容量
150
* @param values
151
* @return
152
*/
153
@SuppressWarnings("unchecked")
154
public <T> Page<T> pagedQueryByStartNo(String countHql,String hql, int startNo, int pageSize, Object... values){
155
// Count查询
156
List<T> countlist = getHibernateTemplate().find(countHql, values);
157
long totalCount = (Long) countlist.get(0);
158
if (totalCount < 1)
159
return new Page();
160

161
int startIndex = startNo;
162
Query query = createQuery(hql, values);
163
List<T> list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
164
return new Page<T>(startIndex, totalCount, pageSize, list);
165
}
166

167
/**
168
* @return 获得spring的HibernateTemplate拥有更多的功能
169
*/
170
public HibernateTemplate getSpringHibernateTemplate(){
171
return this.getHibernateTemplate();
172
}
173
}
GenericEntityDao.java

view sourceprint?
001
/**
002
*
003
*/
004
package com.tinylight.dao.hibernate;
005
import java.io.Serializable;
006
import java.util.List;
007
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
008
/**
009
* 负责为单个Entity对象提供CRUD操作的Hibernate DAO基类.<br>
010
* 子类只要在类定义时指定所管理Entity的Class<br>
011
* 即拥有对单个Entity对象的CRUD操作.
012
* @author scott.Cgi
013
* @since 2009-5-11
014
*
015
*/
016
public class GenericEntityDao<T,PK extends Serializable> extends HibernateDaoSupport {
017

018
protected Class<T> entityClass;// DAO所管理的Entity类型.
019
public void setEntityClass(Class<T> type){//注入实体类型
020
this.entityClass=type;
021
}
022
public Class<T> getEntityClass(){
023
return this.entityClass;
024
}
025

026
public GenericEntityDao(){}
027
public GenericEntityDao(Class<T> entityClass){this.entityClass = entityClass;}
028
/**
029
* 根据主键类型的id获取实体对象,立即执行查询返回对象,数据库没有匹配则返回null
030
*/
031
@SuppressWarnings("unchecked")
032
public T getById(PK id) {
033
return (T)this.getHibernateTemplate().get(this.entityClass, id);
034
}
035

036
/**
037
* 获取实体类型的全部对象
038
*/
039
@SuppressWarnings("unchecked")
040
public List<T> getAll() {
041
return (List<T>)(this.getHibernateTemplate().loadAll(this.entityClass));
042
}
043

044
/**
045
* 获取实体对象的代理,如果数据库没有匹配则异常,实体类有关联其它对象则延时加载
046
* @param id
047
* @return
048
*/
049
@SuppressWarnings("unchecked")
050
public T load(PK id){
051
return (T)this.getHibernateTemplate().load(this.entityClass, id);
052
}
053

054
/**
055
* 把数据加载到指定的非持久化实例上
056
* @param entityObject
057
* @param id
058
*/
059
public void load(T entityObject,PK id){
060
this.getHibernateTemplate().load(entityObject, id);
061
}
062

063
/**
064
* 删除对象.
065
*/
066
public void delete(T entityObject) {
067
this.getHibernateTemplate().delete(entityObject);
068
}
069

070
/**
071
* 根据id删除对象
072
* @param id
073
*/
074
public void deleteById(PK id){
075
this.delete(this.getById(id));
076
}
077

078
/**
079
* 强迫装载对象和它的集合,使用了触发器的数据字段比较适合使用
080
* @param entityObject
081
*/
082
public void refresh(T entityObject){
083
this.getHibernateTemplate().refresh(entityObject);
084
}
085

086
/**
087
* 消除与 Hibernate Session 的关联
088
* @param entityObject
089
*/
090
public void evict(T entityObject){
091
this.getHibernateTemplate().evict(entityObject);
092
}
093

094
/**
095
* 保存对象.<br>
096
* 如果对象已在本session中持久化了,不做任何事。<br>
097
* 如果另一个seesion拥有相同的持久化标识,抛出异常。<br>
098
* 如果没有持久化标识属性,调用save()。<br>
099
* 如果持久化标识表明是一个新的实例化对象,调用save()。<br>
100
* 如果是附带版本信息的(version或timestamp)且版本属性表明为新的实例化对象就save()。<br>
101
* 否则调用update()重新关联托管对象
102
* @param entityObject
103
*/
104
public void save(T entityObject){
105
this.getHibernateTemplate().saveOrUpdate(entityObject);
106
}
107

108
/**
109
* 如果对象已在本session中持久化了,覆盖原有的<br>
110
* 如果session中没有对应对象,从数据库加载<br>
111
* 如果是脱管对象,则什么都不做
112
* @param entityObject
113
* @return
114
*/
115
@SuppressWarnings("unchecked")
116
public T merge(T entityObject){
117
return (T)this.getHibernateTemplate().merge(entityObject);
118
}
119

120
}
SimpleJdbcDao.java

001
/**
002
*
003
*/
004
package com.tinylight.dao.jdbc;
005
import java.sql.Connection;
006
import java.sql.SQLException;
007
import org.springframework.jdbc.core.JdbcTemplate;
008
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
009
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
010
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
011
import org.springframework.jdbc.datasource.DataSourceUtils;
012
import org.springframework.jdbc.support.GeneratedKeyHolder;
013
import org.springframework.jdbc.support.KeyHolder;
014
import org.springframework.jdbc.support.rowset.SqlRowSet;
015
/**
016
* 继承spring的SimpleJdbcDaoSupport
017
* 提供对数据库jdbc级别的操作
018
* 内部使用spring的SimpleJdbcTemplate与JdbcTemplate
019
* @author scott.Cgi
020
* @since 2009-5-7
021
*/
022
public class SimpleJdbcDao extends SimpleJdbcDaoSupport {
023

024
/**
025
* 提供对表的更改和删除操作
026
* @param sql 要执行的sql语句
027
* @param args 变参
028
* @return 影响的行数
029
*/
030
public int update(String sql,Object...args){
031
return this.getSimpleJdbcTemplate().update(sql, args);
032
}
033

034
/**
035
* 批量更新多条记录
036
* @param sql 多条sql组成的数组(不带参数的)
037
* @see 带参数的见: <br>
038
* getJdbcTemplate().batchUpdate(String[] sql,BatchPreparedStatementSetter pss)
039
* @return 影响行数数组
040
*/
041
public int[] batchUpdate(String[] sql){
042
return this.getJdbcTemplate().batchUpdate(sql);
043
}
044

045
/**
046
* 获取行数
047
* @param countSql 计算行数的sql语句
048
* @return
049
*/
050
public long countRows(String countSql){
051
return this.getJdbcTemplate().queryForLong(countSql);
052
}
053

054
/**
055
* 获取本地的Connection对象
056
* @return
057
*/
058
public Connection getNativeConn(){
059

060
//从当前线程绑定的数据连接获取连接
061
Connection conn = DataSourceUtils.getConnection(this.getJdbcTemplate().getDataSource());
062
try {
063
conn = this.getJdbcTemplate().getNativeJdbcExtractor().getNativeConnection(conn);
064
} catch (SQLException e) {
065
e.printStackTrace();
066
return null;
067
}
068

069
return conn;
070
}
071

072
/**
073
* 获得断开数据库连接的行集,大结果集会消耗内存,受到maxSize的限制
074
* @param sql 要执行的sql语句带?占位符
075
* @param params 填充占位符的数组
076
* @param types 填充参数类型(java.sql.Types中的常量)
077
* 例如:new int[]{Types.VARCHAR,Types.DATE}
078
* @return 影响的行数<br>
079
* <b>注:</b> params和types同时为空,sql为不带?占位符;仅仅types为空时,由spring去猜测类型
080
*/
081
public SqlRowSet queryForRowSet(String sql,Object[] params,int[] types){
082

083
if(params != null && types != null){
084
return this.getJdbcTemplate().queryForRowSet(sql, params, types);
085
}else if(params != null && types == null){
086
return this.getJdbcTemplate().queryForRowSet(sql, params);
087
}else {
088
return this.getJdbcTemplate().queryForRowSet(sql);
089
}
090
}
091

092
/**
093
* 提供对表的更改和删除操作
094
* @param hql 使用了命名参数的sql语句
095
* @param sps 例如:<br>
096
* new BeanPropertySqlParamterSource(javaBean其属性要和命名参数对应);<br>
097
* new MapSqlParameterSource().add("命名参数",参数对应的值).add()...可以链式调用
098
* @return KeyHolder主键持有者对象;如果是新增数据,KeyHolder持有新增的主键值<br>
099
* 有3个方法可调用:<br>getKey()一个数字主键<br>
100
* getKeys()复合主键Map结构<br>
101
* getKeyList()多个主键由多个Map组成的List
102
*/
103
public KeyHolder updateNamedParamer(String hql,SqlParameterSource sps){
104
KeyHolder keyHolder = new GeneratedKeyHolder();
105
this.getSimpleJdbcTemplate().getNamedParameterJdbcOperations().update(hql, sps, keyHolder);
106
return keyHolder;
107
}
108

109
/**
110
* 执行sql语句,如创建表等
111
* @param sql
112
*/
113
public void executeSql(String sql){
114
this.getJdbcTemplate().execute(sql);
115
}
116

117
/**
118
* @return 获得spring的JdbcTemplate使用更多功能
119
*/
120
public JdbcTemplate getSpringJdbcTemplate(){
121
return this.getJdbcTemplate();
122
}
123

124
/**
125
* 引入jdk5.0语法的JdbcTemplate的简化版本
126
* @return 获得spring的SimpleJdbcTemplate使用更多功能
127
*/
128
public SimpleJdbcTemplate getSpringSimplaJdbcTemplate(){
129
return this.getSimpleJdbcTemplate();
130
}
131
}
Page.java

001
package com.tinylight.dao.support;
002
import java.io.Serializable;
003
import java.util.Collections;
004
import java.util.List;
005
/**
006
* 分页对象.包含当前页数据及分页信息如总记录数.
007
*
008
* @author scott.Cgi
009
* @since 2008-6-29
010
*/
011
public class Page<T> implements Serializable {
012
private static final long serialVersionUID = -5624189033006412710L;
013
private static long DEFAULT_PAGE_SIZE = 20;
014
private long pageSize = DEFAULT_PAGE_SIZE; // 每页的记录数
015
private long start; // 当前页第一条数据在List中的位置,从0开始
016
private List<T> data = Collections.emptyList(); // 当前页中存放的记录
017
private long totalCount = 0; // 总记录数
018
/**
019
* 构造方法,只构造空页.
020
*/
021
public Page() {
022
this(0l, 0l, DEFAULT_PAGE_SIZE, Collections.<T>emptyList());
023
}
024
/**
025
* 默认构造方法.
026
*
027
* @param start 本页数据在数据库中的起始位置
028
* @param totalSize 数据库中总记录条数
029
* @param pageSize 本页容量
030
* @param data 本页包含的数据
031
*/
032
public Page(long start, long totalSize, long pageSize, List<T> data) {
033
this.pageSize = pageSize;
034
this.start = start;
035
this.totalCount = totalSize;
036
this.data = data;
037
}
038
/**
039
* 取总记录数.
040
*/
041
public long getTotalCount() {
042
return this.totalCount;
043
}
044
/**
045
* 取总页数.
046
*/
047
public long getTotalPageCount() {
048
if (totalCount % pageSize == 0)
049
return totalCount / pageSize;
050
else
051
return totalCount / pageSize + 1;
052
}
053
/**
054
* 取每页数据容量.
055
*/
056
public Long getPageSize() {
057
return pageSize;
058
}
059
/**
060
* 取当前页中的记录.
061
*/
062
public List<T> getResult() {
063
return data;
064
}
065
/**
066
* 取该页当前页码,页码从1开始.
067
*/
068
public long getCurrentPageNo() {
069
return start / pageSize + 1;
070
}
071
/**
072
* 该页是否有下一页.
073
*/
074
public boolean hasNextPage() {
075
return this.getCurrentPageNo() < this.getTotalPageCount();
076
}
077
/**
078
* 该页是否有上一页.
079
*/
080
public boolean hasPreviousPage() {
081
return this.getCurrentPageNo() > 1;
082
}
083
/**
084
* 获取任一页第一条数据在数据集的位置,每页条数使用默认值.
085
*
086
*/
087
protected static long getStartOfPage(long pageNo) {
088
return getStartOfPage(pageNo, DEFAULT_PAGE_SIZE);
089
}
090
/**
091
* 获取任一页第一条数据在数据集的位置.
092
*
093
* @param pageNo 从1开始的页号
094
* @param pageSize 每页记录条数
095
* @return 该页第一条数据
096
*/
097
public static long getStartOfPage(long pageNo, long pageSize) {
098
return (pageNo - 1) * pageSize;
099
}
100
}
applicationContext-annotation.xml

01
<?xml version="1.0" encoding="UTF-8" ?>
02
<beans xmlns="http://www.springframework.org/schema/beans"
03
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
04
xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
05
xmlns:context="http://www.springframework.org/schema/context"
06
xmlns:aop="http://www.springframework.org/schema/aop"
07
xsi:schemaLocation="http://www.springframework.org/schema/beans
08

09
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
10

11
http://www.springframework.org/schema/context
12

13
http://www.springframework.org/schema/context/spring-context-2.5.xsd
14

15
http://www.directwebremoting.org/schema/spring-dwr
16

17
http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd
18

19
http://www.springframework.org/schema/aop
20

21
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
22

23
<context:annotation-config/>
24
</beans>
applicationContext-list.xml

01
<?xml version="1.0" encoding="UTF-8"?>
02
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
03
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
04
xmlns:context="http://www.springframework.org/schema/context"
05
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
06
<description>导入applicationContext文件列表,可随时通过注释disable不需要的模块</description>
07
<!-- 导入spring aop配置文件 -->
08
<import resource="applicationContext-tx.xml" />
09
<!-- 导入spring dao配置文件 -->
10
<import resource="tinylight-dao.xml" />
11

12
</beans>
applicationContext-tx.xml

01
<?xml version="1.0" encoding="UTF-8"?>
02
<!-- 使用aop/tx命名空间 -->
03
<beans xmlns="http://www.springframework.org/schema/beans"
04
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
05
xmlns:aop="http://www.springframework.org/schema/aop"
06
xmlns:tx="http://www.springframework.org/schema/tx"
07
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
08
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
09
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
10
<!-- 配置事务管理器bean,使用HibernateTransactionManager事务管理器 -->
11
<bean id="txManager"
12
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
13
<!-- 为事务管理器注入sessionFactory" -->
14
<property name="sessionFactory">
15
<ref bean="sessionFactory" />
16
</property>
17
</bean>
18
<!-- 通过aop定义事务增强切面 -->
19
<aop:config>
20
<!-- 使用强大的切点表达式语言轻松定义目标方法 -->
21
<aop:pointcut id="serviceMethod"
22
expression="execution(* com.tinylight.dao.base.IBaseDao.*(..))" />
23
<!-- 引用事务增强 -->
24
<aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />
25
</aop:config>
26
<!-- 事务增强 -->
27
<tx:advice id="txAdvice" transaction-manager="txManager">
28
<!-- 属性事务定义 -->
29
<tx:attributes>
30
<!--OpenSessionInViewFilter在getSession的时候,会把获取回来的session的flush mode 设为FlushMode.NEVER。
31
然后把该sessionFactory绑定到TransactionSynchronizationManager,使request的整个过程都使用同一个session,
32
在请求过后再接除该sessionFactory的绑定,最后closeSessionIfNecessary根据该session是否已和transaction绑定来决定是否关闭session。
33
在这个过程中,若HibernateTemplate 发现自当前session有不是readOnly的transaction,就会获取到FlushMode.AUTO Session,使方法拥有写权限。
34
也即是,如果有不是readOnly的transaction就可以由Flush.NEVER转为Flush.AUTO,拥有insert,update,delete操作权限,如果没有transaction,
35
并且没有另外人为地设flush model的话,则doFilter的整个过程都是Flush.NEVER。所以受transaction保护的方法有写权限,没受保护的则没有 -->
36
<tx:method name="*" />
37
</tx:attributes>
38
</tx:advice>
39

40
</beans>
applicationContext.xml

001
<?xml version="1.0" encoding="UTF-8"?>
002
<beans xmlns="http://www.springframework.org/schema/beans"
003
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
004
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
005
<!-- 使用外部文件配置数据源的属性 -->
006
<bean
007
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
008
<property name="locations">
009
<list>
010
<!-- 外部文件地址 -->
011
<value>classpath:database_conn.properties</value>
012
</list>
013
</property>
014
<property name="fileEncoding" value="utf-8" />
015
</bean>
016
<!-- 配置数据源 -->
017
<bean id="dataSource"
018
class="com.mchange.v2.c3p0.ComboPooledDataSource"
019
destroy-method="close">
020
<property name="driverClass" value="${driverClassName}" />
021
<property name="jdbcUrl" value="${url}"/>
022
<property name="user" value="${username}"/>
023
<property name="password" value="${password}"/>
024

025
<!--连接池中保留的最小连接数。-->
026
<property name="minPoolSize" value="5" />
027

028
<!--连接池中保留的最大连接数。Default: 15 -->
029
<property name="maxPoolSize" value="20" />
030

031
<!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
032
<property name="initialPoolSize" value="10" />
033

034
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
035
<property name="maxIdleTime" value="60" />
036

037
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
038
<property name="acquireIncrement" value="5" />
039

040
<!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements
041
属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
042
如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->
043
<property name="maxStatements" value="0"/>
044
<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
045
<property name="idleConnectionTestPeriod" value="60"/>
046

047
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
048
<property name="acquireRetryAttempts" value="0" />
049
<!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效
050
保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试
051
获取连接失败后该数据源将申明已断开并永久关闭。Default: false-->
052
<property name="breakAfterAcquireFailure" value="true" />
053

054
<!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的
055
时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
056
等方法来提升连接测试的性能。Default: false -->
057
<property name="testConnectionOnCheckout" value="false" />
058
</bean>
059
<!-- hibernate3 sessionfactory配置
060
使用AnnotationSessionFactoryBean创建基于JPA注解的SessionFactory-->
061
<bean id="sessionFactory"
062
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
063
<!-- 引用数据源 -->
064
<property name="dataSource">
065
<ref bean="dataSource" />
066
</property>
067
<property name="namingStrategy">
068
<bean class="org.hibernate.cfg.ImprovedNamingStrategy" />
069
</property>
070
<!-- hibernate的属性具体见hibernate文档 -->
071
<property name="hibernateProperties">
072
<props>
073
<prop key="hibernate.dialect">
074
org.hibernate.dialect.MySQLDialect
075
</prop>
076
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
077
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
078
<!-- 非0值 指定jdbc抓取数量的大小调用Statement.setFetchSize() -->
079
<prop key="hibernate.jdbc.fetch_size">${hibernate.jdbc.fetch_size}</prop>
080
<!-- jdbc批量更新 建议5到30 -->
081
<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
082
<!--说明一下:如果不设置查询缓存,那么hibernate只会缓存使用load()方法获得的单个持久化对象
083
如果想缓存使用findall()、list()、Iterator()、createCriteria()、createQuery()
084
等方法获得的数据结果集的话就需要设置hibernate.cache.use_query_cache true 才行 -->
085
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
086
<prop key="hibernate.cache.provider_class">
087
org.hibernate.cache.EhCacheProvider
088
</prop>
089
<prop key="hibernate.cache.provider_configuration_file_resource_path">
090
${hibernate.ehcache_config_file}
091
</prop>
092
</props>
093
</property>
094

095
<property name="packagesToScan" value="com.hibernate.entityclass" />
096
</bean>
097

098
<!-- 加载spring功能列表文件 -->
099
<import resource="applicationContext-list.xml"/>
100
</beans>
database_conn.properties

01
#jdbc settings
02
driverClassName=org.gjt.mm.mysql.Driver
03
url=jdbc\:mysql\://127.0.0.1\:3306/mytest
04
username=root
05
password=123456
06
#hibernate settings
07
hibernate.show_sql=true
08
hibernate.format_sql=true
09
hibernate.cache.use_query_cache=false
10
hibernate.jdbc.fetch_size=10
11
hibernate.jdbc.batch_size=5
12
hibernate.ehcache_config_file=ehcache.xml
ehcache.xml

01
<ehcache>
02
<!-- Sets the path to the directory where cache .data files are created.
03

04
If the path is a Java System Property it is replaced by
05
its value in the running VM.
06

07
The following properties are translated:
08
user.home - User's home directory
09
user.dir - User's current working directory
10
java.io.tmpdir - Default temp file path -->
11
<diskStore path="java.io.tmpdir" />
12
<!--Default Cache configuration. These will applied to caches programmatically created through
13
the CacheManager.
14

15
The following attributes are required:
16

17
maxElementsInMemory - Sets the maximum number of objects that will be created in memory
18
eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the
19
element is never expired.
20
overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
21
has reached the maxInMemory limit.
22

23
The following attributes are optional:
24
timeToIdleSeconds - Sets the time to idle for an element before it expires.
25
i.e. The maximum amount of time between accesses before an element expires
26
Is only used if the element is not eternal.
27
Optional attribute. A value of 0 means that an Element can idle for infinity.
28
The default value is 0.
29
timeToLiveSeconds - Sets the time to live for an element before it expires.
30
i.e. The maximum time between creation time and when an element expires.
31
Is only used if the element is not eternal.
32
Optional attribute. A value of 0 means that and Element can live for infinity.
33
The default value is 0.
34
diskPersistent - Whether the disk store persists between restarts of the Virtual Machine.
35
The default value is false.
36
diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value
37
is 120 seconds.
38
-->
39
<cache name="org.hibernate.cache.StandardQueryCache"
40
maxElementsInMemory="50"
41
eternal="false"
42
timeToIdleSeconds="3600"
43
timeToLiveSeconds="7200"
44
overflowToDisk="true" />
45
<cache name="org.hibernate.cache.UpdateTimestampsCache"
46
maxElementsInMemory="5000"
47
eternal="true"
48
overflowToDisk="true" />
49
<!--
50
默认的Cache配置。用来实现CacheManager.add(String cacheName)创建的缓存
51
memoryStoreEvictionPolicy:内存存储与释放策略。有三个值:
52
LRU -least recently used
53
LFU -least frequently used
54
FIFO-first in first out, the oldest element by creation time
55
diskPersistent :是否持久化磁盘缓存。
56
当这个属性的值为true时,系统在初始化的时候会在磁盘中查找文件名为cache名称
57
后缀名为index的的文件,如CACHE_FUNC.index
58
-->
59
<defaultCache maxElementsInMemory="10000"
60
eternal="false"
61
timeToIdleSeconds="120"
62
timeToLiveSeconds="120"
63
overflowToDisk="true"
64
diskPersistent="false"
65
diskExpiryThreadIntervalSeconds="120"
66
memoryStoreEvictionPolicy="LFU"
67
/>
68
<!-- See http://ehcache.sourceforge.net/documentation/#mozTocId258426 for how to configure caching for your objects -->
69
</ehcache>
log4j.properties

01
log4j.rootLogger=INFO, stdout, logfile
02
log4j.logger.org.springframework=WARN
03
log4j.logger.org.hibernate=WARN
04
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
05
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
06
log4j.appender.stdout.layout.ConversionPattern=[%d] %-5p \: %m%n
07
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
08
log4j.appender.logfile.File=${webAppRootKey}/superDao.log
09
log4j.appender.logfile.MaxFileSize=512KB
10
# Keep three backup files.
11
log4j.appender.logfile.MaxBackupIndex=3
12
# Pattern to output: date priority [category] - message
13
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
14
log4j.appender.logfile.layout.ConversionPattern=[%d] %p [%c] - %m%n
tinyLight-dao.xml

01
<?xml version="1.0" encoding="UTF-8"?>
02
<beans xmlns="http://www.springframework.org/schema/beans"
03
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
04
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
05
<description>tinyLight Dao配置</description>
06
<!-- 定义JdbcTemplate Bean(线程安全,执行底层sql语句) -->
07
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
08
<!-- 设置数据源 -->
09
<property name="dataSource" ref="dataSource" />
10
<!-- 设置jdbcTemplate创建的statement查询数据时最大的超时时间,默认0 -->
11
<property name="queryTimeout" value="0" />
12
<!-- 设置底层ResultSet每次从数据库返回的行数,默认0,Oracle默认100 -->
13
<property name="fetchSize" value="0" />
14
<!-- 设置底层ResultSet从数据库返回的最大行数,默认0 -->
15
<property name="maxRows" value="0" />
16
<!-- 是否忽略sql警告信息,默认true,false JdbcTemplate将会抛出SQLWarningException -->
17
<property name="ignoreWarnings" value="true" />
18
<property name="nativeJdbcExtractor" ref="nativeJdbcExtractor" />
19
</bean>
20
<!-- 定义DBCP数据源的JDBC本地对象抽取器 -->
21
<bean id="nativeJdbcExtractor" lazy-init="true"
22
class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor" />
23
<!-- 定义封装了jdbc操作数据的dao -->
24
<bean id="simpleJdbcDao" class="com.tinylight.dao.jdbc.SimpleJdbcDao">
25
<property name="jdbcTemplate" ref="jdbcTemplate" />
26
</bean>
27
<!-- 定义了与实体相关的dao -->
28
<bean id="genericEntityDao" class="com.tinylight.dao.hibernate.GenericEntityDao"
29
scope="prototype" lazy-init="true">
30
<property name="sessionFactory">
31
<ref bean="sessionFactory" />
32
</property>
33
</bean>
34
<!-- 定义了与实体无关的dao -->
35
<bean id="genericDao" class="com.tinylight.dao.hibernate.GenericDao">
36
<property name="sessionFactory">
37
<ref bean="sessionFactory" />
38
</property>
39
</bean>
40
<!--使用泛型DAO作为抽象基类-->
41
<bean id="baseDao" class="com.tinylight.dao.base.BaseDao"
42
abstract="true" depends-on="genericEntityDao,genericDao">
43
<property name="gedao">
44
<ref bean="genericEntityDao" />
45
</property>
46
<property name="gdao">
47
<ref bean="genericDao" />
48
</property>
49
<property name="sjdao">
50
<ref bean="simpleJdbcDao"/>
51
</property>
52
</bean>
53
<!--
54
当然这里也可以不必为每一个实体类的配置像下面这样的代码,
55
那就要在spring注解注入dao到service类的时候,加上下面这个方法:
56
/**
57
* spring bean的后处理器,如果子类是spring初始化的bean,则在初始化后设置注解dao的实体类类型
58
* @throws IllegalArgumentException
59
* @throws IllegalAccessException
60
*/
61
@PostConstruct
62
@SuppressWarnings("unchecked")
63
protected void preparedDao() throws IllegalArgumentException, IllegalAccessException{
64
Class<? extends BaseService> cl = this.getClass();
65
for(Field f : cl.getDeclaredFields()){
66
log.info("Service类注解属性名称 = {},类型 = {}",f.getName(),f.getGenericType());
67
if(f.isAnnotationPresent(Resource.class) && f.getAnnotation(Resource.class).name().equals("baseDao")){
68
f.setAccessible(true);//修改private修饰权限
69
Type[] params = ((ParameterizedType)f.getGenericType()).getActualTypeArguments();
70
log.info("实体类的参数类型 = {}",params[0].toString());
71
((IBaseDao<?,?>)f.get(this)).changeEntityClass((Class)params[0]);//设置实体类类型
72
f.setAccessible(false);//恢复private修饰权限
73
}
74
}
75
}
76
这样就可以为每一个实体类加下面这段xml配置了,当然dao是不在学要写一条代码啦
77
-->
78

79
<!-- 配置实体Demodata的DAO -->
80
<bean id="demoDao" parent="baseDao">
81
<constructor-arg>
82
<value>com.hibernate.entityclass.Daotest</value>
83
</constructor-arg>
84
</bean>
85

86
</beans>


这个svn有源代码,有兴趣可以看看.
http://xeducation.googlecode.com/svn/trunk
是myeclipse的工程


Share this on: Mixx Delicious Digg Facebook Twitter
DAOHibernateJDBCSpring
Related StoriesMost Popular
Linux系统信息查看命令大全
MySQL架构方案
Struts2 注解功能
Struts2 零配置方法总结
Spring与Memcache的集成
Apache Mina ProtocolCodecFilter Introduction
Leave a Reply
Name *


Email *


Website


Comment


有人回复时邮件通知我
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值