Mybatis 实现共通的增删改查

    xiaoxiao2024-10-18  1

    基于之前写的一套SpringMvc+Mybatis+Maven开源框架,实现了通过配置model层注解的方式,在项目启动的时候自动创建更新表结构。

    如果没看过的可以看下那篇文章的博客地址:Mybatis自动创建表/更新表结构/动态建表

    这本身是一个类似于hibanete的功能,因此,为了更加适合使用hibanete的同学,再次增加共通的CRUD方法,用于对基本表的增删改查,不需要使用代码生成器工具或者自己手动去写这些最基本的代码。

    废话不多说直接上代码。

    Dao层

    /** * 创建更新表结构的Mapper * @author sunchenbin * */ public interface BaseMysqlCRUDMapper { /** * 保存 * @param tableMap */ public void save(@Param("tableMap") Map<Object, Map<Object, Object>> tableMap); /** * 更新 * @param tableMap */ public void update(@Param("tableMap") Map<Object, Map<Object, Object>> tableMap); /** * 删除 * @param tableMap */ public void delete(@Param("tableMap") Map<Object, Map<Object, Object>> tableMap); /** * 查询 * @param <T> * @param tableMap */ public List<Map<String,Object>> query(@Param("tableMap") Map<Object, Map<Object, Object>> tableMap); }

    映射Dao的Mapper

    <?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.sunchenbin.store.dao.common.BaseMysqlCRUDMapper"> <!-- 保存 --> <select id="save" parameterType="java.util.Map"> <foreach collection="tableMap" index="key" item="value"> insert into `${key}`( <foreach collection="value" index="field" item="fieldvalue" separator=","> <if test="fieldvalue != null"> `${field}` </if> </foreach> ) values( <foreach collection="value" item="fieldvalue" separator=","> <if test="fieldvalue != null"> #{fieldvalue} </if> </foreach> ) </foreach> </select> <!-- 更新 --> <select id="update" parameterType="java.util.Map"> <foreach collection="tableMap" index="key" item="value"> update `${key}` set <foreach collection="value" index="field" item="fieldvalue" separator=","> <if test="fieldvalue != null"> <if test="field != 'keyFieldMap'"> `${field}` = #{fieldvalue} </if> </if> </foreach> where <foreach collection="value" index="keyfield" item="keyvalues"> <if test="keyfield == 'keyFieldMap'"> <foreach collection="keyvalues" index="field" item="fieldvalue"> `${field}` = #{fieldvalue} </foreach> </if> </foreach> </foreach> </select> <!-- 删除 --> <select id="delete" parameterType="java.util.Map"> <foreach collection="tableMap" index="key" item="value"> delete from `${key}` where <foreach collection="value" index="field" item="fieldvalue" separator=" and "> <if test="fieldvalue != null"> `${field}` = #{fieldvalue} </if> </foreach> </foreach> </select> <!-- 查询 --> <select id="query" parameterType="java.util.Map" resultType="java.util.HashMap"> <foreach collection="tableMap" index="key" item="value"> select * from `${key}` where <foreach collection="value" index="field" item="fieldvalue" separator=" and "> <if test="fieldvalue != null"> `${field}` = #{fieldvalue} </if> </foreach> </foreach> </select> </mapper>

    manager接口

    public interface BaseMysqlCRUDManager<T>{ /** * 保存,如果主键有值则进行更新操作 * @param t */ void save(T t); /** * 根据传入对象非空的条件删除 * @param t */ void delete(T t); /** * 根据传入对象非空的条件进行查询 * @param t */ List<T> query(T t); }

    manager实现类

    package com.sunchenbin.store.manager.common; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.sunchenbin.store.annotation.Column; import com.sunchenbin.store.annotation.Table; import com.sunchenbin.store.dao.common.BaseMysqlCRUDMapper; @Transactional @Service("baseMysqlCRUDManager") public class BaseMysqlCRUDManagerImpl implements BaseMysqlCRUDManager{ private static final Logger log = LoggerFactory.getLogger(BaseMysqlCRUDManagerImpl.class); private static final String KEYFIELDMAP = "keyFieldMap"; @Autowired private BaseMysqlCRUDMapper baseMysqlCRUDMapper; public void save(Object obj){ boolean isSave = true; Table tableName = obj.getClass().getAnnotation(Table.class); if ((tableName == null) || (tableName.name() == null || tableName.name() == "")) { log.error("必须使用model中的对象!"); return; } Map<Object, Map<Object, Object>> tableMap = new HashMap<Object, Map<Object, Object>>(); Map<Object, Object> dataMap = new HashMap<Object, Object>(); Map<String, Object> keyFieldMap = new HashMap<String, Object>(); Field[] declaredFields = obj.getClass().getDeclaredFields(); for (Field field : declaredFields){ try{ // 私有属性需要设置访问权限 field.setAccessible(true); Column column = field.getAnnotation(Column.class); if (column == null) { log.info("该field没有配置注解不是表中在字段!"); continue; } // 如果是主键,并且不是空的时候,这时候应该是更新操作 if (column.isKey() && field.get(obj) != null) { isSave = false; keyFieldMap.put(field.getName(), field.get(obj)); } // 如果是自增,并且是保存的场合,不需要添加到map中做保存 if (isSave && column.isAutoIncrement()) { log.info("字段:" + field.getName() + "是自增的不需要添加到map中"); continue; } dataMap.put(field.getName(), field.get(obj)); }catch (IllegalArgumentException e){ e.printStackTrace(); }catch (IllegalAccessException e){ e.printStackTrace(); } } if (isSave) { tableMap.put(tableName.name(), dataMap); // 执行保存操作 baseMysqlCRUDMapper.save(tableMap); }else{ dataMap.put(KEYFIELDMAP, keyFieldMap); tableMap.put(tableName.name(), dataMap); // 执行更新操作根据主键 baseMysqlCRUDMapper.update(tableMap); } } public void delete(Object obj){ // 得到表名 Table tableName = obj.getClass().getAnnotation(Table.class); if ((tableName == null) || (tableName.name() == null || tableName.name() == "")) { log.error("必须使用model中的对象!"); return; } Map<Object, Map<Object, Object>> tableMap = new HashMap<Object, Map<Object, Object>>(); Map<Object, Object> dataMap = new HashMap<Object, Object>(); Field[] declaredFields = obj.getClass().getDeclaredFields(); for (Field field : declaredFields){ // 设置访问权限 field.setAccessible(true); // 得到字段的配置 Column column = field.getAnnotation(Column.class); if (column != null) { log.info("该field没有配置注解不是表中在字段!"); continue; } try{ dataMap.put(column.name(), field.get(obj)); }catch (IllegalArgumentException e){ e.printStackTrace(); }catch (IllegalAccessException e){ e.printStackTrace(); } } tableMap.put(tableName.name(), dataMap); baseMysqlCRUDMapper.delete(tableMap); } public List query(Object obj){ // 得到表名 Table tableName = obj.getClass().getAnnotation(Table.class); if ((tableName == null) || (tableName.name() == null || tableName.name() == "")) { log.error("必须使用model中的对象!"); return null; } Map<Object, Map<Object, Object>> tableMap = new HashMap<Object, Map<Object, Object>>(); Map<Object, Object> dataMap = new HashMap<Object, Object>(); Field[] declaredFields = obj.getClass().getDeclaredFields(); for (Field field : declaredFields){ // 设置访问权限 field.setAccessible(true); // 得到字段的配置 Column column = field.getAnnotation(Column.class); if (column != null) { log.info("该field没有配置注解不是表中在字段!"); continue; } try{ dataMap.put(column.name(), field.get(obj)); }catch (IllegalArgumentException e){ e.printStackTrace(); }catch (IllegalAccessException e){ e.printStackTrace(); } } tableMap.put(tableName.name(), dataMap); List<Map<String, Object>> query = baseMysqlCRUDMapper.query(tableMap); List<Object> list = new ArrayList<Object>(); try{ for (Map<String, Object> map : query){ Object newInstance = obj.getClass().newInstance(); Field[] declaredFields2 = newInstance.getClass().getDeclaredFields(); for (Field field : declaredFields2){ field.setAccessible(true); // 得到字段的配置 Column column = field.getAnnotation(Column.class); if (column != null) { log.info("该field没有配置注解不是表中在字段!"); continue; } String name = field.getName(); field.set(newInstance, map.get(name)); } list.add(newInstance); } }catch (InstantiationException e){ // TODO Auto-generated catch block e.printStackTrace(); }catch (IllegalAccessException e){ // TODO Auto-generated catch block e.printStackTrace(); } return list; } }

    使用方法

    @Controller public class TestController{ @Autowired private BaseMysqlCRUDManager<Test> baseMysqlCRUDManager; /** * 首页 */ @RequestMapping("/testDate") @ResponseBody public String testDate(){ Test test = new Test(); test.setName("aaae333"); test.setNumber(9L); test.setDescription("adfsdfe"); baseMysqlCRUDManager.delete(test); baseMysqlCRUDManager.save(test); List<Test> query = baseMysqlCRUDManager.query(test); String json = JsonUtil.format(query); return json; } }

    注意上面使用的对象Test必须是用于创建表时使用的对象,也就是源码中model中的对象,具体可以查看码云上的代码。

    基本思想就是进行数据组装和拼接sql的过程而已没什么特别的东西。

    需要注意的是,model对象中的属性,的数据类型一定要跟数据库中的类型匹配起来,否则转化的时候会报错的,因为类型不同转化肯定会有问题的嘛!

    save的时候会自动去判断哪个是主键,如果主键有值那么就去做更新,否则做插入操作。

    然后就是不要使用基本的数据类型,比如int这种,他默认是0,像上面说的save方法,如果你的主键是id类型使用了int,那么save的机制就会拿着id等于0去无限做更新。。。这不是你的本意。

    因此仔细看过我代码的同学,应该能够明白,比如delete和query或者save的时候我用的where条件,都只是判断null的,所以如果你使用了这种基本数据类型,那么我判断null的时候是无法拦截下这个条件的,所以得到的结果可能就跟你预期的不一样了。

    项目已经放到码云上感兴趣的可以下下来看看:代码下载地址

    有问题的欢迎留言~~~

    转载请注明原文地址: https://ju.6miu.com/read-1292753.html
    最新回复(0)