diff --git a/jakarta-jpa/pom.xml b/jakarta-jpa/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..24cd5c525773d0856b57c5d22d219913f3e7fc34 --- /dev/null +++ b/jakarta-jpa/pom.xml @@ -0,0 +1,63 @@ + + + + + + mybatis-parent + io.mybatis + ${revision} + + 4.0.0 + + mybatis-jakarta-jpa + + + + io.mybatis + mybatis-provider + + + + jakarta.persistence + jakarta.persistence-api + 3.1.0 + provided + + + + + org.hsqldb + hsqldb + + + ch.qos.logback + logback-classic + + + junit + junit + + + javax.persistence + javax.persistence-api + 2.2 + compile + + + diff --git a/jakarta-jpa/src/main/java/io/mybatis/provider/jpa/JakartaJpaEntityClassFinder.java b/jakarta-jpa/src/main/java/io/mybatis/provider/jpa/JakartaJpaEntityClassFinder.java new file mode 100644 index 0000000000000000000000000000000000000000..459721b1be92a2cbceab62be992feffd0880590e --- /dev/null +++ b/jakarta-jpa/src/main/java/io/mybatis/provider/jpa/JakartaJpaEntityClassFinder.java @@ -0,0 +1,39 @@ +/* + * Copyright 2020-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.mybatis.provider.jpa; + +import io.mybatis.provider.defaults.GenericEntityClassFinder; +import jakarta.persistence.Table; + +/** + * 支持识别带有 @javax.persistence.Table 的实体类或者不带任何注解的POJO + * + * @author liuzh + */ +public class JakartaJpaEntityClassFinder extends GenericEntityClassFinder { + + @Override + public boolean isEntityClass(Class clazz) { + //带注解或不是简单类型和枚举的都算实体 + return clazz.isAnnotationPresent(Table.class) || (!clazz.isPrimitive() && !SimpleTypeUtil.isSimpleType(clazz) && !clazz.isEnum()); + } + + @Override + public int getOrder() { + return super.getOrder() + 100; + } +} diff --git a/jakarta-jpa/src/main/java/io/mybatis/provider/jpa/JakartaJpaEntityColumnFactory.java b/jakarta-jpa/src/main/java/io/mybatis/provider/jpa/JakartaJpaEntityColumnFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..affc75c212aa6e79be5403a9dc1ba98f3d2c43ad --- /dev/null +++ b/jakarta-jpa/src/main/java/io/mybatis/provider/jpa/JakartaJpaEntityColumnFactory.java @@ -0,0 +1,83 @@ +/* + * Copyright 2020-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.mybatis.provider.jpa; + +import io.mybatis.provider.*; +import jakarta.persistence.Column; +import jakarta.persistence.Id; +import jakarta.persistence.OrderBy; +import jakarta.persistence.Transient; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +/** + * 通过 SPI 工厂扩展 EntityColumn 和 EntityTable + * + * @author liuzh + */ +public class JakartaJpaEntityColumnFactory implements EntityColumnFactory { + + @Override + public Optional> createEntityColumn(EntityTable entityTable, EntityField field, Chain chain) { + Optional> optionalEntityColumns = chain.createEntityColumn(entityTable, field); + if (field.isAnnotationPresent(Transient.class)) { + return Optional.empty(); + } else if (!optionalEntityColumns.isPresent()) { + //没有 @Transient 注解的字段都认为是表字段,不自动排除字段,字段名默认驼峰转下划线 + optionalEntityColumns = Optional.of(Arrays.asList(EntityColumn.of(field).column(Style.getDefaultStyle().columnName(entityTable, field)))); + } + if (optionalEntityColumns.isPresent()) { + List entityColumns = optionalEntityColumns.get(); + for (EntityColumn entityColumn : entityColumns) { + EntityField entityField = entityColumn.field(); + //主键 + if (!entityColumn.id()) { + entityColumn.id(entityField.isAnnotationPresent(Id.class)); + } + //列名 + if (field.isAnnotationPresent(Column.class)) { + Column column = field.getAnnotation(Column.class); + String columnName = column.name(); + if (!columnName.isEmpty()) { + entityColumn.column(columnName); + } + entityColumn.insertable(column.insertable()).updatable(column.updatable()); + if (column.scale() != 0) { + entityColumn.numericScale(String.valueOf(column.scale())); + } + } + //只能默认空 ASC,或者写 ASC 或 DESC,不能写多个列 + if (field.isAnnotationPresent(OrderBy.class)) { + OrderBy orderBy = field.getAnnotation(OrderBy.class); + if (orderBy.value().isEmpty()) { + entityColumn.orderBy("ASC"); + } else { + entityColumn.orderBy(orderBy.value()); + } + } + } + } + return optionalEntityColumns; + } + + @Override + public int getOrder() { + return EntityColumnFactory.super.getOrder() + 100; + } + +} diff --git a/jakarta-jpa/src/main/java/io/mybatis/provider/jpa/JakartaJpaEntityTableFactory.java b/jakarta-jpa/src/main/java/io/mybatis/provider/jpa/JakartaJpaEntityTableFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..baf384afee0f78f1ee8c2d43d7d27f508200c774 --- /dev/null +++ b/jakarta-jpa/src/main/java/io/mybatis/provider/jpa/JakartaJpaEntityTableFactory.java @@ -0,0 +1,56 @@ +/* + * Copyright 2020-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.mybatis.provider.jpa; + +import io.mybatis.provider.EntityTable; +import io.mybatis.provider.EntityTableFactory; +import io.mybatis.provider.Style; +import io.mybatis.provider.util.Utils; + +import jakarta.persistence.Table; + +/** + * 通过 SPI 工厂扩展 EntityColumn 和 EntityTable + * + * @author liuzh + */ +public class JakartaJpaEntityTableFactory implements EntityTableFactory { + + @Override + public EntityTable createEntityTable(Class entityClass, Chain chain) { + EntityTable entityTable = chain.createEntityTable(entityClass); + if (entityTable == null) { + entityTable = EntityTable.of(entityClass); + } + if (entityClass.isAnnotationPresent(Table.class)) { + Table table = entityClass.getAnnotation(Table.class); + if (!table.name().isEmpty()) { + entityTable.table(table.name()); + } + } else if (Utils.isEmpty(entityTable.table())) { + //没有设置表名时,默认类名转下划线 + entityTable.table(Style.getDefaultStyle().tableName(entityClass)); + } + return entityTable; + } + + @Override + public int getOrder() { + return EntityTableFactory.super.getOrder() + 100; + } + +} diff --git a/jakarta-jpa/src/main/java/io/mybatis/provider/jpa/SimpleTypeUtil.java b/jakarta-jpa/src/main/java/io/mybatis/provider/jpa/SimpleTypeUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..8722935d3be1b6d981d451b46a4618bf37cd9ec9 --- /dev/null +++ b/jakarta-jpa/src/main/java/io/mybatis/provider/jpa/SimpleTypeUtil.java @@ -0,0 +1,138 @@ +/* + * Copyright 2020-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.mybatis.provider.jpa; + +import io.mybatis.provider.util.Utils; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Timestamp; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +/** + * 参考 org.apache.ibatis.type.SimpleTypeRegistry + * + * @author Clinton Begin + * @author liuzh + */ +public class SimpleTypeUtil { + public static final String[] JAVA8_DATE_TIME = { + "java.time.Instant", + "java.time.LocalDateTime", + "java.time.LocalDate", + "java.time.LocalTime", + "java.time.OffsetDateTime", + "java.time.OffsetTime", + "java.time.ZonedDateTime", + "java.time.Year", + "java.time.Month", + "java.time.YearMonth" + }; + private static final Set> SIMPLE_TYPE_SET = new HashSet>(); + + /** + * 特别注意:由于基本类型有默认值,因此在实体类中不建议使用基本类型作为数据库字段类型 + */ + static { + SIMPLE_TYPE_SET.add(byte[].class); + SIMPLE_TYPE_SET.add(String.class); + SIMPLE_TYPE_SET.add(Byte.class); + SIMPLE_TYPE_SET.add(Short.class); + SIMPLE_TYPE_SET.add(Character.class); + SIMPLE_TYPE_SET.add(Integer.class); + SIMPLE_TYPE_SET.add(Long.class); + SIMPLE_TYPE_SET.add(Float.class); + SIMPLE_TYPE_SET.add(Double.class); + SIMPLE_TYPE_SET.add(Boolean.class); + SIMPLE_TYPE_SET.add(Date.class); + SIMPLE_TYPE_SET.add(Timestamp.class); + SIMPLE_TYPE_SET.add(Class.class); + SIMPLE_TYPE_SET.add(BigInteger.class); + SIMPLE_TYPE_SET.add(BigDecimal.class); + //反射方式设置 java8 中的日期类型 + for (String time : JAVA8_DATE_TIME) { + registerSimpleTypeSilence(time); + } + } + + /** + * 注册新的类型 + * + * @param clazz + */ + public static void registerSimpleType(Class clazz) { + SIMPLE_TYPE_SET.add(clazz); + } + + /** + * 注册 8 种基本类型 + */ + public static void registerPrimitiveTypes() { + registerSimpleType(boolean.class); + registerSimpleType(byte.class); + registerSimpleType(short.class); + registerSimpleType(int.class); + registerSimpleType(long.class); + registerSimpleType(char.class); + registerSimpleType(float.class); + registerSimpleType(double.class); + } + + /** + * 注册新的类型 + * + * @param classes + */ + public static void registerSimpleType(String classes) { + if (Utils.isNotEmpty(classes)) { + String[] cls = classes.split(","); + for (String c : cls) { + try { + SIMPLE_TYPE_SET.add(Class.forName(c)); + } catch (ClassNotFoundException e) { + throw new RuntimeException("注册类型出错:" + c, e); + } + } + } + } + + /** + * 注册新的类型,不存在时不抛出异常 + * + * @param clazz + */ + private static void registerSimpleTypeSilence(String clazz) { + try { + SIMPLE_TYPE_SET.add(Class.forName(clazz)); + } catch (ClassNotFoundException e) { + //ignore + } + } + + /** + * Tells us if the class passed in is a known common type + * + * @param clazz The class to check + * @return True if the class is known + */ + public static boolean isSimpleType(Class clazz) { + return SIMPLE_TYPE_SET.contains(clazz); + } + +} diff --git a/jakarta-jpa/src/main/resources/META-INF/services/io.mybatis.provider.EntityClassFinder b/jakarta-jpa/src/main/resources/META-INF/services/io.mybatis.provider.EntityClassFinder new file mode 100644 index 0000000000000000000000000000000000000000..edbba54a9c2d378dac8dfe33b732e3d643991482 --- /dev/null +++ b/jakarta-jpa/src/main/resources/META-INF/services/io.mybatis.provider.EntityClassFinder @@ -0,0 +1,17 @@ +# +# Copyright 2020-2022 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +io.mybatis.provider.jpa.JakartaJpaEntityClassFinder diff --git a/jakarta-jpa/src/main/resources/META-INF/services/io.mybatis.provider.EntityColumnFactory b/jakarta-jpa/src/main/resources/META-INF/services/io.mybatis.provider.EntityColumnFactory new file mode 100644 index 0000000000000000000000000000000000000000..0978ba7fa30ab58e2980f29d941f641deadaa843 --- /dev/null +++ b/jakarta-jpa/src/main/resources/META-INF/services/io.mybatis.provider.EntityColumnFactory @@ -0,0 +1,17 @@ +# +# Copyright 2020-2022 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +io.mybatis.provider.jpa.JakartaJpaEntityColumnFactory diff --git a/jakarta-jpa/src/main/resources/META-INF/services/io.mybatis.provider.EntityTableFactory b/jakarta-jpa/src/main/resources/META-INF/services/io.mybatis.provider.EntityTableFactory new file mode 100644 index 0000000000000000000000000000000000000000..3d556561f1b07397d3b707ae329a747da813ea87 --- /dev/null +++ b/jakarta-jpa/src/main/resources/META-INF/services/io.mybatis.provider.EntityTableFactory @@ -0,0 +1,17 @@ +# +# Copyright 2020-2022 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +io.mybatis.provider.jpa.JakartaJpaEntityTableFactory diff --git a/jakarta-jpa/src/test/java/io/mybatis/provider/BaseTest.java b/jakarta-jpa/src/test/java/io/mybatis/provider/BaseTest.java new file mode 100644 index 0000000000000000000000000000000000000000..5abd0642829b8feb1fa8636de7d2eade9687eff6 --- /dev/null +++ b/jakarta-jpa/src/test/java/io/mybatis/provider/BaseTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2020-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.mybatis.provider; + +import org.apache.ibatis.io.Resources; +import org.apache.ibatis.jdbc.ScriptRunner; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; +import org.junit.BeforeClass; + +import java.io.IOException; +import java.io.Reader; +import java.sql.Connection; + +public class BaseTest { + private static SqlSessionFactory sqlSessionFactory; + + @BeforeClass + public static void init() { + try { + Reader reader = Resources.getResourceAsReader("mybatis-config.xml"); + sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); + reader.close(); + + //创建数据库 + try (SqlSession session = sqlSessionFactory.openSession()) { + Connection conn = session.getConnection(); + reader = Resources.getResourceAsReader("testdb.sql"); + ScriptRunner runner = new ScriptRunner(conn); + runner.setLogWriter(null); + runner.runScript(reader); + reader.close(); + } + } catch (IOException ignore) { + } + } + + public SqlSession getSqlSession() { + return sqlSessionFactory.openSession(); + } + +} diff --git a/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/BaseProvider.java b/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/BaseProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..9bc8db40428230baaa4af8de54b82a8b06761503 --- /dev/null +++ b/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/BaseProvider.java @@ -0,0 +1,53 @@ +/* + * Copyright 2020-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.mybatis.provider.jpa; + +import io.mybatis.provider.EntityColumn; +import io.mybatis.provider.SqlScript; +import org.apache.ibatis.builder.annotation.ProviderContext; + +import java.util.stream.Collectors; + +import static io.mybatis.provider.SqlScript.LF; + +public class BaseProvider { + + public static String getById(ProviderContext providerContext) { + return SqlScript.caching(providerContext, entity -> + "SELECT " + entity.baseColumnAsPropertyList() + " FROM " + entity.tableName() + + " WHERE " + entity.idColumns().stream().map(EntityColumn::columnEqualsProperty).collect(Collectors.joining(" AND "))); + } + + public static String deleteById(ProviderContext providerContext) { + return SqlScript.caching(providerContext, entity -> + "DELETE FROM " + entity.tableName() + + " WHERE " + entity.idColumns().stream().map(EntityColumn::columnEqualsProperty).collect(Collectors.joining(" AND "))); + } + + public static String insertSelective(ProviderContext providerContext) { + return SqlScript.caching(providerContext, (entity, util) -> + "INSERT INTO " + entity.tableName() + + util.trimSuffixOverrides("(", ")", ",", () -> + entity.insertColumns().stream().map(column -> + util.ifTest(column.notNullTest(), () -> column.column() + ",") + ).collect(Collectors.joining(LF))) + + util.trimSuffixOverrides(" VALUES (", ")", ",", () -> + entity.insertColumns().stream().map(column -> + util.ifTest(column.notNullTest(), () -> column.variables() + ",") + ).collect(Collectors.joining(LF)))); + } +} diff --git a/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/User.java b/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/User.java new file mode 100644 index 0000000000000000000000000000000000000000..d146e9366de43064965275f3ddac7d7072bc3385 --- /dev/null +++ b/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/User.java @@ -0,0 +1,59 @@ +/* + * Copyright 2020-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.mybatis.provider.jpa; + +import io.mybatis.provider.Entity; + +import jakarta.persistence.Column; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Table(name = "user") +public class User { + @Id + @Column + private Long id; + @Column(name = "name") + private String username; + @Column + @Entity.Column(selectable = false) + private String sex; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getSex() { + return sex; + } + + public void setSex(String sex) { + this.sex = sex; + } +} diff --git a/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserAuto.java b/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserAuto.java new file mode 100644 index 0000000000000000000000000000000000000000..f3403879edb8c1a8542cffddf2a823454e8f36c2 --- /dev/null +++ b/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserAuto.java @@ -0,0 +1,50 @@ +/* + * Copyright 2020-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.mybatis.provider.jpa; + +import jakarta.persistence.Id; + +public class UserAuto { + @Id + private int id; + private String userName; + private String address; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } +} diff --git a/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserAutoMapper.java b/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserAutoMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..817c0e0356a4c643e9cb7719fc7c08f700574a9c --- /dev/null +++ b/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserAutoMapper.java @@ -0,0 +1,29 @@ +/* + * Copyright 2020-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.mybatis.provider.jpa; + +import io.mybatis.provider.Caching; +import org.apache.ibatis.annotations.Lang; +import org.apache.ibatis.annotations.SelectProvider; + +public interface UserAutoMapper { + + @Lang(Caching.class) + @SelectProvider(type = BaseProvider.class, method = "getById") + UserAuto getById(Long id); + +} diff --git a/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserAutoMapperTest.java b/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserAutoMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..01aff1e85394680d864bcb9fb0e82f4ecda604de --- /dev/null +++ b/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserAutoMapperTest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.mybatis.provider.jpa; + +import io.mybatis.provider.BaseTest; +import org.apache.ibatis.session.SqlSession; +import org.junit.Assert; +import org.junit.Test; + +public class UserAutoMapperTest extends BaseTest { + + @Test + public void testSelectById() { + try (SqlSession sqlSession = getSqlSession()) { + UserAutoMapper userMapper = sqlSession.getMapper(UserAutoMapper.class); + UserAuto user = userMapper.getById(1L); + Assert.assertNotNull(user); + Assert.assertEquals("sjz", user.getUserName()); + Assert.assertNotNull(user.getAddress()); + } + } + +} diff --git a/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserMapper.java b/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..e14ab15c2c9350688555b2c636798467e5654da4 --- /dev/null +++ b/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserMapper.java @@ -0,0 +1,29 @@ +/* + * Copyright 2020-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.mybatis.provider.jpa; + +import io.mybatis.provider.Caching; +import org.apache.ibatis.annotations.Lang; +import org.apache.ibatis.annotations.SelectProvider; + +public interface UserMapper { + + @Lang(Caching.class) + @SelectProvider(type = BaseProvider.class, method = "getById") + User getById(Long id); + +} diff --git a/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserMapperTest.java b/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..63c8fb47384a467bd28aa39e0f50d563259fd188 --- /dev/null +++ b/jakarta-jpa/src/test/java/io/mybatis/provider/jpa/UserMapperTest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.mybatis.provider.jpa; + +import io.mybatis.provider.BaseTest; +import org.apache.ibatis.session.SqlSession; +import org.junit.Assert; +import org.junit.Test; + +public class UserMapperTest extends BaseTest { + + @Test + public void testSelectById() { + try (SqlSession sqlSession = getSqlSession()) { + UserMapper userMapper = sqlSession.getMapper(UserMapper.class); + User user = userMapper.getById(1L); + Assert.assertNotNull(user); + Assert.assertEquals("张无忌", user.getUsername()); + Assert.assertNull(user.getSex()); + } + } + +} diff --git a/jakarta-jpa/src/test/resources/logback.xml b/jakarta-jpa/src/test/resources/logback.xml new file mode 100644 index 0000000000000000000000000000000000000000..e47b06cb1404e609b1877d8fa92037789ebf7efd --- /dev/null +++ b/jakarta-jpa/src/test/resources/logback.xml @@ -0,0 +1,26 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + diff --git a/jakarta-jpa/src/test/resources/mybatis-config.xml b/jakarta-jpa/src/test/resources/mybatis-config.xml new file mode 100644 index 0000000000000000000000000000000000000000..4172dde6baadd8debf04bb4fbdb2953fcff8da7c --- /dev/null +++ b/jakarta-jpa/src/test/resources/mybatis-config.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jakarta-jpa/src/test/resources/testdb.sql b/jakarta-jpa/src/test/resources/testdb.sql new file mode 100644 index 0000000000000000000000000000000000000000..f4efad11fcc4d9bd72336c76823b5b9605dffba6 --- /dev/null +++ b/jakarta-jpa/src/test/resources/testdb.sql @@ -0,0 +1,29 @@ +drop table user if exists; +drop table user_auto if exists; + +create table user +( + id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY, + name VARCHAR(32) DEFAULT 'DEFAULT', + sex VARCHAR(2) +); + + +insert into user(id, name, sex) +values (1, '张无忌', '男'), + (2, '赵敏', '女'), + (3, '周芷若', '女'), + (4, '小昭', '女'), + (5, '殷离', '女'); + +-- 自动映射 +create table user_auto +( + id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY, + user_name VARCHAR(32) DEFAULT 'DEFAULT', + address VARCHAR(64) +); +insert into user_auto(id, user_name, address) +values (1, 'sjz', '河北省/石家庄市'), + (2, 'hd', '河北省/邯郸市'), + (3, 'xt', '河北省/邢台市');