15.迭代器模式(Iterator)
在软件开发中,经常需要将某一类对象放在一个集合里,或者放在容器里,这个时候通常需要对集合或容器里的对象进行访问,很明显,对集合或容器里对象的访问必须涉及遍历,这就是迭代器模式。
哪里会用到迭代器模式
在电子商城的网站开发中,经常会有一个产品的列表展示,经常会使用到循环进行处理,从而将产品一个一个地展示出来。在网站浏览新闻时,各种类型的新闻也是一条一条显示在界面上的,这种类型的展示都需要使用迭代器。
迭代器模式的实现原理
迭代器模式就是提供了一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部标识,迭代器模式分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明地访问集合内部的数据。
迭代器模式在Java中的具体实现原理
Iterator
package java.util;
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
Map
package java.util;
public interface Map<K, V> {
int size();
boolean isEmpty();
boolean containsKey(Object key);
boolean containsValue(Object value);
V get(Object key);
V put(K key, V value);
V remove(Object key);
void putAll(Map<? extends K, ? extends V> m);
void clear();
Set<K> keySet();
Collection<V> values();
Set<Map.Entry<K, V>> entrySet();
interface Entry<K, V> {
K getKey();
V getValue();
V setValue(V value);
boolean equals(Object o);
int hashCode();
}
boolean equals(Object o);
int hashCode();
}
Collection
package java.util;
public interface Collection<E> extends Iterable<E> {
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator<E> iterator();
Object[] toArray();
<T> T[] toArray(T[] a);
boolean add(E e);
boolean remove(Object o);
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c);
void clear();
boolean equals(Object o);
int hashCode();
}
List
package java.util;
public interface List<E> extends Collection<E> {
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator<E> iterator();
Object[] toArray();
<T> T[] toArray(T[] a);
boolean add(E e);
boolean remove(Object o);
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean addAll(int index, Collection<? extends E> c);
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c);
void clear();
boolean equals(Object o);
int hashCode();
E get(int index);
E set(int index, E element);
void add(int index, E element);
E remove(int index);
int indexOf(Object o);
int lastIndexOf(Object o);
ListIterator<E> listIterator();
ListIterator<E> listIterator(int index);
List<E> subList(int fromIndex, int toIndex);
}
16.模版方法模式(TemplateMethod)
模版方法模式在程序开发中经常使用,目的就是定义一系列算法执行的顺序,而把具体算法的实现在子类中完成,在很多框架(比如Spring、JUnit)中都实现了模版方法模式。
哪里会使用到模版方法模式
比如新闻发布系统中,对于查看新闻的页面来说,该新闻的抬头、结尾都有一定的格式,变化的只是新闻的内容,通常情况下,开发人员会使用模版技术,将新闻的抬头和结尾都固定,只改变新闻的内容,这样能够极大提高开发效率。
再比如其后介绍的命令模式,它是将用户事先设定好的命令存储起来,然后在指定的时间里按照一定的顺序将命令取出来执行,可以看出,在实际的应用开发中,命令模式与职责链模式可以很好的结合起来,对于用户的命令,可以通过命令模式进行存储,然后通过职责链模式,再将命令按照一定的顺序进行执行。
拿前面策略模式的薪资例子为例(和策略模式很像,但模版模式规定了执行方法的顺序):
模版方法模式的实现原理
模版方法模式在JUnit中的使用
源码比较简单,模版方法模式主要体现在TestCase类的runBare()方法
模版方法模式在Servlet中的使用
在HttpServlet中有几个重要的方法,一个是doPost()方法,一个是doGet()方法,还有一个是Service()方法。
Servlet是由WebLogic之类的Servlet容器来调用处理器请求的,Servlet定义了一个处理模版,实现Servlet只需继承Servlet并实现doGet、doPost等方法即可。
HttpServlet
package javax.servlet.http;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.ResourceBundle;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public abstract class HttpServlet extends GenericServlet implements
Serializable {
private static final String METHOD_DELETE = "DELETE";
private static final String METHOD_HEAD = "HEAD";
private static final String METHOD_GET = "GET";
private static final String METHOD_OPTIONS = "OPTIONS";
private static final String METHOD_POST = "POST";
private static final String METHOD_PUT = "PUT";
private static final String METHOD_TRACE = "TRACE";
private static final String HEADER_IFMODSINCE = "If-Modified-Since";
private static final String HEADER_LASTMOD = "Last-Modified";
private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings";
private static ResourceBundle lStrings = ResourceBundle
.getBundle("javax.servlet.http.LocalStrings");
// doGet方法
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
}
}
protected long getLastModified(HttpServletRequest req) {
return -1L;
}
// doHead方法
protected void doHead(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
NoBodyResponse response = new NoBodyResponse(resp);
doGet(req, response);
response.setContentLength();
}
// doPost方法
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_post_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
}
}
// doPut方法
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_put_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
}
}
// doDelete方法
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_delete_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
}
}
private static Method[] getAllDeclaredMethods(Class c) {
if (c.equals(HttpServlet.class)) {
return null;
}
Method[] parentMethods = getAllDeclaredMethods(c.getSuperclass());
Method[] thisMethods = c.getDeclaredMethods();
if ((parentMethods != null) && (parentMethods.length > 0)) {
Method[] allMethods = new Method[parentMethods.length
+ thisMethods.length];
System.arraycopy(parentMethods, 0, allMethods, 0,
parentMethods.length);
System.arraycopy(thisMethods, 0, allMethods, parentMethods.length,
thisMethods.length);
thisMethods = allMethods;
}
return thisMethods;
}
// doOptions方法
protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
Method[] methods = getAllDeclaredMethods(getClass());
boolean ALLOW_GET = false;
boolean ALLOW_HEAD = false;
boolean ALLOW_POST = false;
boolean ALLOW_PUT = false;
boolean ALLOW_DELETE = false;
boolean ALLOW_TRACE = true;
boolean ALLOW_OPTIONS = true;
for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
if (m.getName().equals("doGet")) {
ALLOW_GET = true;
ALLOW_HEAD = true;
}
if (m.getName().equals("doPost")) {
ALLOW_POST = true;
}
if (m.getName().equals("doPut")) {
ALLOW_PUT = true;
}
if (m.getName().equals("doDelete")) {
ALLOW_DELETE = true;
}
}
String allow = null;
if ((ALLOW_GET) && (allow == null)) {
allow = "GET";
}
if (ALLOW_HEAD) {
if (allow == null) {
allow = "HEAD";
} else {
allow = allow + ", HEAD";
}
}
if (ALLOW_POST) {
if (allow == null) {
allow = "POST";
} else {
allow = allow + ", POST";
}
}
if (ALLOW_PUT) {
if (allow == null) {
allow = "PUT";
} else {
allow = allow + ", PUT";
}
}
if (ALLOW_DELETE) {
if (allow == null) {
allow = "DELETE";
} else {
allow = allow + ", DELETE";
}
}
if (ALLOW_TRACE) {
if (allow == null) {
allow = "TRACE";
} else {
allow = allow + ", TRACE";
}
}
if (ALLOW_OPTIONS) {
if (allow == null) {
allow = "OPTIONS";
} else {
allow = allow + ", OPTIONS";
}
}
resp.setHeader("Allow", allow);
}
// 执行doTrace
protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String CRLF = "\r\n";
String responseString = "TRACE " + req.getRequestURI() + " "
+ req.getProtocol();
Enumeration reqHeaderEnum = req.getHeaderNames();
while (reqHeaderEnum.hasMoreElements()) {
String headerName = (String) reqHeaderEnum.nextElement();
responseString = responseString + CRLF + headerName + ": "
+ req.getHeader(headerName);
}
responseString = responseString + CRLF;
// 获取长度
int responseLength = responseString.length();
// 设定报头
resp.setContentType("message/http");
resp.setContentLength(responseLength);
ServletOutputStream out = resp.getOutputStream();
out.print(responseString);
out.close();
}
// 在service里判断具体执行哪个方法
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getMethod();
if (method.equals("GET")) {
long lastModified = getLastModified(req);
if (lastModified == -1L) {
doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader("If-Modified-Since");
if (ifModifiedSince < lastModified / 1000L * 1000L) {
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if (method.equals("HEAD")) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals("POST")) {
doPost(req, resp);
} else if (method.equals("PUT")) {
doPut(req, resp);
} else if (method.equals("DELETE")) {
doDelete(req, resp);
} else if (method.equals("OPTIONS")) {
doOptions(req, resp);
} else if (method.equals("TRACE")) {
doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
// 记录最后的修改状态
private void maybeSetLastModified(HttpServletResponse resp,
long lastModified) {
if (resp.containsHeader("Last-Modified")) {
return;
}
if (lastModified >= 0L) {
resp.setDateHeader("Last-Modified", lastModified);
}
}
// 都会执行service方法
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
try {
HttpServletRequest request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
HttpServletResponse response;
throw new ServletException("non-HTTP request or response");
}
HttpServletResponse response;
HttpServletRequest request;
service(request, response);
}
}
模版方法模式在数据库的实际应用
注:以下Spring源码是Spring 3.2.16的,现在已经弃用了,不过可以看看了解一下模式
JpaTemplate
package org.springframework.orm.jpa;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceException;
import javax.persistence.Query;
import org.apache.commons.logging.Log;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@Deprecated
public class JpaTemplate extends JpaAccessor implements JpaOperations {
private boolean exposeNativeEntityManager = false;
public JpaTemplate() {
}
public JpaTemplate(EntityManagerFactory emf) {
setEntityManagerFactory(emf);
afterPropertiesSet();
}
public JpaTemplate(EntityManager em) {
setEntityManager(em);
afterPropertiesSet();
}
public void setExposeNativeEntityManager(boolean exposeNativeEntityManager) {
this.exposeNativeEntityManager = exposeNativeEntityManager;
}
public boolean isExposeNativeEntityManager() {
return this.exposeNativeEntityManager;
}
// 用于实现查询方法的回调
public <T> T execute(JpaCallback<T> action) throws DataAccessException {
return execute(action, isExposeNativeEntityManager());
}
// 查询方法
public List executeFind(JpaCallback<?> action) throws DataAccessException {
Object result = execute(action, isExposeNativeEntityManager());
if (!(result instanceof List)) {
throw new InvalidDataAccessApiUsageException(
"Result object returned from JpaCallback isn't a List: ["
+ result + "]");
}
return (List) result;
}
// 执行回调
public <T> T execute(JpaCallback<T> action,
boolean exposeNativeEntityManager) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
// 获取实体管理器
EntityManager em = getEntityManager();
boolean isNewEm = false;
if (em == null) {
em = getTransactionalEntityManager();
if (em == null) {
this.logger
.debug("Creating new EntityManager for JpaTemplate execution");
em = createEntityManager();
isNewEm = true;
}
}
// 反射
try {
EntityManager emToExpose = exposeNativeEntityManager ? em
: createEntityManagerProxy(em);
T result = action.doInJpa(emToExpose);
flushIfNecessary(em, !isNewEm);
return result;
} catch (RuntimeException ex) {
throw translateIfNecessary(ex);
} finally {
if (isNewEm) {
this.logger
.debug("Closing new EntityManager after JPA template execution");
EntityManagerFactoryUtils.closeEntityManager(em);
}
}
}
// 创建实体管理器的代理
protected EntityManager createEntityManagerProxy(EntityManager em) {
Class[] ifcs = null;
EntityManagerFactory emf = getEntityManagerFactory();
if ((emf instanceof EntityManagerFactoryInfo)) {
Class entityManagerInterface = ((EntityManagerFactoryInfo) emf)
.getEntityManagerInterface();
if (entityManagerInterface != null) {
ifcs = new Class[] { entityManagerInterface };
}
}
if (ifcs == null) {
ifcs = ClassUtils.getAllInterfacesForClass(em.getClass());
}
return (EntityManager) Proxy.newProxyInstance(em.getClass()
.getClassLoader(), ifcs, new CloseSuppressingInvocationHandler(
em));
}
// 查询方法的具体实现
public <T> T find(final Class<T> entityClass, final Object id)
throws DataAccessException {
execute(new JpaCallback() {
public T doInJpa(EntityManager em) throws PersistenceException {
return em.find(entityClass, id);
}
}, true);
}
// 查询方法
public <T> T getReference(final Class<T> entityClass, final Object id)
throws DataAccessException {
execute(new JpaCallback() {
public T doInJpa(EntityManager em) throws PersistenceException {
return em.getReference(entityClass, id);
}
}, true);
}
public boolean contains(final Object entity) throws DataAccessException {
((Boolean) execute(new JpaCallback() {
public Boolean doInJpa(EntityManager em)
throws PersistenceException {
return Boolean.valueOf(em.contains(entity));
}
}, true)).booleanValue();
}
// 刷新方法的具体实现
public void refresh(final Object entity) throws DataAccessException {
execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
em.refresh(entity);
return null;
}
}, true);
}
// 保存方法的具体实现
public void persist(final Object entity) throws DataAccessException {
execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
em.persist(entity);
return null;
}
}, true);
}
// 更新方法的具体实现
public <T> T merge(final T entity) throws DataAccessException {
execute(new JpaCallback() {
public T doInJpa(EntityManager em) throws PersistenceException {
return em.merge(entity);
}
}, true);
}
// 删除方法的具体实现
public void remove(final Object entity) throws DataAccessException {
execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
em.remove(entity);
return null;
}
}, true);
}
public void flush() throws DataAccessException {
execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
em.flush();
return null;
}
}, true);
}
// 查询方法
public List find(String queryString) throws DataAccessException {
return find(queryString, (Object[]) null);
}
// 返回多笔查询结果
public List find(final String queryString, final Object... values) throws DataAccessException
{
(List)execute(new JpaCallback()
{
public List doInJpa(EntityManager em) throws PersistenceException
{
Query queryObject = em.createQuery(queryString);
JpaTemplate.this.prepareQuery(queryObject);
if (values != null) {
for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i + 1, values[i]);
}
}
return queryObject.getResultList();
}
});
}
// 根据名称和实体类查询
public List findByNamedParams(final String queryString, final Map<String, ?> params)
throws DataAccessException
{
(List)execute(new JpaCallback()
{
public List doInJpa(EntityManager em)
throws PersistenceException
{
Query queryObject = em.createQuery(queryString);
JpaTemplate.this.prepareQuery(queryObject);
if (params != null) {
for (Map.Entry<String, ?> entry : params.entrySet()) {
queryObject.setParameter((String)entry.getKey(), entry.getValue());
}
}
return queryObject.getResultList();
}
});
}
public List findByNamedQuery(String queryName) throws DataAccessException {
return findByNamedQuery(queryName, (Object[]) null);
}
public List findByNamedQuery(final String queryName, final Object... values)
throws DataAccessException
{
(List)execute(new JpaCallback()
{
public List doInJpa(EntityManager em)
throws PersistenceException
{
Query queryObject = em.createNamedQuery(queryName);
JpaTemplate.this.prepareQuery(queryObject);
if (values != null) {
for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i + 1, values[i]);
}
}
return queryObject.getResultList();
}
});
}
public List findByNamedQueryAndNamedParams(final String queryName, final Map<String, ?> params)
throws DataAccessException
{
(List)execute(new JpaCallback()
{
public List doInJpa(EntityManager em)
throws PersistenceException
{
Query queryObject = em.createNamedQuery(queryName);
JpaTemplate.this.prepareQuery(queryObject);
if (params != null) {
for (Map.Entry<String, ?> entry : params.entrySet()) {
queryObject.setParameter((String)entry.getKey(), entry.getValue());
}
}
return queryObject.getResultList();
}
});
}
public void prepareQuery(Query query) {
EntityManagerFactory emf = getEntityManagerFactory();
if (emf != null) {
EntityManagerFactoryUtils.applyTransactionTimeout(query,
getEntityManagerFactory());
}
}
private class CloseSuppressingInvocationHandler implements
InvocationHandler {
private final EntityManager target;
public CloseSuppressingInvocationHandler(EntityManager target) {
this.target = target;
}
// java反射的具体应用
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if (method.getName().equals("equals")) {
return Boolean.valueOf(proxy == args[0]);
}
if (method.getName().equals("hashCode")) {
return Integer.valueOf(System.identityHashCode(proxy));
}
if (method.getName().equals("close")) {
return null;
}
try {
Object retVal = method.invoke(this.target, args);
if ((retVal instanceof Query)) {
JpaTemplate.this.prepareQuery((Query) retVal);
}
return retVal;
} catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
}
JdoTemplate
package org.springframework.orm.jdo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.Map;
import javax.jdo.JDOException;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@Deprecated
public class JdoTemplate extends JdoAccessor implements JdoOperations {
private boolean allowCreate = true;
private boolean exposeNativePersistenceManager = false;
public JdoTemplate() {
}
public JdoTemplate(PersistenceManagerFactory pmf) {
setPersistenceManagerFactory(pmf);
afterPropertiesSet();
}
public JdoTemplate(PersistenceManagerFactory pmf, boolean allowCreate) {
setPersistenceManagerFactory(pmf);
setAllowCreate(allowCreate);
afterPropertiesSet();
}
public void setAllowCreate(boolean allowCreate) {
this.allowCreate = allowCreate;
}
public boolean isAllowCreate() {
return this.allowCreate;
}
public void setExposeNativePersistenceManager(
boolean exposeNativePersistenceManager) {
this.exposeNativePersistenceManager = exposeNativePersistenceManager;
}
public boolean isExposeNativePersistenceManager() {
return this.exposeNativePersistenceManager;
}
public <T> T execute(JdoCallback<T> action) throws DataAccessException {
return execute(action, isExposeNativePersistenceManager());
}
public Collection executeFind(JdoCallback<?> action)
throws DataAccessException {
Object result = execute(action, isExposeNativePersistenceManager());
if ((result != null) && (!(result instanceof Collection))) {
throw new InvalidDataAccessApiUsageException(
"Result object returned from JdoCallback isn't a Collection: ["
+ result + "]");
}
return (Collection) result;
}
public <T> T execute(JdoCallback<T> action,
boolean exposeNativePersistenceManager) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
PersistenceManager pm = PersistenceManagerFactoryUtils
.getPersistenceManager(getPersistenceManagerFactory(),
isAllowCreate());
boolean existingTransaction = TransactionSynchronizationManager
.hasResource(getPersistenceManagerFactory());
try {
PersistenceManager pmToExpose = exposeNativePersistenceManager ? pm
: createPersistenceManagerProxy(pm);
T result = action.doInJdo(pmToExpose);
flushIfNecessary(pm, existingTransaction);
return postProcessResult(result, pm, existingTransaction);
} catch (JDOException ex) {
throw convertJdoAccessException(ex);
} catch (RuntimeException ex) {
throw ex;
} finally {
PersistenceManagerFactoryUtils.releasePersistenceManager(pm,
getPersistenceManagerFactory());
}
}
protected PersistenceManager createPersistenceManagerProxy(
PersistenceManager pm) {
Class[] ifcs = ClassUtils.getAllInterfacesForClass(pm.getClass(),
getClass().getClassLoader());
return (PersistenceManager) Proxy.newProxyInstance(pm.getClass()
.getClassLoader(), ifcs, new CloseSuppressingInvocationHandler(
pm));
}
protected <T> T postProcessResult(T result, PersistenceManager pm,
boolean existingTransaction) {
return result;
}
public Object getObjectById(final Object objectId)
throws DataAccessException {
execute(new JdoCallback() {
public Object doInJdo(PersistenceManager pm) throws JDOException {
return pm.getObjectById(objectId, true);
}
}, true);
}
public <T> T getObjectById(final Class<T> entityClass, final Object idValue)
throws DataAccessException {
execute(new JdoCallback() {
public T doInJdo(PersistenceManager pm) throws JDOException {
return pm.getObjectById(entityClass, idValue);
}
}, true);
}
public void evict(final Object entity) throws DataAccessException {
execute(new JdoCallback() {
public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.evict(entity);
return null;
}
}, true);
}
public void evictAll(final Collection entities) throws DataAccessException {
execute(new JdoCallback() {
public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.evictAll(entities);
return null;
}
}, true);
}
public void evictAll() throws DataAccessException {
execute(new JdoCallback() {
public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.evictAll();
return null;
}
}, true);
}
public void refresh(final Object entity) throws DataAccessException {
execute(new JdoCallback() {
public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.refresh(entity);
return null;
}
}, true);
}
public void refreshAll(final Collection entities)
throws DataAccessException {
execute(new JdoCallback() {
public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.refreshAll(entities);
return null;
}
}, true);
}
public void refreshAll() throws DataAccessException {
execute(new JdoCallback() {
public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.refreshAll();
return null;
}
}, true);
}
public <T> T makePersistent(final T entity) throws DataAccessException {
execute(new JdoCallback() {
public T doInJdo(PersistenceManager pm) throws JDOException {
return pm.makePersistent(entity);
}
}, true);
}
public <T> Collection<T> makePersistentAll(final Collection<T> entities)
throws DataAccessException
{
(Collection)execute(new JdoCallback()
{
public Collection<T> doInJdo(PersistenceManager pm)
throws JDOException
{
return pm.makePersistentAll(entities);
}
}, true);
}
public void deletePersistent(final Object entity)
throws DataAccessException {
execute(new JdoCallback() {
public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.deletePersistent(entity);
return null;
}
}, true);
}
public void deletePersistentAll(final Collection entities)
throws DataAccessException {
execute(new JdoCallback() {
public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.deletePersistentAll(entities);
return null;
}
}, true);
}
public <T> T detachCopy(final T entity) {
execute(new JdoCallback() {
public T doInJdo(PersistenceManager pm) throws JDOException {
return pm.detachCopy(entity);
}
}, true);
}
public <T> Collection<T> detachCopyAll(final Collection<T> entities)
{
(Collection)execute(new JdoCallback()
{
public Collection<T> doInJdo(PersistenceManager pm)
throws JDOException
{
return pm.detachCopyAll(entities);
}
}, true);
}
public void flush() throws DataAccessException {
execute(new JdoCallback() {
public Object doInJdo(PersistenceManager pm) throws JDOException {
pm.flush();
return null;
}
}, true);
}
public <T> Collection<T> find(Class<T> entityClass)
throws DataAccessException {
return find(entityClass, null, null);
}
public <T> Collection<T> find(Class<T> entityClass, String filter)
throws DataAccessException {
return find(entityClass, filter, null);
}
public <T> Collection<T> find(final Class<T> entityClass, final String filter, final String ordering)
throws DataAccessException
{
(Collection)execute(new JdoCallback()
{
public Collection<T> doInJdo(PersistenceManager pm)
throws JDOException
{
Query query = filter != null ? pm.newQuery(entityClass, filter) : pm.newQuery(entityClass);
JdoTemplate.this.prepareQuery(query);
if (ordering != null) {
query.setOrdering(ordering);
}
return (Collection)query.execute();
}
}, true);
}
public <T> Collection<T> find(Class<T> entityClass, String filter,
String parameters, Object... values) throws DataAccessException {
return find(entityClass, filter, parameters, values, null);
}
public <T> Collection<T> find(final Class<T> entityClass, final String filter, final String parameters, final Object[] values, final String ordering)
throws DataAccessException
{
(Collection)execute(new JdoCallback()
{
public Collection<T> doInJdo(PersistenceManager pm)
throws JDOException
{
Query query = pm.newQuery(entityClass, filter);
JdoTemplate.this.prepareQuery(query);
query.declareParameters(parameters);
if (ordering != null) {
query.setOrdering(ordering);
}
return (Collection)query.executeWithArray(values);
}
}, true);
}
public <T> Collection<T> find(Class<T> entityClass, String filter,
String parameters, Map<String, ?> values)
throws DataAccessException {
return find(entityClass, filter, parameters, values, null);
}
public <T> Collection<T> find(final Class<T> entityClass, final String filter, final String parameters, final Map<String, ?> values, final String ordering)
throws DataAccessException
{
(Collection)execute(new JdoCallback()
{
public Collection<T> doInJdo(PersistenceManager pm)
throws JDOException
{
Query query = pm.newQuery(entityClass, filter);
JdoTemplate.this.prepareQuery(query);
query.declareParameters(parameters);
if (ordering != null) {
query.setOrdering(ordering);
}
return (Collection)query.executeWithMap(values);
}
}, true);
}
public Collection find(final String language, final Object queryObject)
throws DataAccessException
{
(Collection)execute(new JdoCallback()
{
public Collection doInJdo(PersistenceManager pm)
throws JDOException
{
Query query = pm.newQuery(language, queryObject);
JdoTemplate.this.prepareQuery(query);
return (Collection)query.execute();
}
}, true);
}
public Collection find(final String queryString)
throws DataAccessException
{
(Collection)execute(new JdoCallback()
{
public Collection doInJdo(PersistenceManager pm)
throws JDOException
{
Query query = pm.newQuery(queryString);
JdoTemplate.this.prepareQuery(query);
return (Collection)query.execute();
}
}, true);
}
public Collection find(final String queryString, final Object... values)
throws DataAccessException
{
(Collection)execute(new JdoCallback()
{
public Collection doInJdo(PersistenceManager pm)
throws JDOException
{
Query query = pm.newQuery(queryString);
JdoTemplate.this.prepareQuery(query);
return (Collection)query.executeWithArray(values);
}
}, true);
}
public Collection find(final String queryString, final Map<String, ?> values)
throws DataAccessException
{
(Collection)execute(new JdoCallback()
{
public Collection doInJdo(PersistenceManager pm)
throws JDOException
{
Query query = pm.newQuery(queryString);
JdoTemplate.this.prepareQuery(query);
return (Collection)query.executeWithMap(values);
}
}, true);
}
public <T> Collection<T> findByNamedQuery(final Class<T> entityClass, final String queryName)
throws DataAccessException
{
(Collection)execute(new JdoCallback()
{
public Collection<T> doInJdo(PersistenceManager pm)
throws JDOException
{
Query query = pm.newNamedQuery(entityClass, queryName);
JdoTemplate.this.prepareQuery(query);
return (Collection)query.execute();
}
}, true);
}
public <T> Collection<T> findByNamedQuery(final Class<T> entityClass, final String queryName, final Object... values)
throws DataAccessException
{
(Collection)execute(new JdoCallback()
{
public Collection<T> doInJdo(PersistenceManager pm)
throws JDOException
{
Query query = pm.newNamedQuery(entityClass, queryName);
JdoTemplate.this.prepareQuery(query);
return (Collection)query.executeWithArray(values);
}
}, true);
}
public <T> Collection<T> findByNamedQuery(final Class<T> entityClass, final String queryName, final Map<String, ?> values)
throws DataAccessException
{
(Collection)execute(new JdoCallback()
{
public Collection<T> doInJdo(PersistenceManager pm)
throws JDOException
{
Query query = pm.newNamedQuery(entityClass, queryName);
JdoTemplate.this.prepareQuery(query);
return (Collection)query.executeWithMap(values);
}
}, true);
}
public void prepareQuery(Query query) throws JDOException {
PersistenceManagerFactoryUtils.applyTransactionTimeout(query,
getPersistenceManagerFactory(), getJdoDialect());
}
private class CloseSuppressingInvocationHandler implements
InvocationHandler {
private final PersistenceManager target;
public CloseSuppressingInvocationHandler(PersistenceManager target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if (method.getName().equals("equals")) {
return Boolean.valueOf(proxy == args[0]);
}
if (method.getName().equals("hashCode")) {
return Integer.valueOf(System.identityHashCode(proxy));
}
if (method.getName().equals("close")) {
return null;
}
try {
Object retVal = method.invoke(this.target, args);
if ((retVal instanceof Query)) {
JdoTemplate.this.prepareQuery((Query) retVal);
}
return retVal;
} catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
}
SqlMapClientTemplate
package org.springframework.orm.ibatis;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapExecutor;
import com.ibatis.sqlmap.client.event.RowHandler;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.JdbcUpdateAffectedIncorrectNumberOfRowsException;
import org.springframework.jdbc.support.JdbcAccessor;
@Deprecated
public class SqlMapClientTemplate extends JdbcAccessor implements
SqlMapClientOperations {
private SqlMapClient sqlMapClient;
public SqlMapClientTemplate() {
}
public SqlMapClientTemplate(SqlMapClient sqlMapClient) {
setSqlMapClient(sqlMapClient);
afterPropertiesSet();
}
public SqlMapClientTemplate(DataSource dataSource, SqlMapClient sqlMapClient) {
setDataSource(dataSource);
setSqlMapClient(sqlMapClient);
afterPropertiesSet();
}
public void setSqlMapClient(SqlMapClient sqlMapClient) {
this.sqlMapClient = sqlMapClient;
}
public SqlMapClient getSqlMapClient() {
return this.sqlMapClient;
}
public DataSource getDataSource() {
DataSource ds = super.getDataSource();
return ds != null ? ds : this.sqlMapClient.getDataSource();
}
public void afterPropertiesSet() {
if (this.sqlMapClient == null) {
throw new IllegalArgumentException(
"Property 'sqlMapClient' is required");
}
super.afterPropertiesSet();
}
/* Error */
public <T> T execute(SqlMapClientCallback<T> action)
throws DataAccessException {
}
@Deprecated
public List executeWithListResult(SqlMapClientCallback<List> action)
throws DataAccessException {
return (List) execute(action);
}
@Deprecated
public Map executeWithMapResult(SqlMapClientCallback<Map> action)
throws DataAccessException {
return (Map) execute(action);
}
public Object queryForObject(String statementName)
throws DataAccessException {
return queryForObject(statementName, null);
}
public Object queryForObject(final String statementName,
final Object parameterObject) throws DataAccessException {
execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor)
throws SQLException {
return executor.queryForObject(statementName, parameterObject);
}
});
}
public Object queryForObject(final String statementName,
final Object parameterObject, final Object resultObject)
throws DataAccessException {
execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor)
throws SQLException {
return executor.queryForObject(statementName, parameterObject,
resultObject);
}
});
}
public List queryForList(String statementName) throws DataAccessException {
return queryForList(statementName, null);
}
public List queryForList(final String statementName, final Object parameterObject)
throws DataAccessException
{
(List)execute(new SqlMapClientCallback()
{
public List doInSqlMapClient(SqlMapExecutor executor)
throws SQLException
{
return executor.queryForList(statementName, parameterObject);
}
});
}
public List queryForList(String statementName, int skipResults,
int maxResults) throws DataAccessException {
return queryForList(statementName, null, skipResults, maxResults);
}
public List queryForList(final String statementName, final Object parameterObject, final int skipResults, final int maxResults)
throws DataAccessException
{
(List)execute(new SqlMapClientCallback()
{
public List doInSqlMapClient(SqlMapExecutor executor)
throws SQLException
{
return executor.queryForList(statementName, parameterObject, skipResults, maxResults);
}
});
}
public void queryWithRowHandler(String statementName, RowHandler rowHandler)
throws DataAccessException {
queryWithRowHandler(statementName, null, rowHandler);
}
public void queryWithRowHandler(final String statementName,
final Object parameterObject, final RowHandler rowHandler)
throws DataAccessException {
execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor)
throws SQLException {
executor.queryWithRowHandler(statementName, parameterObject,
rowHandler);
return null;
}
});
}
public Map queryForMap(final String statementName, final Object parameterObject, final String keyProperty)
throws DataAccessException
{
(Map)execute(new SqlMapClientCallback()
{
public Map doInSqlMapClient(SqlMapExecutor executor)
throws SQLException
{
return executor.queryForMap(statementName, parameterObject, keyProperty);
}
});
}
public Map queryForMap(final String statementName, final Object parameterObject, final String keyProperty, final String valueProperty)
throws DataAccessException
{
(Map)execute(new SqlMapClientCallback()
{
public Map doInSqlMapClient(SqlMapExecutor executor)
throws SQLException
{
return executor.queryForMap(statementName, parameterObject, keyProperty, valueProperty);
}
});
}
public Object insert(String statementName) throws DataAccessException {
return insert(statementName, null);
}
public Object insert(final String statementName,
final Object parameterObject) throws DataAccessException {
execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor)
throws SQLException {
return executor.insert(statementName, parameterObject);
}
});
}
public int update(String statementName) throws DataAccessException {
return update(statementName, null);
}
public int update(final String statementName, final Object parameterObject)
throws DataAccessException {
((Integer) execute(new SqlMapClientCallback() {
public Integer doInSqlMapClient(SqlMapExecutor executor)
throws SQLException {
return Integer.valueOf(executor.update(statementName,
parameterObject));
}
})).intValue();
}
public void update(String statementName, Object parameterObject,
int requiredRowsAffected) throws DataAccessException {
int actualRowsAffected = update(statementName, parameterObject);
if (actualRowsAffected != requiredRowsAffected) {
throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(
statementName, requiredRowsAffected, actualRowsAffected);
}
}
public int delete(String statementName) throws DataAccessException {
return delete(statementName, null);
}
public int delete(final String statementName, final Object parameterObject)
throws DataAccessException {
((Integer) execute(new SqlMapClientCallback() {
public Integer doInSqlMapClient(SqlMapExecutor executor)
throws SQLException {
return Integer.valueOf(executor.delete(statementName,
parameterObject));
}
})).intValue();
}
public void delete(String statementName, Object parameterObject,
int requiredRowsAffected) throws DataAccessException {
int actualRowsAffected = delete(statementName, parameterObject);
if (actualRowsAffected != requiredRowsAffected) {
throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(
statementName, requiredRowsAffected, actualRowsAffected);
}
}
}