代码拉取完成,页面将自动刷新
1.下载代码
2.本地 maven install
3.添加依赖到任意的一个 springboot 项目中
<groupId>com.orm</groupId>
<artifactId>MyBatisDemo</artifactId>
<version>1.1-SNAPSHOT</version>
4.在你的项目中启动类上加注解 @EnableMyBatis
5.在写 mapper 的时候继承我指定的类并泛型为实体类
// 你的实体类应该是这样的
@TableName("t_user")
@Data
public class User {
@FieldName("id")
private String id;
@FieldName("name")
private String username;
}
// 比如这样
public interface UserMapper extends MyMapper<UserEntity> {
default List<UserEntity> selectByName(String userName) {
MyLambdaQueryWrapper<UserEntity> queryWrapper = new MyLambdaQueryWrapper<>();
queryWrapper.eq(UserEntity::getName, userName);
return selectList(queryWrapper);
}
}
太棒了!现在就可以像操作 mybatisPlus 一样操作数据库了
首先我们应该定义一个注解,当用户把注解放在启动类上的时候。扫描启动类下面的所有类看看那个是继承了MyMapper
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MyBatisRegistrar.class)
public @interface EnableMyBatis {
}
public class MyBatisRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
}
}
核心在这里 @Import(MyBatisRegistrar.class) 由于你的注解上标注了这个。所以当用户使用你的 jar 包并在启动类上加上注解之后,spring 会找到这个类。并自动执行 registerBeanDefinitions 方法。这是 spring 提供的一种加载机制。那么好我们只需要在这个方法里面扫描我们想要的类就可以了
// 扫描启动类下面的类,找到实现了 MyMapper 的接口!
String basePackage = ClassUtils.getPackageName(importingClassMetadata.getClassName());
Set<Class<?>> classes = findMyMappers(basePackage);
使用 JDK 的动态代理为接口生成代理对象。
@AllArgsConstructor
public class MyMapperProxy implements InvocationHandler {
// 目标接口 userMapper.class
private Class mapperInterface;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 代理其他方法
DefaultMyMapperImpl defaultMyMapper = new DefaultMyMapperImpl(mapperInterface);
defaultMyMapper.setInterfaceClass(mapperInterface);
return method.invoke(defaultMyMapper, args);
}
@SuppressWarnings("unchecked")
public static <T> T createProxy(Class<T> mapperInterface) {
return (T) Proxy.newProxyInstance(
mapperInterface.getClassLoader(),
new Class[]{mapperInterface},
new MyMapperProxy(mapperInterface)
);
}
}
通过该工具类,为扫描到的接口生成代理实例对象!
将生成的代理对象注入我们需要构造一个 beanDefinition,将其编织到 spring 的生命周期当中
public class MyBatisRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 将获取到的 interface 生成代理,注入 spring 当中
for (Class<?> clazz : classes) {
System.out.println("clazz = " + clazz);
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(clazz);
beanDefinition.setInstanceSupplier(() -> MyMapperProxy.createProxy(clazz));
String beanName = clazz.getSimpleName();
beanName = Character.toLowerCase(beanName.charAt(0)) + beanName.substring(1);
System.out.println("注入beanName = " + beanName);
registry.registerBeanDefinition(beanName, beanDefinition);
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。