Code Monkey home page Code Monkey logo

reactive-mybatis-support's Introduction

Build and Test With Maven [2.x] Maven Central

Build and Test With Maven [3.x] Maven Central

JDK/R2DBC-SPI/Spring-Boot Compatibility

  • Refer to the table below to determine the appropriate version of mybatis-r2dbc for your project.

Exclude the v prefix when using the version number.

Compiled JDK 8 11 17
r2dbc-spi 0.9.1.RELEASE 1.0.0.RELEASE 1.0.0.RELEASE
mybatis-r2dbc Maven Central Maven Central --
mybatis-r2dbc-generator Maven Central Maven Central --
mybatis-r2dbc-spring Maven Central -- Maven Central
Spring Boot [2.7.x,3.0.0) -- [3.0.0,~)
  • The whole project reactive-mybatis-support(2.x.x) is compiled with JDK8 and SpringBoot(2.7.x), aka r2dbc-spi(0.9.1.RELEASE)
  • The mybatis-r2dbc(3.x.x) and mybatis-r2dbc-generator(3.x.x) are compiled with JDK11, aka r2dbc-spi(1.0.0.RELEASE).
  • The mybatis-r2dbc-spring(3.x.x) is compiled with JDK17 and SpringBoot(3.x.x), aka r2dbc-spi(1.0.0.RELEASE).

Instruction

  • Reactive Mybatis Support is aimed to adapt original mybatis to reactive project (aka WebFlux/Reactor3) with r2dbc drivers.
  • mybatis-r2dbc module is inspired by linux-china/mybatis-r2dbc and based on mybatis3's original source code.
  • mybatis-generator module is used to adapt mybatis-dynamic-sql to reactive project.
  • Most of the MyBatis3 features are applicable, but there are a few features that are not supported:
    • ❌ 1 . mybatis-plugin
    • ❌ 2 . multi ResultSets or Results
    • ❌ 3 . nested query with multi SQL statements
    • ❌️ 4 . blocking java type (aka: InputStream .eg)
  • For more usage instructions, please refer to the wiki: WIKI

Maven Central

  • dependency
<dependencies>
    <dependency>
      <groupId>pro.chenggang</groupId>
      <artifactId>mybatis-r2dbc</artifactId>
      <version>${compatible-version}</version>
    </dependency>
    <dependency>
      <groupId>pro.chenggang</groupId>
      <artifactId>mybatis-r2dbc-generator</artifactId>
      <version>${compatible-version}</version>
    </dependency>
    <dependency>
      <groupId>pro.chenggang</groupId>
      <artifactId>mybatis-r2dbc-spring</artifactId>
      <version>${compatible-version}</version>
    </dependency>
</dependencies>

Reference

reactive-mybatis-support's People

Contributors

chenggangpro avatar cooperlyt avatar dependabot[bot] avatar yuyayokoyama8864 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

reactive-mybatis-support's Issues

ResultHandler handle single nested query result returns null when there is only 1 nested result record

The work is great! thanks.
I just found that if there is a tag collection in resultMap, it will return empty.

I found there is only 1 record, the code return null.

By using the project sample, after run the following sql:

delete from emp where dept_no in (2,3,4);
delete from dept where dept_no in (2,3,4);

The test case will failed.

    @Test
    public void testGetDeptWithEmpCount() throws Exception {
        this.reactiveSqlSessionOperator.executeMany(
                this.deptMapper.selectDeptWithEmpList())
                .as(StepVerifier::create)
                .expectNextCount(1)
                .verifyComplete();
    }

I guess the problem is in the mybatis-r2dbc\src\main\java\pro\chenggang\project\reactive\mybatis\support\r2dbc\executor\result\handler\DefaultReactiveResultHandler.java
the totalCount is 0 in this case.

    private List<Object> handleRowValuesForNestedResultMap(RowResultWrapper rowResultWrapper, ResultMap resultMap) throws SQLException {
        // ...
        this.resultHolder.addAll(resultHandler.getResultList());
        if (totalCount.intValue() != 0 && null == partialObject) {
            List<Object> holdResultList = new ArrayList<>(this.resultHolder);
            this.resultHolder.clear();
            return holdResultList;
        }
        return Collections.singletonList(DEFERRED);
}

The insert operation must provide keyColumn, but no need before

The following content worked when use mybatis, but failed when use mybatis_r2dbc,

<insert id="insert" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId">

To get the mybatis_r2dbc working, I have to provide values for keyColumn elements

<insert id="insert" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId" keyColumn="user_id">

Exception with @MapperScan

@MapperScan is not work!

@SpringBootApplication
@MapperScan({"xx.mapper"})
public class Application {
   ...
}

throw exception:

Caused by: java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
	at org.springframework.util.Assert.notNull(Assert.java:201)
	at org.mybatis.spring.support.SqlSessionDaoSupport.checkDaoConfig(SqlSessionDaoSupport.java:122)
	at org.mybatis.spring.mapper.MapperFactoryBean.checkDaoConfig(MapperFactoryBean.java:73)
	at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
	... 101 more

Change to @Mapper is worked!

ReactiveSqlSession.openSession()返回的ReactiveSqlSession是个单例对象

我看源码发现DefaultReactiveSqlSession.openSession()返回的ReactiveSqlSession不是新创建的,而是一个全局变量。这样导致所有线程设置的事务等参数都是在同一个ReactiveSqlSession上进行的,会相互覆盖。另外,我发现并发的时候由于用的是同一个sqlSession,所有跟数据库的通讯都是串行执行的,无论并发量多大,数据库查到都只有一个连接。不知道能否优化?难道要动态创建新的DefaultReactiveSqlSession吗?

EnumTypeHandler to not being registered

Mybatis Default EnumTypeHandler is Not be auto register,
I Got a ClassCastException by Enum.
Need I Register it by manual ?
Or
Need I implement a R2dbcTypeHandlerAdapter?

Exception with @R2dbcMapperScan and @Repository

@R2dbcMapperScan include a @repository throws exception:

Caused by: java.lang.ClassNotFoundException: net.bytebuddy.renamed.java.lang.Object$ByteBuddy$hogupVqa at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)

@R2dbcMapperScan("xxx.r2dbc.mapper")
public class WorkerIdAutoConfigure {
//...
}

@Repository
public interface R2dbcWorkerNodeMapper {
//...
}

Just remove @repository, It's worked!

Change to get the database type using in `PlaceholderFormatter` from `ConnectionFactory` to `Connection`

When using AbstractRoutingConnectionFactory(From spring-data-r2dbc) with multi database. The way PlaceholderFormatter gets the database type in purpose of formatting sql with different dialect is through ConnectionFactory.getMetadata(), the way currently used that does not work with different types of databases.this should be changed to Connection.getMetadata() in order to work properly with multiple types of databases.

关于r2dbc如何整合国产数据库达梦

我想问一下就是如何用这个reactive-mybatis-support如何连接达梦数据库并操作呢,目前有没有这样的计划或者有什么解决办法,我看项目分支都没有这个,因此问一下,感谢您的回答。

Refactor ReactiveResultHandler

    1. Use resultOrdered to reduce the cache generated when nested-result-map processing
    1. Make ReactiveResultHandler's handleResult method return single value

Exception with useGeneratedKeys = false

Exception with useGeneratedKeys set to false. same code set to true will be worked!

Suppressed: java.lang.ClassCastException: class java.lang.Long cannot be cast to class java.lang.Integer (java.lang.Long and java.lang.Integer are in module java.base of loader 'bootstrap')

...
        <dependency>
            <groupId>org.mariadb</groupId>
            <artifactId>r2dbc-mariadb</artifactId>
            <version>1.1.3</version>
        </dependency>
...

This is my test code in mapper:

//  create table TEST1(ID bigint NOT NULL AUTO_INCREMENT , NAME VARCHAR(10) NULL, PRIMARY KEY(ID));
  @Insert("INSERT INTO TEST1(NAME)" +
      " VALUES(#{name})")
  @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "ID")
  Mono<Integer> addTest1(Tmod mod);  // **This is Worked.**

  @Insert("INSERT INTO TEST1(NAME)" +
      " VALUES(#{name})")
  @Options(useGeneratedKeys =false)
  Mono<Integer> addTest1( @Param("name")String name); // **This throws  Exception**

//  create table TEST2(ID bigint NOT NULL  , NAME VARCHAR(10) NULL, PRIMARY KEY(ID));
  @Insert("INSERT INTO TEST2(ID,NAME)" +
      " VALUES(#{id},#{name})")
  Mono<Integer> addTest2(@Param("id") long id, @Param("name")String name);// **This throws  Exception too**

Return type change to Mono<Long> is same exception.

mapperLocations excess warning

Even if mapperLocations were not specified (= null), library still shows warning:
Property 'mapperLocations' was specified but matching resources are not found.
That's because resolveMapperLocations() method never returns null. The fix should be as follows: resolveMapperLocations() should return null if mapperLocations==null.

why do u use R2DBC

Hi, i am reading your project and i am interested in this, but i have a question, why do you use R2DBC instead of other non blocking IO like Hibernate Reactive or others... can you tell me your purpose, the pros and cons of R2DBC, thank you so much

Return Optional<T>

If Query return null , current is return Mono.emty can't map or other operation like this:

Mono<Tmod> getSomething(@Param("id") long id);
getSomething(1l).map(obj -> {
      if (obj == null) 
         ...
         can't work
});

So if return Optional is best , but is not support in this version.

Optional is work fine in mabatis jdbc.

Mono<Optional<Tmod>> getSomething(@Param("id") long id);

getSomething(1l).map(obj -> obj.orElse(...));

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.