mybatis通用DAO

掃掃關注「茶爸爸」微信公衆號
堅持最初的執着,從未曾有半點懈怠,爲優秀而努力,爲證實本身而活。
回覆:茶爸爸瞭解他這我的!!

花了幾天的時間研究了一下mybatis的源代碼,以爲這個框架仍是很不錯的。可是有一些缺陷的地方。java

先來講說它和別的框架比起來我認爲的好處:spring

          (1)sql外置,把sql文件寫在配置文件中加上強大的動態sql支持。sql

          (2)利用cjk動態代理,實現配置文件映射接口。數據庫

這樣咱們在使用這套orm框架的時候就能夠再也不寫那個拼接sql語句的dao實現類(dao-impl class),把dao實現類的工做都移交給那些*mapper.xml文件,若是數據庫查詢業務須要修改sql的話,那麼只須要修改xml文件中的sql語句。apache

須要擴展的地方:微信

          (1)沒有內置物理分頁的實現。session

咱們通常的習慣都是返回咱們本身的分頁實現類,網上大多的mybatis分頁實現都是先返回分頁列表,再查下返回總頁數,而後處理成咱們本身的分頁類。我本身也寫了一個分頁,把這部分工做交給mybatis來處理,之後會把代碼貼出來。antd

           (2)公用範型接口daomybatis

公用範型接口dao類幾乎成爲咱們開發中最長使用的,把一些長操做的方法封裝一下,供咱們的業務dao調用,可是在mybatis中,我如今不想再寫dao的實現類,只有接口類,取締他的是mapper-xml文件,這樣如何才能封裝咱們的公用方法呢。app

幸虧mybatis提供了插件攔截器,咱們能夠在不修改mybatis源碼的基礎上來擴展它的功能。

 

好忙啊,花了些時間寫了一個範型接口dao,尚未通過驗證,先貼上代碼。

使用方法很簡單,只要你使用MappInterceptor這個攔截器,在你的Mapper接口中繼承這個IGenericDao這樣 公用的方法就可使用了,這樣的好處是在通常業務的類中不用再寫Dao的實現,直接使用 IGenericDao中提供的方法就ok

 

 

公用dao,你的接口只要繼承這個dao就可使用裏面的方法。

 

package org.cf.guott.mybatis;

import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.cf.guott.mybatis.pagination.PageMyBatis;

public interface IGenericDao<T,PK> {
  
  @Select("MapperGD.find.entityById")
  public T findEntityById(PK id);
  
  @Select("MapperGD.find.entitys")
  public List<T> findEntity(Object... obj);
  
  @Select("MapperGD.find.ListByLike")
  public List<T> findLikeEntity(Object... obj);
  
  @Insert("MapperGD.insert.entity")
  public void insertEntity(T t);
  
  @Update("MapperGD.update.entity")
  public void updateEntityById(T entity);
  
  @Delete("MapperGD.delete.id")
  public void deleteById(PK id);
  
  @Delete("MapperGD.delete.condition")
  public void deleteByCondition(Object param);
  
  @Select("MapperGD.find.entity.queryByVo")
  public PageMyBatis<T> queryByVo(int i,int c,Object... obj);
  
  @Select("MapperGD.find.entity.queryByVoLike")
  public PageMyBatis<T> LikequeryByVo(int i,int c,Object... obj);
  
  
}
 

 

 

 這個一個攔截器,來處理你的公用dao中的方法

package org.cf.guott.mybatis.dbmapper.interceptor;

import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.cf.guott.mybatis.helpers.MapperSqlHelper;
import org.cf.guott.mybatis.pagination.MappedStatmentHelper;

  @Intercepts({
    @Signature(
          type = Executor.class,
          method = "query",
          args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
      ,@Signature(
          type = Executor.class,
          method = "update",
          args = {MappedStatement.class, Object.class})
  })
  
  public class MappInterceptor implements Interceptor{
    private final static String _sql_regex = ".*MapperGD.*";
    
    @SuppressWarnings("unchecked")
    private void processIntercept(final Object[] queryArgs) {
      final MappedStatement ms = (MappedStatement) queryArgs[0];
      final Object parameter = queryArgs[1];
      String mapperSQL = ms.getBoundSql(parameter).getSql();
      BoundSql boundSQL = ms.getBoundSql(parameter);
      
      Class<?> entityclazz = MappedStatmentHelper.getEntityClazz(ms.getResource());
      queryArgs[0] = MappedStatmentHelper.setMSReturnSetMap(ms, entityclazz);
      
      boolean interceptor = mapperSQL.matches(_sql_regex);
      if(!interceptor){
        return;
      }
      if(entityclazz == null){
        throw new RuntimeException("使用公共dao必須給mapper接口的@MyBatisRepository(User.class) 註解設置值.");
      }
      
      String new_sql = MapperSqlHelper.getExecuSQL(entityclazz,mapperSQL,parameter);
      
      BoundSql newBoundSql = MappedStatmentHelper.copyFromBoundSql(ms,
          boundSQL, new_sql);
      MappedStatement newMs = MappedStatmentHelper
          .copyFromMappedStatement(ms, newBoundSql);
      queryArgs[0] = newMs;
      
    }
    public Object intercept(Invocation invocation) throws Throwable {
      
      processIntercept(invocation.getArgs());
      
      return invocation.proceed();
    }
    public Object plugin(Object o) {
          return Plugin.wrap(o, this);
    }
    public void setProperties(Properties arg0) {
    }
  }
  這個類來處理你的sql語句
package org.cf.guott.mybatis.helpers;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;

import org.apache.commons.lang3.reflect.FieldUtils;
import org.cf.guott.mybatis.annotation.MyBatisColumn;
import org.cf.guott.mybatis.annotation.MyBatisRepository;
import org.cf.guott.mybatis.annotation.MybatisID;
import org.cf.guott.mybatis.annotation.MybatisTable;
import org.cf.guott.mybatis.entity.User;

public class MapperSqlHelper{

  public static final Class<? extends Annotation> MYBATISREPOSITORY = MyBatisRepository.class;
  public static final Class<? extends Annotation> MYBATISTABLE = MybatisTable.class;
  public static final Class<? extends Annotation> MYBATISCOLUMN = MyBatisColumn.class;
  public static final Class<? extends Annotation> MYBATISID = MybatisID.class;
  
  
  public  String getUpdateSQL(){
    return null;
  }
  /**
  * 傳入mapper接口class
  * @param mapperclazz
  * @return
  */
  private String insertEntity(Class<?> clazz){
    StringBuilder sql = new StringBuilder();
    StringBuilder intosql = new StringBuilder();
    StringBuilder valuessql = new StringBuilder();
    if(!clazz.isAnnotationPresent(MYBATISTABLE)){
      sql.append("INSERT INTO "+clazz.getName());
    }else{
      MybatisTable antable = (MybatisTable)clazz.getAnnotation(MYBATISTABLE);
      if(antable.value() == ""){
        sql.append("INSERT INTO "+clazz.getName());
      }else{
        sql.append("INSERT INTO "+antable.value());
      }
    }
    Field[] files = clazz.getDeclaredFields();
    intosql.append("(");
    for(Field file : files){
      file.setAccessible(true);
      if(file.isAnnotationPresent(MYBATISCOLUMN)){
        MyBatisColumn anColumn = (MyBatisColumn)file.getAnnotation(MYBATISCOLUMN);
        if(!anColumn.isAutoKey()){
          if(anColumn.value().equals("")){
            intosql.append(file.getName()+",");
          }else{
            intosql.append(anColumn.value()+",");
          }
        }
      }else{
        intosql.append(file.getName()+",");
      }
    }
    valuessql.append(" values (");
    for(Field file : files){
      file.setAccessible(true);
      if(file.isAnnotationPresent(MYBATISCOLUMN)){
        MyBatisColumn anColumn = (MyBatisColumn)file.getAnnotation(MYBATISCOLUMN);
        if(!anColumn.isAutoKey()){
          if(anColumn.value().equals("")){
            valuessql.append("#{"+file.getName()+"},");
          }else{
            valuessql.append("#{"+file.getName()+"},");
          }
        }
      }else{
        valuessql.append("#{"+file.getName()+"},");
      }
      
    }
    return sql.append(intosql.substring(0, intosql.length()-1)).append(") ").append(valuessql.substring(0, valuessql.length()-1)).append(")").toString();
  }
  
  /**
  * 傳入mapper接口class
  * @param mapperclazz
  * @return
  */
  private  String updateEntityById(Class<?> clazz){
    StringBuilder sql = new StringBuilder();
    StringBuilder set = new StringBuilder();
    StringBuilder wheresql = new StringBuilder();
    if(!clazz.isAnnotationPresent(MYBATISTABLE)){
      sql.append("UPDATE  "+clazz.getName());
    }else{
      MybatisTable antable = (MybatisTable)clazz.getAnnotation(MYBATISTABLE);
      if(antable.value() == ""){
        sql.append("UPDATE  "+clazz.getName());
      }else{
        sql.append("UPDATE  "+antable.value());
      }
    }
    Field[] files = clazz.getDeclaredFields();
    set.append(" set ");
    wheresql.append(" where 1=1 ");
    for(Field file : files){
      file.setAccessible(true);
      if(file.isAnnotationPresent(MYBATISCOLUMN)){
        MyBatisColumn anColumn = (MyBatisColumn)file.getAnnotation(MYBATISCOLUMN);
        if(!anColumn.isID()){//判斷字段不爲主鍵
          if(anColumn.value().equals("")){
            set.append(file.getName()+" = #{"+file.getName()+"} ,");
          }else{
            set.append(anColumn.value()+" = #{"+file.getName()+"} ,");
          }
        }else{
          if(anColumn.value().equals("")){
            wheresql.append(" and "+file.getName()+" = #{"+file.getName()+"},");
          }else{
            wheresql.append(" and "+anColumn.value()+" = #{"+anColumn.value()+"},");
          }
        }
      }else{
        set.append(file.getName()+" = #{"+file.getName()+"} ,");
      }
    }
    if(wheresql.equals(" where 1=1 ")){
      throw new RuntimeException("實體變量沒有設置ID字段值");
    }
    sql.append(set.substring(0, set.length()-1)).append(wheresql.substring(0, wheresql.length()-1));
    return sql.toString();
  }
  private String findEntityAll(Class<?> clazz,Object args,boolean islike){
    StringBuilder sql = new StringBuilder();
    StringBuilder whereSQL = new StringBuilder(" where 1=1 ");
    StringBuffer orderby = new StringBuffer();
    if(!clazz.isAnnotationPresent(MYBATISTABLE)){
      sql.append("select * from  "+clazz.getName());
    }else{
      MybatisTable antable = (MybatisTable)clazz.getAnnotation(MYBATISTABLE);
      if(antable.value() == ""){
        sql.append("select * from  "+clazz.getSimpleName());
      }else{
        sql.append("select * from  "+antable.value());
      }
    }
    Object[] paramObjs = (Object[]) ((Map)args).get("array");
    if(paramObjs != null && paramObjs.length>0){
      Object param = paramObjs[0];
      if(param != null ){
        if(param instanceof Map){
          Map<String,Object> map = (Map)param;
          if(map.containsKey("orderby")){
            orderby.append(" order by "+map.get("orderby"));
          }
          if(map.containsKey("sortby")){
            orderby.append(" "+map.get("sortby")+" ");
          }
          for(String key : map.keySet())
          {
            if(islike)
            whereSQL.append(" and "+key + " like '%" + map.get(key)+"%',");
            else whereSQL.append(" and "+key + " = '" + map.get(key)+"',");
          }
          sql.append(whereSQL.subSequence(0,whereSQL.length()-1)).append(orderby);
        }else if(param instanceof Conditions){
          Conditions<String,Object> map = (Conditions)param;
          if(map.containsKey("orderby")){
            orderby.append(" order by "+map.get("orderby"));
          }
          if(map.containsKey("sortby")){
            orderby.append(" "+map.get("sortby")+" ");
          }
          for(String key : map.keySet())
          {
            if(key.equals("orderby") || key.equals("sortby")){
              continue;
            }
            if(islike)
            whereSQL.append(" and "+key + " like '%" + map.get(key)+"%',");
            else whereSQL.append(" and "+key + " = '" + map.get(key)+"',");
          }
          sql.append(whereSQL.subSequence(0,whereSQL.length()-1)).append(orderby);
        }
      }
    }
    return sql.toString();
  }
  private String findEntityById(Class<?> clazz){
    StringBuilder sql = new StringBuilder();
    if(!clazz.isAnnotationPresent(MYBATISTABLE)){
      sql.append("select * from  "+clazz.getName());
    }else{
      MybatisTable antable = (MybatisTable)clazz.getAnnotation(MYBATISTABLE);
      if(antable.value() == ""){
        sql.append("select * from  "+clazz.getSimpleName());
      }else{
        sql.append("select * from  "+antable.value());
      }
    }
    sql.append("  where 1=1 ");
    Field[] files = clazz.getDeclaredFields();
    boolean falg = false;
    for(Field file : files){
      file.setAccessible(true);
      if(file.isAnnotationPresent(MyBatisColumn.class)){
        MyBatisColumn anColumn = (MyBatisColumn)file.getAnnotation(MYBATISCOLUMN);
        if(anColumn.isID()){//判斷字段不爲主鍵
          falg = true;
          if(anColumn.value().equals("")){
            sql.append(" and "+file.getName()+" = #{"+file.getName()+"},");
          }else{
            sql.append(" and "+file.getName()+" = #{"+file.getName()+"},");
          }
        }
      }
    }
    if(!falg){
      throw new RuntimeException("不能通過id查詢實體,實體中沒有定義@mybatisID");
    }
    
    return sql.subSequence(0, sql.length()-1).toString();
  }
  public String deleteById(Class<?> clazz){
    StringBuilder sql = new StringBuilder();
    StringBuilder wheresql = new StringBuilder(" where 1=1 ");
    if(!clazz.isAnnotationPresent(MYBATISTABLE)){
      sql.append("delete  "+clazz.getName());
    }else{
      MybatisTable antable = (MybatisTable)clazz.getAnnotation(MYBATISTABLE);
      if(antable.value() == ""){
        sql.append("delete  "+clazz.getName());
      }else{
        sql.append("delete  "+antable.value());
      }
    }
    Field[] files = clazz.getDeclaredFields();
    for(Field file : files){
      file.setAccessible(true);
      if(file.isAnnotationPresent(MYBATISCOLUMN)){
        MyBatisColumn anColumn = (MyBatisColumn)file.getAnnotation(MYBATISCOLUMN);
        if(anColumn.isID()){//判斷字段不爲主鍵
          if(anColumn.value().equals("")){
            wheresql.append(" and "+file.getName()+" = #{"+file.getName()+"},");
          }else{
            wheresql.append(" and "+anColumn.value()+" = #{"+anColumn.value()+"},");
          }
        }
      }
    }
    if(wheresql.equals(" where 1=1 ")){
      throw new RuntimeException("實體變量沒有設置ID字段值");
    }
    sql.append(wheresql.substring(0,wheresql.length()-1));
    return sql.toString();
  }
  public String queryByVo(Class<?> clazz,Object args,boolean islike){
    StringBuilder sql = new StringBuilder();
    StringBuilder whereSQL = new StringBuilder(" where 1=1 ");
    StringBuilder orderbySQL = new StringBuilder("");
    if(!clazz.isAnnotationPresent(MYBATISTABLE)){
      sql.append("select *  from "+clazz.getName());
    }else{
      MybatisTable antable = (MybatisTable)clazz.getAnnotation(MYBATISTABLE);
      if(antable.value() == ""){
        sql.append("select * from "+clazz.getName());
      }else{
        sql.append("select * from "+antable.value());
      }
    }
    if(args instanceof Map){
      Map map = (Map)args;
      Object[] arr = (Object[])map.get("param3");
      if(arr.length>0){
        Map<String,Object> params = (Map)arr[0];
        if(params.containsKey("orderby")){
          orderbySQL.append(" order by "+params.get("orderby"));
        }
        if(params.containsKey("sortby")){
          orderbySQL.append(" "+params.get("sortby")+" ");
        }
        for(String key:params.keySet()){
          if(key.equals("orderby") || key.equals("sortby")){
            continue;
          }
          if(islike)
            whereSQL.append(" and "+key + " like '%" + params.get(key)+"%',");
            else whereSQL.append(" and "+key + " = '" + params.get(key)+"',");
        }
      }
    }
    
    return sql.append(whereSQL.substring(0, whereSQL.length()-1)).append(orderbySQL).toString();
  }
  public String count(Class<?> clazz,Object args){
    StringBuilder sql = new StringBuilder();
    StringBuilder whereSQL = new StringBuilder(" where 1=1 ");
    if(!clazz.isAnnotationPresent(MYBATISTABLE)){
      sql.append("select count(*)  from "+clazz.getName());
    }else{
      MybatisTable antable = (MybatisTable)clazz.getAnnotation(MYBATISTABLE);
      if(antable.value() == ""){
        sql.append("select count(*) from "+clazz.getName());
      }else{
        sql.append("select count(*) from "+antable.value());
      }
    }
    Object[] paramObjs = (Object[]) ((Map)args).get("array");
    if(paramObjs != null && paramObjs.length>0){
      Object param = paramObjs[0];
      if(param != null ){
        if(param instanceof Map){
          Map<String,Object> map = (Map)param;
          for(String key : map.keySet())
          {
            whereSQL.append(" and "+key + " = '" + map.get(key)+"',");
          }
          sql.append(whereSQL.subSequence(0,whereSQL.length()-1));
        }else if(param instanceof Conditions){
          Conditions<String,Object> map = (Conditions)param;
          for(String key : map.keySet())
          {
            whereSQL.append(" and "+key + " = '" + map.get(key)+"',");
          }
          sql.append(whereSQL.subSequence(0,whereSQL.length()-1));
        }
      }
    }
    return sql.toString();
  }
  public String deleteByCondition(Class<?> clazz,Object param){
    StringBuilder sql = new StringBuilder();
    StringBuilder whereSQL = new StringBuilder(" where 1=1 ");
    if(!clazz.isAnnotationPresent(MYBATISTABLE)){
      sql.append("delete  "+clazz.getName());
    }else{
      MybatisTable antable = (MybatisTable)clazz.getAnnotation(MYBATISTABLE);
      if(antable.value() == ""){
        sql.append("delete  "+clazz.getName());
      }else{
        sql.append("delete  "+antable.value());
      }
    }
    if(param != null ){
      if(param instanceof Map){
        Map<String,Object> map = (Map)param;
        for(String key : map.keySet())
        {
          whereSQL.append(" and "+key + " = '" + map.get(key)+"',");
        }
        sql.append(whereSQL.subSequence(0,whereSQL.length()-1));
      }else if(param instanceof Conditions){
        Conditions<String,Object> map = (Conditions)param;
        for(String key : map.keySet())
        {
          whereSQL.append(" and "+key + " = '" + map.get(key)+"',");
        }
        sql.append(whereSQL.subSequence(0,whereSQL.length()-1));
      }
    }
    if(whereSQL.equals(" where 1=1 ")){
      throw new RuntimeException("實體變量沒有設置ID字段值");
    }
    return sql.toString();
  }
  private static MapperSqlHelper App(){
    return new MapperSqlHelper();
  }
  public static String getExecuSQL(Class<?> clazz, String mapperDBsql,Object param) {
    if(mapperDBsql.equals("MapperGD.find.entitys")){
      return MapperSqlHelper.App().findEntityAll(clazz,param,false);//條件查詢實體列表
    }else if(mapperDBsql.equals("MapperGD.find.entityById")){
      return MapperSqlHelper.App().findEntityById(clazz);//id查詢實體
    }else if(mapperDBsql.equals("MapperGD.find.ListByLike")){
      return MapperSqlHelper.App().findEntityAll(clazz,param,true);//條件查詢實體列表
    }else if(mapperDBsql.equals("MapperGD.insert.entity")){
      return MapperSqlHelper.App().insertEntity(clazz);//保存單一實體
    }else if(mapperDBsql.equals("MapperGD.update.entity")){
      return MapperSqlHelper.App().updateEntityById(clazz);//保存單一實體
    }else if(mapperDBsql.equals("MapperGD.update.entity.condistion")){
      return mapperDBsql;
    }else if(mapperDBsql.equals("MapperGD.delete.id")){
      return MapperSqlHelper.App().deleteById(clazz);
    }else if(mapperDBsql.equals("MapperGD.delete.condition")){
      return MapperSqlHelper.App().deleteByCondition(clazz,param);
    }else if(mapperDBsql.equals("MapperGD.count.condition")){
      return MapperSqlHelper.App().count(clazz,param);
    }else if(mapperDBsql.equals("MapperGD.find.entity.queryByVo")){
      return MapperSqlHelper.App().queryByVo(clazz,param,false);
    }else if(mapperDBsql.equals("MapperGD.find.entity.queryByVoLike")){
      return MapperSqlHelper.App().queryByVo(clazz,param,true);
    }
    return null;
  }
  //預留接口
  private  String updateEntityByConditions(Class<?> clazz,Object param){
    
    return null;
  }
  public void getParam(Object param){
    StringBuffer bf = new StringBuffer();
    if (isPrimitiveType(param.getClass())) {
      bf.append(param);
        } else if (param instanceof Map) {
        	Map<String,Object> map = (Map)param;
        } 
  }
  
  public static boolean isPrimitiveType(Class clazz) {
        return clazz != null && (clazz.isPrimitive() || clazz.equals(Long.class) || clazz.equals(Integer.class)
                || clazz.equals(Short.class) || clazz.equals(Byte.class) || clazz.equals(Double.class)
                || clazz.equals(Float.class) || clazz.equals(Boolean.class) || clazz.equals(Character.class) || clazz.equals(String.class));
    }
  public static void main(String[] args) {
//		Object object = null;
//		if (isPrimitiveType(object.getClass())) {
//        } else if (object instanceof Map) {
//        } 
    Field[] files = User.class.getDeclaredFields();
    User u = new User();
    try {
      System.out.println(FieldUtils.readDeclaredField(u, "id",true));
    } catch (IllegalAccessException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
 測試用例:

 

業務dao,這個接口繼承自 IGenericDao

package org.cf.guott.mybatis.mapper;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Select;
import org.cf.guott.mybatis.ITestGDAO;
import org.cf.guott.mybatis.annotation.MyBatisRepository;
import org.cf.guott.mybatis.entity.User;
import org.cf.guott.mybatis.pagination.PageMyBatis;

@MyBatisRepository(User.class)
public interface UserMapper extends IGenericDao<User,Integer>{

}
 main運行方法
package org.cf.guott.mybatis.main;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.RowBounds;
import org.cf.guott.mybatis.entity.User;
import org.cf.guott.mybatis.helpers.Conditions;
import org.cf.guott.mybatis.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class Main {
  @Autowired
  UserMapper userMapper;
  public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-mybatis.xml");
    Main main = context.getBean(Main.class);
    Map map = new HashMap();
    map.put("name", "ccc");
    List<User> users = main.userMapper.LikequeryByVo(0,2,new Conditions<String, Object>().add("name", "guotiantdddian").addOrderBy("id").setSortByDesc());
System.out.println(users.size());
}
}
相關文章
相關標籤/搜索