Skip to content

Commit

Permalink
Fix #6490 add mybatis extension
Browse files Browse the repository at this point in the history
  • Loading branch information
zhfeng committed Jul 13, 2020
1 parent abcd741 commit e1613c6
Show file tree
Hide file tree
Showing 19 changed files with 604 additions and 0 deletions.
16 changes: 16 additions & 0 deletions bom/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<microprofile-opentracing-api.version>1.3.3</microprofile-opentracing-api.version>
<microprofile-reactive-streams-operators.version>1.0.1</microprofile-reactive-streams-operators.version>
<microprofile-rest-client.version>1.4.1</microprofile-rest-client.version>
<mybatis.version>3.5.5</mybatis.version>
<smallrye-config.version>1.8.1</smallrye-config.version>
<smallrye-health.version>2.2.2</smallrye-health.version>
<smallrye-metrics.version>2.4.2</smallrye-metrics.version>
Expand Down Expand Up @@ -1186,6 +1187,16 @@
<artifactId>quarkus-mongodb-client-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-mybatis</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-mybatis-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-grpc</artifactId>
Expand Down Expand Up @@ -2785,6 +2796,11 @@
<artifactId>mongodb-crypt</artifactId>
<version>${mongo-crypt.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId>
Expand Down
69 changes: 69 additions & 0 deletions extensions/mybatis/deployment/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quarkus-mybatis-parent</artifactId>
<groupId>io.quarkus</groupId>
<version>999-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>quarkus-mybatis-deployment</artifactId>
<name>Quarkus - Mybatis - Deployment</name>

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-agroal-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-mybatis</artifactId>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-internal</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2-deployment</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-processor</artifactId>
<version>${project.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.quarkus.mybatis.deployment;

import org.jboss.jandex.DotName;

import io.quarkus.builder.item.MultiBuildItem;

public final class MyBatisMapperBuildItem extends MultiBuildItem {
private final DotName dotName;

public MyBatisMapperBuildItem(DotName dotName) {
this.dotName = dotName;
}

public DotName getDotName() {
return dotName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package io.quarkus.mybatis.deployment;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.inject.Singleton;

import org.apache.ibatis.annotations.Mapper;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.DotName;
import org.jboss.logging.Logger;

import io.quarkus.agroal.deployment.JdbcDataSourceBuildItem;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.BeanContainerBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.configuration.ConfigurationError;
import io.quarkus.mybatis.runtime.MyBatisProducers;
import io.quarkus.mybatis.runtime.MyBatisRecorder;
import io.quarkus.mybatis.runtime.MyBatisRuntimeConfig;

class MybatisProcessor {

private static final Logger LOG = Logger.getLogger(MybatisProcessor.class);
private static final String FEATURE = "mybatis";
private static final DotName MYBATIS_MAPPER = DotName.createSimple(Mapper.class.getName());

@BuildStep
FeatureBuildItem feature() {
return new FeatureBuildItem(FEATURE);
}

@BuildStep
void addMyBatisMappers(BuildProducer<MyBatisMapperBuildItem> mappers,
BuildProducer<AdditionalBeanBuildItem> additionalBeans,
CombinedIndexBuildItem indexBuildItem) {
for (AnnotationInstance i : indexBuildItem.getIndex().getAnnotations(MYBATIS_MAPPER)) {
if (i.target().kind() == AnnotationTarget.Kind.CLASS) {
DotName dotName = i.target().asClass().name();
mappers.produce(new MyBatisMapperBuildItem(dotName));
additionalBeans.produce(new AdditionalBeanBuildItem(dotName.toString()));
}
}
}

@BuildStep
void unremovableBeans(BuildProducer<AdditionalBeanBuildItem> beanProducer) {
beanProducer.produce(AdditionalBeanBuildItem.unremovableOf(MyBatisProducers.class));
}

@Record(ExecutionTime.RUNTIME_INIT)
@BuildStep
SqlSessionFactoryBuildItem generateSqlSessionFactory(MyBatisRuntimeConfig myBatisRuntimeConfig,
List<MyBatisMapperBuildItem> myBatisMapperBuildItems,
List<JdbcDataSourceBuildItem> jdbcDataSourcesBuildItem,
MyBatisRecorder recorder) {
List<String> mappers = myBatisMapperBuildItems
.stream().map(m -> m.getDotName().toString()).collect(Collectors.toList());

String dataSourceName;
if (myBatisRuntimeConfig.dataSource.isPresent()) {
dataSourceName = myBatisRuntimeConfig.dataSource.get();
Optional<JdbcDataSourceBuildItem> jdbcDataSourceBuildItem = jdbcDataSourcesBuildItem.stream()
.filter(i -> i.getName().equals(dataSourceName))
.findFirst();
if (!jdbcDataSourceBuildItem.isPresent()) {
throw new ConfigurationError("Can not find datasource " + dataSourceName);
}
} else {
Optional<JdbcDataSourceBuildItem> defaultJdbcDataSourceBuildItem = jdbcDataSourcesBuildItem.stream()
.filter(i -> i.isDefault())
.findFirst();
if (defaultJdbcDataSourceBuildItem.isPresent()) {
dataSourceName = defaultJdbcDataSourceBuildItem.get().getName();
} else {
throw new ConfigurationError("No default datasource");
}
}

return new SqlSessionFactoryBuildItem(recorder.createSqlSessionFactory(
myBatisRuntimeConfig.environment,
myBatisRuntimeConfig.transactionFactory,
dataSourceName,
mappers));
}

@Record(ExecutionTime.RUNTIME_INIT)
@BuildStep
SqlSessionManagerBuildItem generateSqlSessionManager(SqlSessionFactoryBuildItem sqlSessionFactoryBuildItem,
MyBatisRecorder recorder) {
return new SqlSessionManagerBuildItem(recorder.createSqlSessionManager(
sqlSessionFactoryBuildItem.getSqlSessionFactory()));
}

@Record(ExecutionTime.RUNTIME_INIT)
@BuildStep
void generateMapperBeans(MyBatisRecorder recorder,
List<MyBatisMapperBuildItem> myBatisMapperBuildItems,
SqlSessionManagerBuildItem sqlSessionManagerBuildItem,
BuildProducer<SyntheticBeanBuildItem> syntheticBeanBuildItemBuildProducer) {

for (MyBatisMapperBuildItem i : myBatisMapperBuildItems) {
SyntheticBeanBuildItem.ExtendedBeanConfigurator configurator = SyntheticBeanBuildItem
.configure(i.getDotName())
.scope(Singleton.class)
.setRuntimeInit()
.unremovable()
.supplier(recorder.MyBatisMapperSupplier(i.getDotName().toString(),
sqlSessionManagerBuildItem.getSqlSessionManager()));
syntheticBeanBuildItemBuildProducer.produce(configurator.done());
}
}

@Record(ExecutionTime.RUNTIME_INIT)
@BuildStep
void register(SqlSessionFactoryBuildItem sqlSessionFactoryBuildItem,
BeanContainerBuildItem beanContainerBuildItem,
MyBatisRecorder recorder) {
recorder.register(sqlSessionFactoryBuildItem.getSqlSessionFactory(), beanContainerBuildItem.getValue());
}

@Record(ExecutionTime.RUNTIME_INIT)
@BuildStep
void runInitialSql(SqlSessionFactoryBuildItem sqlSessionFactoryBuildItem,
MyBatisRuntimeConfig myBatisRuntimeConfig,
MyBatisRecorder recorder) {
if (myBatisRuntimeConfig.initialSql.isPresent()) {
recorder.runInitialSql(sqlSessionFactoryBuildItem.getSqlSessionFactory(),
myBatisRuntimeConfig.initialSql.get());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.quarkus.mybatis.deployment;

import org.apache.ibatis.session.SqlSessionFactory;

import io.quarkus.builder.item.SimpleBuildItem;
import io.quarkus.runtime.RuntimeValue;

/**
* Hold the RuntimeValue of {@link SqlSessionFactory}
*/
public final class SqlSessionFactoryBuildItem extends SimpleBuildItem {
private final RuntimeValue<SqlSessionFactory> sqlSessionFactory;

public SqlSessionFactoryBuildItem(RuntimeValue<SqlSessionFactory> sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}

public RuntimeValue<SqlSessionFactory> getSqlSessionFactory() {
return sqlSessionFactory;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.quarkus.mybatis.deployment;

import org.apache.ibatis.session.SqlSessionManager;

import io.quarkus.builder.item.SimpleBuildItem;
import io.quarkus.runtime.RuntimeValue;

/**
* Hold the RuntimeValue of {@link SqlSessionManager}
*/
public final class SqlSessionManagerBuildItem extends SimpleBuildItem {
private final RuntimeValue<SqlSessionManager> sqlSessionManager;

public SqlSessionManagerBuildItem(RuntimeValue<SqlSessionManager> sqlSessionManager) {
this.sqlSessionManager = sqlSessionManager;
}

public RuntimeValue<SqlSessionManager> getSqlSessionManager() {
return sqlSessionManager;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.quarkus.mybatis.test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import javax.inject.Inject;

import org.apache.ibatis.session.SqlSessionFactory;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;

public class MyBatisTest {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest().withConfigurationResource("application.properties")
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(UserMapper.class, User.class));

@Inject
UserMapper userMapper;

@Inject
SqlSessionFactory sqlSessionFactory;

@Test
public void test() throws Exception {
assertTrue(sqlSessionFactory.getConfiguration().getMapperRegistry().hasMapper(UserMapper.class));
User user = userMapper.getUser(1);
assertEquals(user.getId(), 1);
assertEquals(user.getName(), "Test User1");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.quarkus.mybatis.test;

import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.h2.H2DatabaseTestResource;

@QuarkusTestResource(H2DatabaseTestResource.class)
public class TestResources {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.quarkus.mybatis.test;

public class User {
private Integer id;
private String name;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.quarkus.mybatis.test;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface UserMapper {

@Select("select * from users where id = #{id}")
User getUser(Integer id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
quarkus.datasource.db-kind=h2
quarkus.datasource.username=username-default

quarkus.datasource.jdbc.url=jdbc:h2:tcp://localhost/mem:default
quarkus.mybatis.initialSql=insert.sql
Loading

0 comments on commit e1613c6

Please sign in to comment.