大概
- 对于一些业务逻辑操作,每个实体类会有很多重复的操作,如学生管理,教师管理,书本管理等都会需要用到增删查改,就会出现大量的重复代码,不优雅,不美观,没逼格。
- 所以 我想法呢 就是将那些重复的代码抽出来,放到一个公共的mapper中(学过mybatis的应该能明白吧),并慢慢加上分页、级联。
- 实现呢就是封装一个 base 层 ,将需要的数据在 service 层中处理好后 传给 baseDao 的接口,然后在baseMapper 中使用动态语句来实现对数据库的操作
- 当然如果大牛觉得此方法有什么不妥 完全可以说出来,我可以调整,如果这个结构不妥,不符合java或者编程上的某些高深的思想,那就当是另外一种方式来学习吧。毕竟都是一种实现方式,没有最好的,只有慢慢发掘更好,让其更完善
先简单实现一些公用方法.当前结构如下图:
public interface IBaseService <T>{ void del( int id ); List<T> queryAll(); int add( T t ); void update ( T t ); }
package com.hututu.xinyong.base.serviceImpl; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.ibatis.javassist.CodeConverter.ArrayAccessReplacementMethodNames; import org.springframework.stereotype.Service; import com.hututu.commons.Tool; import com.hututu.xinyong.base.service.IBaseService; import com.hututu.xinyong.dao.IBaseDao; @Service public abstract class BaseService<T> implements IBaseService<T>{ //提供一个抽象方法 当前类的子类需要提供具体实现类的 Dao public abstract IBaseDao<T> getBaseDao(); //提供一个抽象方法 当前类的子类需要提供 entity的 Class 对象 public abstract Class<T> getClasss(); public Class<T> clsss; { clsss = getClasss(); } /** * 根据 id 查找一个对象 */ @Override public T queryOne(Long id) { String name = getTableName(); Map<Object, Object> map = getBaseDao().queryOne(name,id).get(0); T t = hashMapToEntity(map); return t; } /** * 查找所有对象 */ @Override public List<T> queryAll() { List<T> ts = new ArrayList<>(); String name = clsss.getSimpleName().toLowerCase(); List<HashMap<Object, Object>> list = getBaseDao().queryAll( name ); for (HashMap<Object, Object> hashMap : list) { ts.add( hashMapToEntity( hashMap ) ); } return ts; } /** * 添加一个 对象 */ @Override public int add(T t) { //获取表名 String tableName = getTableName(); List<String> clumus= new ArrayList<>(); List<Object> list= new ArrayList<>(); //将参数放入数组中 for (Field field : getAllFields()) { field.setAccessible(true);//权限 try { if ( field.get(t) == null ) { continue; } list.add(field.get(t)); clumus.add(field.getName()); } catch (IllegalArgumentException | IllegalAccessException e) { e.printStackTrace(); } } clumus.add("create_time"); clumus.add("update_time"); clumusToline(clumus); list.add(new Date()); list.add(new Date()); return getBaseDao().add( tableName ,clumus.toArray(),list.toArray() ); } /** * 更新一个对象 */ @Override public void update(T t) { Long id = 0l; String tableName = getTableName(); List<Object> list= new ArrayList<>(); for (Field field : t.getClass().getDeclaredFields()) { field.setAccessible(true);//权限 try { if ( field.get(t) == null ) { continue; } if (("id").equals( field.getName()) ) { id = (Long) field.get(t); continue ; } //拼接成 :变量名='值' 的形式 list.add( field.getName()+"="+ "'" + field.get(t) + "'" ); } catch (IllegalArgumentException | IllegalAccessException e) { e.printStackTrace(); } } getBaseDao().update( id, tableName , list.toArray() ); } public Field[] getAllFields(){ Class clazz = clsss; List<Field> fieldList = new ArrayList<>(); while (clazz != null){ Field[] Filelds = clazz.getDeclaredFields(); for (Field field : Filelds) { if(!fieldList.contains(field)) { fieldList.add(field); } } clazz = clazz.getSuperclass(); } Field[] fields = new Field[fieldList.size()]; System.out.println(fieldList.size()); fieldList.toArray(fields); return fields; } /** * 根据id 删除 一个对象 */ @Override public void del(Long id) { String name = clsss.getSimpleName(); name = name.toLowerCase(); getBaseDao().del(name, id); } private String getTableName() { String name=clsss.getSimpleName(); String tableName = Tool.humpToLine2(name); return tableName; } private T hashMapToEntity(Map<Object, Object> map) { return injectBean(clsss,map); } //使用泛型 public static final <T> T injectBean(Class<T> beanClass,Map parasMap) { T bean = null; try { //通过反射生成对象 bean = beanClass.newInstance(); //还可以用Class.forName生成对象 } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } //获取类的方法 Method[] methods = beanClass.getMethods(); int len = methods.length; for(int i = 0; i < len; ++i) { Method method = methods[i]; String methodName = method.getName(); //如果方法名是set开头的且名字长度大于3的 if(methodName.startsWith("set") && methodName.length() > 3) { //获取方法的参数类型 Class[] types = method.getParameterTypes(); //只有一个参数的方法才继续执行 if(types.length == 1) { //取字段名且让其首字母小写 String attrName = firstCharToLowerCase(methodName.substring(3)); //map中是否有属性名 attrName=Tool.humpToLine2(attrName); if(parasMap.containsKey(attrName)) { Object value = parasMap.get(attrName); try { //通过反射的方式执行bean的mothod方法,在这里相当于执行set方法赋值 method.invoke(bean, new Object[]{value}); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } } } return bean; } //取字段名且让其首字母小写 public static String firstCharToLowerCase(String substring) { if (substring!=null&& substring.charAt(0)>='A' && substring.charAt(0)<='Z'){ char[] arr = substring.toCharArray(); arr[0] = (char)(arr[0] + 32); return new String(arr); }else { return substring; } } public void clumusToline(List<String> clumus) { for(int i=0;i<clumus.size();i++) { clumus.set(i, Tool.humpToLine2(clumus.get(i))); } } }
接下来是 Dao 层接口
- mybatis 中 一个多个参数时需要用 @Param(” xxx “) 设置别名以区分
package com.hututu.xinyong.dao; import java.util.HashMap; import java.util.List; import org.apache.ibatis.annotations.Param; public interface IBaseDao <T> { List<HashMap<Object, Object>> queryOne( @Param("name") String name,@Param("id")Long id ); List<HashMap<Object, Object>> queryAll( @Param("name") String name ); int add( @Param("name")String name ,@Param("clumus") Object[] clumus, @Param("values") Object ...values ); void update ( @Param("id") Long id, @Param("name") String name, @Param("params")Object []params ); void del(@Param("name")String lowerCase, @Param("id")Long id); }
Dao 的实现类
- 在service中将参数处理好 然后在此 mapper 中使用动态SQL语句进行操作
- 因为不知道查询的时候返回的是啥子 所以 返回类型是一个 hashmap 接收需要用 List
-
<?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.hututu.xinyong.dao.IBaseDao" > <!-- 按id查找一个 --> <select id="queryOne" resultType="hashmap"> select * from ${name} where id=#{id} </select> <!-- 查询所有 --> <select id="queryAll" resultType="hashmap"> select * from ${name} </select> <insert id="add" > insert into ${name} <foreach collection="clumus" item="clumu" open="(" separator="," close=")" > ${clumu} </foreach> values <foreach collection="values" item="value" open="(" separator="," close=")" > #{value} </foreach> </insert> <update id="update"> update ${name} <set> <foreach collection="params" item="param" > ${param}, </foreach> </set> where id=#{id} </update> <update id="del"> update ${name} <set> dr=1 </set> where id=#{id} </update> </mapper>