What problem are you trying to solve, or goal you're trying to achieve by doing this? Is it strictly a performance consideration?
Clinton On Fri, Jan 1, 2010 at 7:31 AM, Eduardo Macarron <eduardo.macar...@gmail.com > wrote: > Fist of all happy new year! > > Some work has been doing on Spring 3 and Ibatis 3 integration. > > Having a look at mappers internals we saw that a new MapperMethod is > created (with some introspection work) on each call to a mapper method. I > wonder if it would be better to build them all during startup or maybe cache > them somehow. > > this is the Jira issue (http://jira.springframework.org/browse/SPR-5991) > Grabriel Axel posted it here some months ago (he opened the issue) > > The main problem with this task is that MapperMethods are not thread safe > and that they hold an SqlSession. Enabling cache would require to make some > changes to MapperMethods. SqlSession should be passed as an argument to > execute instead to its constructor. > > public MapperMethod(Method method, Configuration configuration) { > paramNames = new ArrayList<String>(); > paramPositions = new ArrayList<Integer>(); > ... > > public Object execute(Object[] args, SqlSession sqlSession) { > Object result; > if (SqlCommandType.INSERT == type) { > ... > > And MapperProxy > > public Object invoke(Object proxy, Method method, Object[] args) throws > Throwable { > return new MapperMethod(method, > sqlSession.getConfiguration()).execute(args, sqlSession); > } > > > So for example Spring could have this code to use directly injected Mappers > where SqlSession is got from spring's transaction context. > > private Map<Method, MapperMethod> mapperMethods = new > ConcurrentHashMap<Method, MapperMethod>(); > > public <T> T getMapper(final Class<T> type) { > // mimic iBATIS MapperProxy > return (T) > java.lang.reflect.Proxy.newProxyInstance(type.getClassLoader(), new Class[] > { type }, > new InvocationHandler() { > @Override > public Object invoke(final Object proxy, final Method > method, final Object[] args) throws Throwable { > return execute(new SqlSessionCallback<T>() { > @Override > public T doInSqlSession(SqlSession sqlSession) > throws SQLException { > // mimic iBATIS MapperProxy > Class<?> type = method.getDeclaringClass(); > if > (!sqlSession.getConfiguration().hasMapper(type)) { > throw new BindingException("Type " + type + > " is not known to the MapperRegistry."); > } > > MapperMethod mm = mapperMethods.get(method); > if (mm == null) { > mm = new MapperMethod(method, > sqlSession.getConfiguration()); > mapperMethods.put(method, mm); > } else { > logger.debug("Returning a cached mapper > method"); > } > > return (T) mm.execute(args, sqlSession); > } > }); > } > }); > } > > Or maybe avoid using directly MapperMethods and access to them thought the > "standard" api SqlSession.getConfiguration().getMapper(impl, sesion) but in > that case caching should be done inside. > > what do you think about this? > > >