spring-data-relational icon indicating copy to clipboard operation
spring-data-relational copied to clipboard

DATAJDBC-373 - Integration Mybatis with spring-data-jdbc,make mybatis can mixed with…

Open neil4dong opened this issue 5 years ago • 13 comments

Integration Mybatis with spring-data-jdbc,make mybatis can mixed with spring-data-jdbc in ONE repository by annotation with @MybatisQuery

And also Integration tests provided.

Please check out if this way is feasible ? In my case we currently use mybatis for data access, and we are considering to migrate to spring-data-jdbc, but we have a lot of complex SQL which organized by Mybatis.

Considering the migration cost, how about use mybaitis and spring-data-jdbc together, so we can benefit form

  1. the simplicity provided form spring-data-jdbc
  2. another complex SQL solution provided by mybatis (which now only provided by QueryDsl)

neil4dong avatar May 16 '19 02:05 neil4dong

@neil4dong Please sign the Contributor License Agreement!

Click here to manually synchronize the status of this Pull Request.

See the FAQ for frequently asked questions.

pivotal-issuemaster avatar May 16 '19 02:05 pivotal-issuemaster

@neil4dong Thank you for signing the Contributor License Agreement!

pivotal-issuemaster avatar May 16 '19 02:05 pivotal-issuemaster

Please create an issue at https://jira.spring.io/browse/DATAJDBC so we can discuss the goal of the PR first.

schauder avatar May 16 '19 05:05 schauder

Issue was created. Adding here the link to ease tracking https://jira.spring.io/projects/DATAJDBC/issues/DATAJDBC-373

jmsanzg avatar Jul 15 '19 07:07 jmsanzg

At a first very cursory glance this looks reasonable. But I think we should treet MyBatis as a source for named queries. I.e. by default we should try to find a MyBatis query based on the name of the method and alternatively offer the option to supply a name in the @Query annotation.

There is already work in progress for something similar based on property files (#180). I'll will first try to get that one onto the main branch before giving a proper review to this issue with proper instructions how to proceed.

One minor thing until then: It seems like formatting got changed for JdbcQueryLookupStrategy.java. Please make sure you use the proper formatter. See https://github.com/spring-projects/spring-data-build/blob/master/CONTRIBUTING.adoc#quickstart

schauder avatar Nov 19 '19 14:11 schauder

Hi, schauder , a year have passed. I check the feture "propety file based NamedQuery", If i'm correct ,it just move sql to a property file.

If I need to build dynamic sql, is there a way to do so without using JPA (only use spring-data-jdbc) In one repository ?

I also checked document https://docs.spring.io/spring-data/data-jdbc/docs/2.0.0.RELEASE/reference/html/#repositories.custom-implementations It says I can mix springdatajdbc repository with customized repository,I tried to make a demo , but it doesn't work . Is this feature implemented?

looking forward your apply ,thanks.

neil4dong avatar Jun 04 '20 10:06 neil4dong

Custom methods should work, yes. If they don't please create a ticket.

schauder avatar Jun 04 '20 11:06 schauder

@neil4dong Could you rebase this PR to resolve the merge conflicts?

schauder avatar Jun 08 '20 07:06 schauder

@schauder yes. the Custom methods is working in newer version.
sorry, I have not check the github notifications due to I'm very busy recently , I will rebase the PR when I'm free.

neil4dong avatar Jul 17 '20 14:07 neil4dong

And when I use Customized Method , I feel that is also a good way to integrate Mybatis Into springdata. event better. we can discuss here.

`

import xxxxxx.xxxxx.xxxxx.MybatisConfig;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration;
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactoryBean;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryComposition;
import org.springframework.lang.NonNull;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

//Mybatis load before this
@Import(MybatisConfig.class)
@Configuration
@EnableJdbcRepositories(basePackages = "com.dmall.dfp.invoicing.dao.springdatajdbc", repositoryFactoryBeanClass = SpringDataJdbcConfig.MybatisWithJdbcRepository.class)
public class SpringDataJdbcConfig extends AbstractJdbcConfiguration {

    /**
     * 集成mybatis 和 spring-data-jdbc.    混合在一个类中使用.     
     * 只需要SpringDataJdbc的Repository上implement Mybatis的接口就可以路由到mybatis
     *
     * 使用此类时,需要手动Import mybatis 的配置,使mybatis先于此类加载
     */
    public static class MybatisWithJdbcRepository<T extends Repository<S, ID>, S, ID extends Serializable> extends JdbcRepositoryFactoryBean<T, S, ID> implements ApplicationContextAware {
        private ApplicationContext applicationContext;

        public static Class<? extends Annotation> annotationClass = Mapper.class;

        /**
         * Creates a new {@link MybatisWithJdbcRepository} for the given repository interface.
         *
         * @param repositoryInterface must not be {@literal null}.
         */
        protected MybatisWithJdbcRepository(Class<? extends T> repositoryInterface) {
            super(repositoryInterface);
        }

        @Override
        public void afterPropertiesSet() {
            Class<? extends T> repositoryInterface = getObjectType();
            for (Type genericInterface : repositoryInterface.getGenericInterfaces()) {
                Class<?> clazz = genericInterface instanceof Class ? ((Class) genericInterface) : null;
                if (clazz != null && clazz.isAnnotationPresent(annotationClass)) {
                    Object bean = applicationContext.getBean(clazz);
                    setRepositoryFragments(RepositoryComposition.RepositoryFragments.just(bean));
                }
            }
            super.afterPropertiesSet();
        }

        @Override
        public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    }
}

neil4dong avatar Jul 17 '20 14:07 neil4dong

When we use the configuration above , We only need to make a mybatis interface and let mybatis mechanism work, then extends the interface on our Spring Data Jdbc Repository.

neil4dong avatar Jul 17 '20 14:07 neil4dong

Let's move the discussion to https://jira.spring.io/projects/DATAJDBC/issues/DATAJDBC-373 since it seems we are discussing the merit of the feature itself and not just that of the current PR.

schauder avatar Oct 28 '20 07:10 schauder