Skip to content

Expose properties in DefaultParameterHandler.java #2172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
johnny2002 opened this issue Feb 5, 2021 · 7 comments
Open

Expose properties in DefaultParameterHandler.java #2172

johnny2002 opened this issue Feb 5, 2021 · 7 comments

Comments

@johnny2002
Copy link

In order to extend mybatis to support batch sql by Preparedstatement, we need to add an plugin, thus, in the pulgin, we need to get "mappedStatement", "parameterObject","boundSql" from DefaultParameterHandler.java. While, these 3 properties are all private, so we have to use reflect.

Suggest to add getters for these 3 properties.
Full path:
/src/main/java/org/apache/ibatis/scripting/defaults/DefaultParameterHandler.java

@johnny2002
Copy link
Author

sample code to use these properties as below:

public class BatchParameterHandler implements Interceptor {

    public Object intercept(Invocation invocation) throws Throwable {
        if (invocation.getTarget() instanceof DefaultParameterHandler) {
            DefaultParameterHandler parameterHandler = (DefaultParameterHandler) invocation.getTarget();

            MappedStatement mappedStatement = (MappedStatement) ReflectUtils.getValueByFieldName(parameterHandler, "mappedStatement");

            Object paramObj = ReflectUtils.getValueByFieldName(parameterHandler, "parameterObject");
            if (paramObj instanceof BatchParameter) {

                PreparedStatement ps = (PreparedStatement) invocation.getArgs()[0];
                BoundSql boundSql = (BoundSql) ReflectUtils.getValueByFieldName(parameterHandler, "boundSql");

                @SuppressWarnings({ "unchecked", "rawtypes" })
                List<Object> parameterObject = (List) ((BatchParameter) paramObj).getData();

                ps.clearBatch();
                ps.clearParameters();

                @SuppressWarnings("rawtypes")
                int batchSize = ((BatchParameter) paramObj).getBatchSize();
                int i = 0;
                for (Object pobject : parameterObject) {
                    DefaultParameterHandler handler = new DefaultParameterHandler(mappedStatement, pobject, boundSql);
                    handler.setParameters(ps);
                    ps.addBatch();
                    i += 1;
                    if (i % batchSize == 0) {
                        ps.executeBatch();
                    }
                }
                if (parameterObject.size() % batchSize != 0) {
                    ps.executeBatch();
                }

                return i;
            }
        }

        return invocation.proceed();
    }

    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    public void setProperties(Properties properties) {

    }

}

@bitgaoshu
Copy link

defaultExecutorType can satisfy ?

@johnny2002
Copy link
Author

johnny2002 commented Feb 9, 2021

defaultExecutorType

defaultExecutorType looks attractive, while, how can I use BATCH only for specified SQL IDs and others use SIMPLE?

@bitgaoshu
Copy link

in different sqlSession?

@johnny2002
Copy link
Author

johnny2002 commented Feb 22, 2021

in different sqlSession?

Hi bitgaoshu, happy Chinese New Year to you!
Seems this can resolve ExecutorType probleam. While, another problem is that BATCH ExecutorType actually also execute each line a time, but I want to use PreparedStatement.addBatch() to execute many lines a time, this way is far more efficient. If only you can add another ExecutorType to use PreparedStatement.addBatch().

@johnny2002
Copy link
Author

johnny2002 commented Feb 22, 2021

So, even my problem is resolved by adding aonther ExecutorType, I think, Expose properties in DefaultParameterHandler.java can bring more flexiblity to developers, why not do it?
As a generic framework, extensibility is very important to users.
For simular situation, I have suggestted Spring framework to did many same things. see:
spring-projects/spring-framework#25323
spring-cloud/spring-cloud-openfeign#278
OpenFeign/feign#1162
apache/shardingsphere#7471

@harawata
Copy link
Member

harawata commented Feb 22, 2021

Hello @johnny2002 !

I'm sorry about the belated response.
As @bitgaoshu pointed out, MyBatis already has batch executor type to execute batch operation.
I would suggest you to take a look at this demo.

Regarding your request, there have been similar requests before, but we have no plan to expose those internal variables (they are intentionally hidden from the public API).
You are welcome to use reflection (at your own risk) if necessary.

BATCH ExecutorType actually also execute each line a time, but I want to use PreparedStatement.addBatch() to execute many lines a time

I'm pretty sure MyBatis uses addBatch().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants