基于MyBatis注解扩展,实现无需配置就可拥有增删改
基于MyBatis注解扩展,实现无需配置就可拥有增删改
小兵成长记 发表于2年前
基于MyBatis注解扩展,实现无需配置就可拥有增删改
  • 发表于 2年前
  • 阅读 2410
  • 收藏 105
  • 点赞 1
  • 评论 17

移动开发云端新模式探索实践 >>>   

摘要: 使用Mybatis开发过程中,总是要相应的sql文件,即让人烦燥,也降低开发的效率,大部分人用代码生成工具解决,分享下基于Mybatis本身注解SqlProivder提供的一些增删改的封装

一、使用篇

      如果项目本身基于SpringMVC+Mybatis构建,不需添加任何配置Mapper类只需继承

BaseMapper,即拥有增删改方法操作,无需任何配置文件

  1.    
    package com.springmvc.mapper;
    
    import org.springframework.stereotype.Repository;
    
    import com.nmtx.mybatis.ext.mapper.BaseMapper;
    import com.springmvc.model.User;
    @Repository
    public interface UserMapper extends BaseMapper<User>{
    
    }
    

     

  2.  

    package com.springmvc.service.impl;
    
    import javax.annotation.Resource;
    
    import org.springframework.stereotype.Service;
    
    import com.springmvc.mapper.UserMapper;
    import com.springmvc.model.User;
    import com.springmvc.service.UserService;
    
    
    @Service
    public class UserServiceImpl implements UserService{
        
        @Resource
        private UserMapper userMapper;
        
        public int insertUser(User user) {
            return userMapper.insert(user);
        }
    
        @Override
        public int updateUser(User user) {
            return userMapper.update(user);
        }
    
        @Override
        public int deleteUser(User user) {
            return userMapper.delete(user);
        }
    
        @Override
        public User findUser(User user) {
            return userMapper.findFirst(user);
        }
    }

     

  3.  

    user.xml无需任何配置<?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
     PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.springmvc.mapper.UserMapper">
             
    </mapper>

     

二、扩展原理基于Mybatis中 @InsertProvider,@DeleteProvider,@UpdateProvider,@SelectProvider注解,具体实现代码如下

  1.  

    package com.nmtx.mybatis.ext.mapper;
    
    import org.apache.ibatis.annotations.DeleteProvider;
    import org.apache.ibatis.annotations.InsertProvider;
    import org.apache.ibatis.annotations.Options;
    import org.apache.ibatis.annotations.SelectProvider;
    import org.apache.ibatis.annotations.UpdateProvider;
    
    import com.nmtx.mybatis.ext.common.SqlProvider;
    
    public interface BaseMapper<T> {
    
        @InsertProvider(type = SqlProvider.class, method = "insert")
        @Options(useGeneratedKeys=true)
        public int insert(T bean);
    
        @DeleteProvider(type = SqlProvider.class, method = "delete")
        public int delete(T bean);
    
        @UpdateProvider(type = SqlProvider.class, method = "update")
        public int update(T bean);
    
        @SelectProvider(type = SqlProvider.class, method = "findFirst")
        public T findFirst(T bean);
    }


     

  2.  

    package com.nmtx.mybatis.ext.common;
    
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.apache.commons.lang3.ArrayUtils;
    import org.springframework.util.StringUtils;
    
    import com.nmtx.mybatis.ext.common.table.TableFormat;
    import com.nmtx.mybatis.ext.common.table.annotation.Column;
    import com.nmtx.mybatis.ext.common.table.annotation.Table;
    import com.nmtx.mybatis.ext.common.table.impl.HumpToUnderLineFormat;
    
    public class SqlProvider {
        
        
        private TableFormat tableFormat = new HumpToUnderLineFormat();
    
        public String insert(Object bean) {
            Class<?> beanClass = bean.getClass();
            String tableName = getTableName(beanClass);
            Field[] fields = getFields(beanClass);
            StringBuilder insertSql = new StringBuilder();
            List<String> insertParas = new ArrayList<String>();
            List<String> insertParaNames = new ArrayList<String>();
            insertSql.append("INSERT INTO ").append(tableName).append("(");
            try {
                for (int i = 0; i < fields.length; i++) {
                    Field field = fields[i];
                    Column column = field.getAnnotation(Column.class);
                    String columnName = "";
                    if (column != null) {
                        if (!column.required())
                            continue;
                        columnName = column.value();
                    }
                    if (StringUtils.isEmpty(columnName)) {
                        columnName = tableFormat.getColumnName(field.getName());
                    }
                    field.setAccessible(true);
                    Object object = field.get(bean);
                    if (object != null) {
                        insertParaNames.add(columnName);
                        insertParas.add("#{" + field.getName() + "}");
                    }
                }
            } catch (Exception e) {
                new RuntimeException("get insert sql is exceptoin:" + e);
            }
            for (int i = 0; i < insertParaNames.size(); i++) {
                insertSql.append(insertParaNames.get(i));
                if (i != insertParaNames.size() - 1)
                    insertSql.append(",");
            }
            insertSql.append(")").append(" VALUES(");
            for (int i = 0; i < insertParas.size(); i++) {
                insertSql.append(insertParas.get(i));
                if (i != insertParas.size() - 1)
                    insertSql.append(",");
            }
            insertSql.append(")");
            return insertSql.toString();
        }
    
        public String update(Object bean) {
            Class<?> beanClass = bean.getClass();
            String tableName = getTableName(beanClass);
            Field[] fields = getFields(beanClass);
            StringBuilder updateSql = new StringBuilder();
            updateSql.append(" update ").append(tableName).append(" set ");
            try {
                for (int i = 0; i < fields.length; i++) {
                    Field field = fields[i];
                    Column column = field.getAnnotation(Column.class);
                    String columnName = "";
                    if (column != null) {
                        if (!column.required())
                            continue;
                        columnName = column.value();
                    }
                    if (StringUtils.isEmpty(columnName)) {
                        columnName = tableFormat.getColumnName(field.getName());
                    }
                    field.setAccessible(true);
                    Object beanValue = field.get(bean);
                    if (beanValue != null) {
                        updateSql.append(columnName).append("=#{").append(field.getName()).append("}");
                        if (i != fields.length - 1) {
                            updateSql.append(",");
                        }
                    }
                }
            } catch (Exception e) {
                new RuntimeException("get update sql is exceptoin:" + e);
            }
            updateSql.append(" where ").append(tableFormat.getId()+" =#{id}");
            return updateSql.toString();
        }
    
        public String delete(Object bean) {
            Class<?> beanClass = bean.getClass();
            String tableName = getTableName(beanClass);
            Field[] fields = getFields(beanClass);
            StringBuilder deleteSql = new StringBuilder();
            deleteSql.append(" delete from ").append(tableName).append(" where  ");
            try {
                for (int i = 0; i < fields.length; i++) {
                    Field field = fields[i];
                    Column column = field.getAnnotation(Column.class);
                    String columnName = "";
                    if (column != null) {
                        if (!column.required())
                            continue;
                        columnName = column.value();
                    }
                    if (StringUtils.isEmpty(columnName)) {
                        columnName = tableFormat.getColumnName(field.getName());
                    }
                    field.setAccessible(true);
                    Object beanValue = field.get(bean);
                    if (beanValue != null) {
                        deleteSql.append(columnName).append("=#{").append(field.getName()).append("}");
                        if (i != fields.length - 1) {
                            deleteSql.append(" and ");
                        }
                    }
                }
            } catch (Exception e) {
                new RuntimeException("get delete sql is exceptoin:" + e);
            }
            return deleteSql.toString();
        }
    
        public String findFirst(Object bean) {
            Class<?> beanClass = bean.getClass();
            String tableName = getTableName(beanClass);
            Field[] fields = getFields(beanClass);
            StringBuilder selectSql = new StringBuilder();
            List<String> selectParaNames = new ArrayList<String>();
            List<String> selectParas = new ArrayList<String>();
            selectSql.append("select ");
            try {
                for (int i = 0; i < fields.length; i++) {
                    Field field = fields[i];
                    Column column = field.getAnnotation(Column.class);
                    String columnName = "";
                    if (column != null) {
                        if (!column.required())
                            continue;
                        columnName = column.value();
                    }
                    if (StringUtils.isEmpty(columnName)) {
                        columnName = tableFormat.getColumnName(field.getName());
                    }
                    field.setAccessible(true);
                    Object object = field.get(bean);
                    selectSql.append(field.getName());
                    if (object != null) {
                        selectParaNames.add(columnName);
                        selectParas.add("#{" + field.getName() + "}");
                    }
                    if (i != fields.length - 1)
                        selectSql.append(",");
                }
            } catch (Exception e) {
                new RuntimeException("get select sql is exceptoin:" + e);
            }
            selectSql.append(" from ").append(tableName).append(" where ");
            for (int i = 0; i < selectParaNames.size(); i++) {
                selectSql.append(selectParaNames.get(i)).append("=").append(selectParas.get(i));
                if (i != selectParaNames.size() - 1)
                    selectSql.append(" and ");
            }
            return selectSql.toString();
        }
    
        private String getTableName(Class<?> beanClass) {
            String tableName = "";
            Table table = beanClass.getAnnotation(Table.class);
            if (table != null) {
                tableName = table.value();
            } else {
                tableName = tableFormat.getTableName(beanClass.getSimpleName());
            }
            return tableName;
        }
    
        private Field[] getFields(Class<?> beanClass) {
            Field[] beanFields = beanClass.getDeclaredFields();
            Class<?> beanSuperClass = beanClass.getSuperclass();
            Field[] beanSuperFields = beanSuperClass.getDeclaredFields();
            return ArrayUtils.addAll(beanFields, beanSuperFields);
        }
    }

     

   三、源码地址 

  http://git.oschina.net/lianghao2016/mybatis-ext

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 75
博文 76
码字总数 30465
评论 (17)
haoran_10
不错,有想法!
小兵成长记

引用来自“haoran_10”的评论

不错,有想法!
因为懒所以找各种偷懒的方法44
引鸩怼孑
厉害!
os790858223
6666
k-magic
79挺好
akeng
不错,挺给力的
小兵成长记

引用来自“akeng”的评论

不错,挺给力的
应该还有更牛的功能,待发现,一起多看看
akeng

引用来自“akeng”的评论

不错,挺给力的

引用来自“小兵成长记”的评论

应该还有更牛的功能,待发现,一起多看看
不支持,类属性里面有其他类这种情况吧
小兵成长记

引用来自“akeng”的评论

不错,挺给力的

引用来自“小兵成长记”的评论

应该还有更牛的功能,待发现,一起多看看

引用来自“akeng”的评论

不支持,类属性里面有其他类这种情况吧
你说的是级联查询吧,肯定支持,需要配置一个resultMap
akeng

引用来自“akeng”的评论

不错,挺给力的

引用来自“小兵成长记”的评论

应该还有更牛的功能,待发现,一起多看看

引用来自“akeng”的评论

不支持,类属性里面有其他类这种情况吧

引用来自“小兵成长记”的评论

你说的是级联查询吧,肯定支持,需要配置一个resultMap
额,我只是说你的这个代码
小兵成长记

引用来自“akeng”的评论

不错,挺给力的

引用来自“小兵成长记”的评论

应该还有更牛的功能,待发现,一起多看看

引用来自“akeng”的评论

不支持,类属性里面有其他类这种情况吧

引用来自“小兵成长记”的评论

你说的是级联查询吧,肯定支持,需要配置一个resultMap

引用来自“akeng”的评论

额,我只是说你的这个代码
这个没写全,只在自己项目中用过,级联查询不通用,做不了扩展
akeng

引用来自“akeng”的评论

不错,挺给力的

引用来自“小兵成长记”的评论

应该还有更牛的功能,待发现,一起多看看

引用来自“akeng”的评论

不支持,类属性里面有其他类这种情况吧

引用来自“小兵成长记”的评论

你说的是级联查询吧,肯定支持,需要配置一个resultMap

引用来自“akeng”的评论

额,我只是说你的这个代码

引用来自“小兵成长记”的评论

这个没写全,只在自己项目中用过,级联查询不通用,做不了扩展
哦,用了你的这个在我的小项目里,还挺好用的,省了我的增删改查方法
小兵成长记

引用来自“akeng”的评论

引用来自“akeng”的评论

不错,挺给力的

引用来自“小兵成长记”的评论

应该还有更牛的功能,待发现,一起多看看

引用来自“akeng”的评论

不支持,类属性里面有其他类这种情况吧

引用来自“小兵成长记”的评论

你说的是级联查询吧,肯定支持,需要配置一个resultMap

引用来自“akeng”的评论

额,我只是说你的这个代码

引用来自“小兵成长记”的评论

这个没写全,只在自己项目中用过,级联查询不通用,做不了扩展
哦,用了你的这个在我的小项目里,还挺好用的,省了我的增删改查方法

还有分页也可以自己实现
Kevin_Zhan
地址失效了
小兵成长记

引用来自“Kevin_Zhan”的评论

地址失效了
项目不完整,占不公了,你看这篇博客就可以了,有什么问题,可以@我
Kevin_Zhan

引用来自“Kevin_Zhan”的评论

地址失效了

引用来自“小兵成长记”的评论

项目不完整,占不公了,你看这篇博客就可以了,有什么问题,可以@我
@小兵成长记 对了,那些import com.nmtx.mybatis.ext.common.table.TableFormat;
import com.nmtx.mybatis.ext.common.table.annotation.Column;
import com.nmtx.mybatis.ext.common.table.annotation.Table;
import com.nmtx.mybatis.ext.common.table.impl.HumpToUnderLineFormat; 都是你自己自定义的吧?怎么在博客里找不到相关的代码呢,大概的流程和思路我看了,想法的确挺好的
小兵成长记

引用来自“Kevin_Zhan”的评论

地址失效了

引用来自“小兵成长记”的评论

项目不完整,占不公了,你看这篇博客就可以了,有什么问题,可以@我

引用来自“Kevin_Zhan”的评论

@小兵成长记 对了,那些import com.nmtx.mybatis.ext.common.table.TableFormat;
import com.nmtx.mybatis.ext.common.table.annotation.Column;
import com.nmtx.mybatis.ext.common.table.annotation.Table;
import com.nmtx.mybatis.ext.common.table.impl.HumpToUnderLineFormat; 都是你自己自定义的吧?怎么在博客里找不到相关的代码呢,大概的流程和思路我看了,想法的确挺好的
嗯,是的,这个根据你自己的需求来,就是表名和你的bean对应转换,字段名和属性名之间的转换,你自己实现就好,我的个不一定适和你
×
小兵成长记
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: