diff --git a/README.md b/README.md index 519cc11..de14255 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ # mini-mybatis 该项目是mybatis的mini版本,包含动态SQL,参数绑定,结果集处理,以及插件支持等核心功能,写mini-mybatis的初衷是想参照现有mybatis的功能,自己从0到1实现一个简化版,同时也希望帮助其他人熟悉mybatis的设计思想以及源码理解,为降低代码复杂度,该项目主要以实现核心功能为主,不会太注重性能以及线程安全等问题。该项目采用一步一步(step-by-step)的方式完善功能,每一个小功能模块使用一个独立的分支,分支前缀带有递增序号,序号由小到大表示功能的完善程度。 # 功能模块 +[1.注册Mapper接口](https://github.com/FuriousPws002/mini-mybatis/wiki/1.%E6%B3%A8%E5%86%8CMapper%E6%8E%A5%E5%8F%A3 "Markdown") \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100755 index 0000000..ba6aeb8 --- /dev/null +++ b/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + com.furious + mini-mybatis + 0.0.1-SNAPSHOT + + mini-mybatis + mini-mybatis + + 8 + + + + + junit + junit + 4.13.2 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + + + diff --git a/src/main/java/org/apache/ibatis/binding/BindingException.java b/src/main/java/org/apache/ibatis/binding/BindingException.java new file mode 100644 index 0000000..e545334 --- /dev/null +++ b/src/main/java/org/apache/ibatis/binding/BindingException.java @@ -0,0 +1,27 @@ +package org.apache.ibatis.binding; + +/** + * @author furious 2024/4/3 + */ +public class BindingException extends RuntimeException { + + public BindingException() { + super(); + } + + public BindingException(String message) { + super(message); + } + + public BindingException(String message, Throwable cause) { + super(message, cause); + } + + public BindingException(Throwable cause) { + super(cause); + } + + protected BindingException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/org/apache/ibatis/binding/MapperProxy.java b/src/main/java/org/apache/ibatis/binding/MapperProxy.java new file mode 100644 index 0000000..9c28600 --- /dev/null +++ b/src/main/java/org/apache/ibatis/binding/MapperProxy.java @@ -0,0 +1,25 @@ +package org.apache.ibatis.binding; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +import org.apache.ibatis.session.SqlSession; + +/** + * @author furious 2024/4/3 + */ +public class MapperProxy implements InvocationHandler { + + private final SqlSession sqlSession; + private final Class mapperInterface; + + public MapperProxy(SqlSession sqlSession, Class mapperInterface) { + this.sqlSession = sqlSession; + this.mapperInterface = mapperInterface; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return null; + } +} diff --git a/src/main/java/org/apache/ibatis/binding/MapperProxyFactory.java b/src/main/java/org/apache/ibatis/binding/MapperProxyFactory.java new file mode 100644 index 0000000..d02d411 --- /dev/null +++ b/src/main/java/org/apache/ibatis/binding/MapperProxyFactory.java @@ -0,0 +1,23 @@ +package org.apache.ibatis.binding; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; + +import org.apache.ibatis.session.SqlSession; + +/** + * @author furious 2024/4/3 + */ +public class MapperProxyFactory { + + private final Class mapperInterface; + + public MapperProxyFactory(Class mapperInterface) { + this.mapperInterface = mapperInterface; + } + + public T newInstance(SqlSession sqlSession) { + InvocationHandler handler = new MapperProxy(sqlSession, mapperInterface); + return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, handler); + } +} diff --git a/src/main/java/org/apache/ibatis/binding/MapperRegistry.java b/src/main/java/org/apache/ibatis/binding/MapperRegistry.java new file mode 100644 index 0000000..87bed3a --- /dev/null +++ b/src/main/java/org/apache/ibatis/binding/MapperRegistry.java @@ -0,0 +1,41 @@ +package org.apache.ibatis.binding; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.SqlSession; + +/** + * @author furious 2024/4/3 + */ +public class MapperRegistry { + + private final Configuration config; + private final Map, MapperProxyFactory> knownMappers = new HashMap<>(); + + public MapperRegistry(Configuration config) { + this.config = config; + } + + public boolean hasMapper(Class type) { + return knownMappers.containsKey(type); + } + + public void addMapper(Class type) { + //不是接口不支持,直接返回 + if (!type.isInterface() || hasMapper(type)) { + return; + } + knownMappers.put(type, new MapperProxyFactory<>(type)); + } + + public T getMapper(Class type, SqlSession sqlSession) { + MapperProxyFactory mapperProxyFactory = knownMappers.get(type); + if (Objects.isNull(mapperProxyFactory)) { + throw new BindingException(type + " type is not exist"); + } + return mapperProxyFactory.newInstance(sqlSession); + } +} diff --git a/src/main/java/org/apache/ibatis/session/Configuration.java b/src/main/java/org/apache/ibatis/session/Configuration.java new file mode 100644 index 0000000..cfb4315 --- /dev/null +++ b/src/main/java/org/apache/ibatis/session/Configuration.java @@ -0,0 +1,24 @@ +package org.apache.ibatis.session; + +import org.apache.ibatis.binding.MapperRegistry; + +/** + * mybatis全局配置类 + * + * @author furious 2024/4/3 + */ +public class Configuration { + + private final MapperRegistry mapperRegistry = new MapperRegistry(this); + + public Configuration() { + } + + public void addMapper(Class type) { + mapperRegistry.addMapper(type); + } + + public T getMapper(Class type, SqlSession sqlSession) { + return mapperRegistry.getMapper(type, sqlSession); + } +} diff --git a/src/main/java/org/apache/ibatis/session/SqlSession.java b/src/main/java/org/apache/ibatis/session/SqlSession.java new file mode 100644 index 0000000..1ca9268 --- /dev/null +++ b/src/main/java/org/apache/ibatis/session/SqlSession.java @@ -0,0 +1,14 @@ +package org.apache.ibatis.session; + +import java.io.Closeable; + +/** + * @author furious 2024/3/29 + */ +public interface SqlSession extends Closeable { + + Configuration getConfiguration(); + + T getMapper(Class type); + +} diff --git a/src/main/java/org/apache/ibatis/session/defaults/DefaultSqlSession.java b/src/main/java/org/apache/ibatis/session/defaults/DefaultSqlSession.java new file mode 100644 index 0000000..2425483 --- /dev/null +++ b/src/main/java/org/apache/ibatis/session/defaults/DefaultSqlSession.java @@ -0,0 +1,33 @@ +package org.apache.ibatis.session.defaults; + +import java.io.IOException; + +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.SqlSession; + +/** + * @author furious 2024/4/3 + */ +public class DefaultSqlSession implements SqlSession { + + private final Configuration configuration; + + public DefaultSqlSession(Configuration configuration) { + this.configuration = configuration; + } + + @Override + public Configuration getConfiguration() { + return configuration; + } + + @Override + public T getMapper(Class type) { + return configuration.getMapper(type, this); + } + + @Override + public void close() throws IOException { + + } +} diff --git a/src/test/java/org/apache/ibatis/binding/MapperRegistryTest.java b/src/test/java/org/apache/ibatis/binding/MapperRegistryTest.java new file mode 100644 index 0000000..acf284b --- /dev/null +++ b/src/test/java/org/apache/ibatis/binding/MapperRegistryTest.java @@ -0,0 +1,23 @@ +package org.apache.ibatis.binding; + +import org.apache.ibatis.dao.UserMapper; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.defaults.DefaultSqlSession; +import org.junit.Assert; +import org.junit.Test; + +/** + * @author furious 2024/4/3 + */ +public class MapperRegistryTest { + + @Test + public void test() { + Configuration configuration = new Configuration(); + configuration.addMapper(UserMapper.class); + SqlSession sqlSession = new DefaultSqlSession(configuration); + UserMapper userMapper = sqlSession.getMapper(UserMapper.class); + Assert.assertNotNull(userMapper); + } +} diff --git a/src/test/java/org/apache/ibatis/dao/UserMapper.java b/src/test/java/org/apache/ibatis/dao/UserMapper.java new file mode 100644 index 0000000..bffabd1 --- /dev/null +++ b/src/test/java/org/apache/ibatis/dao/UserMapper.java @@ -0,0 +1,7 @@ +package org.apache.ibatis.dao; + +/** + * @author furious 2024/4/3 + */ +public interface UserMapper { +}