相信使用过mybatis-plus人都有这样的经历,mybatis-plus确实精简了数据库操作,但是还是需要为每个实体创建其对一个的mapper接口和实现类或者 IService接口和实现类,无形中让开发者多少感觉不太方面,如果能将省去这些繁琐的过程,势必会让我们使用mybaitis-plus更爽。请看以下代码:
initMybatisTableMapperAndDao方法,系统启动时执行:
void initMybatisTableMapperAndDao() {
String BASE_PATH = getClass().getPackage().getName().replace(".config", "");
// 扫描数据库实体,根据实体创建对应 mapper、service
Set<Class<?>> entityClassSet = ClassUtil.scanPackage(BASE_PATH + ".entity");
if (entityClassSet.isEmpty()) {
return;
}
// 创建实体其他数据库用户的实体类
Set<Class<?>> thirdDbEntityClassSet = new HashSet<>();
for (Class<?> entityClass : entityClassSet) {
for (String dbUser : thirdDbUsers) {
List<AnnotationDescription> annotations = new ArrayList<>();
String tableNameValue = ObjectUtil.isNull(entityClass.getAnnotation(TableName.class)) ? "" : entityClass.getAnnotation(TableName.class).value();
String value = dbUser.toUpperCase() + "." + (StringUtils.isEmpty(tableNameValue) ? entityClass.getSimpleName() : tableNameValue);
annotations.add(AnnotationDescription.Builder.ofType(TableName.class).define("value", value).build());
Class<?> thirdDbUserEntity = new ByteBuddy()
.subclass(TypeDescription.Generic.Builder.rawType(entityClass).build())
.name(dbUser.toUpperCase() + "_" + entityClass.getSimpleName())
.annotateType(annotations)
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
.getLoaded();
thirdDbEntityClassSet.add(thirdDbUserEntity);
}
}
if (CollectionUtil.isNotEmpty(entityClassSet)) {
thirdDbEntityClassSet.addAll(entityClassSet);
}
for (Class<?> entityClass : thirdDbEntityClassSet) {
// 只创建带有 TableName 注解的实体
TableName tableName = entityClass.getAnnotation(TableName.class);
if (tableName == null) {
continue;
}
String mapperClassName = BASE_PATH + ".mapper" + "." + entityClass.getSimpleName() + "Mapper";
String serviceImplClassName = BASE_PATH + ".service" + "." + entityClass.getSimpleName() + "ServiceImpl";
String serviceClassName = BASE_PATH + ".service" + "." + entityClass.getSimpleName() + "Service";
/* 创建 mapper */
Class<?> mapperClass = new ByteBuddy()
.makeInterface(TypeDescription.Generic.Builder.parameterizedType(BaseMapper.class, entityClass).build())
.name(mapperClassName)
.annotateType(AnnotationDescription.Builder.ofType(Mapper.class).build())
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
.getLoaded();
MapperFactoryBean<?> factoryBean = new MapperFactoryBean<>(mapperClass);
factoryBean.setSqlSessionFactory(sqlSessionFactory);
sqlSessionFactory.getConfiguration().addMapper(mapperClass);
try {
SpringUtil.registerBean(getBeanName(mapperClassName), factoryBean.getObject());
log.info("register mapper Bean -> name:{}", getBeanName(mapperClassName));
} catch (Exception e) {
e.printStackTrace();
}
/* 创建 service */
Class<?> serviceClass = new ByteBuddy()
.makeInterface(TypeDescription.Generic.Builder.parameterizedType(IService.class, entityClass).build())
.name(serviceClassName)
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
.getLoaded();
List<AnnotationDescription> annotations = new ArrayList<>();
annotations.add(AnnotationDescription.Builder.ofType(Service.class).build());
Class<?> serviceImplClass = new ByteBuddy()
.subclass(TypeDescription.Generic.Builder.parameterizedType(ServiceImpl.class, mapperClass, entityClass).build())
.implement(serviceClass)
.name(serviceImplClassName)
.annotateType(annotations)
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
.getLoaded();
try {
SpringUtil.registerBean(getBeanName(serviceImplClassName), serviceImplClass.newInstance());
log.info("register Dao Bean -> name:{}", getBeanName(serviceImplClassName));
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
initRemoteApi();
}
创建DbHelper工具类:
public class DbHelper {
public static String DB_USER_ROOT="root";
public static <T> IService getTableDao(final Class<T> t) {
return SpringUtil.getBean(getBeanName(t) + "ServiceImpl");
}
/**
*
* @param t
* @param dbUser
* @return
* @param <T>
*/
public static <T> IService getTableDao(final Class<T> t,String dbUser) {
if(StrUtil.isNotEmpty(dbUser)){
String name=dbUser.substring(0, 1).toLowerCase() + dbUser.substring(1).toUpperCase();
return SpringUtil.getBean(name+"_"+ t.getSimpleName() + "ServiceImpl");
}
return SpringUtil.getBean(getBeanName(t) + "ServiceImpl");
}
public static <T> BaseMapper getTableMapper(final Class<T> t) {
return SpringUtil.getBean(getBeanName(t) + "Mapper");
}
public static <T> BaseMapper getTableMapper(final Class<T> t,String dbUser) {
if(StrUtil.isNotEmpty(dbUser)){
String name=dbUser.substring(0, 1).toLowerCase() + dbUser.substring(1);
return SpringUtil.getBean(name+"_"+ t.getSimpleName() + "Mapper");
}
return SpringUtil.getBean(getBeanName(t) + "Mapper");
}
private static String getBeanName(final Class t) {
if(!AnnotationUtil.hasAnnotation(t,TableName.class)){
throw ExceptionUtil.wrapRuntime(StrUtil.format("传入的{}不是entity类",t.getName()));
}
return t.getSimpleName().substring(0, 1).toLowerCase() + t.getSimpleName().substring(1);
}
public static <T>QueryWrapper<T> newQueryWrapper(Class <T> cls){
return new QueryWrapper<T>();
}
public static <T>UpdateWrapper<T> newUpdateWrapper(){
return new UpdateWrapper<T>();
}
public static <T>UpdateWrapper<T> newUpdateWrapper(Class <T> cls){
return new UpdateWrapper<T>();
}
public static <T>LambdaQueryWrapper<T> newLambdaQueryWrapper(Class <T> cls){
return new LambdaQueryWrapper<T>();
}
public static <T>LambdaUpdateWrapper<T> newLambdaUpdateWrapper(Class <T> cls){
return new LambdaUpdateWrapper<T>();
}
}
使用示例:
List<Student> studentList= DbHelper.getTableDao(Student.class).list();
Student student= (Student) DbHelper.getTableDao(Student.class).getById(1);
Student updateStudent =new Student();
DbHelper.getTableDao(Student.class).updateById(updateStudent );
是不是很简单,只要往工具方法里传入实体类型,就就能直接使用mybatis-plus提供的基本功能,欢迎大家来实践。
git地址私聊我