博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于mybatis的BaseDao及BaseService深度结合
阅读量:5776 次
发布时间:2019-06-18

本文共 19380 字,大约阅读时间需要 64 分钟。

hot3.png

mybatis帮助程序猿省去了很多工作了,需要结合好BaseDao与BaseService,这里就提供下我所使用的BaseXXX。

前提,mybatis的映射文件是采用mybatis-generator自动生成的()

 

1、BaseDao,我们知道在mybatis与SpringMVC结合的时候,Dao层只需要写interface即可,剩下的实现工作将由mybatis自动为我们实现,这个BaseDao省去interface这层,采用SpringMvc的@Repository标签进行注入管理,上代码:

import java.io.Serializable;  import java.lang.reflect.InvocationTargetException;  import java.util.HashMap;  import java.util.List;  import java.util.Map;    import org.apache.commons.beanutils.PropertyUtils;  import org.apache.ibatis.session.RowBounds;  import org.apache.ibatis.session.SqlSessionFactory;  import org.mybatis.spring.support.SqlSessionDaoSupport;  import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.stereotype.Repository;    import com.alibaba.dubbo.common.utils.CollectionUtils;  import com.github.pagehelper.PageHelper;  import com.github.pagehelper.PageInfo;  //工具类  import com.ivan.core.util.GenericsUtils;  //分页Form  import com.ivan.core.util.page.PageForm;    @Repository("baseDao")  public class BaseDao
extends SqlSessionDaoSupport implements Serializable { private static final long serialVersionUID = 7623507504198633838L; private final String POSTFIX = "Dao"; private final String _INSERT = ".insert"; private final String _INSERTSELECTIVE = ".insertSelective"; private final String _SELECTBYPRIMARYKEY = ".selectByPrimaryKey"; private final String _UPDATEBYPRIMARYKEY = ".updateByPrimaryKey"; private final String _UPDATEBYPRIMARYKEYSELECTIVE = ".updateByPrimaryKeySelective"; private final String _DELETEBYPRIMARYKEY = ".deleteByPrimaryKey"; @Autowired public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { super.setSqlSessionFactory(sqlSessionFactory); } /*GenericsUtils为工具类,请见下方代码 泛型获得XXXEntity,将其转换为XXXEntityDao,具体操作替换掉Entity变成XXXDao,对应Mapper.xml中的namespace命名 */ @SuppressWarnings({ "unchecked", "rawtypes" }) public String getNampSpace() { Class
clazz = (Class)GenericsUtils.getSuperClassGenricType(this.getClass()); String simpleName = clazz.getSimpleName() + POSTFIX; return simpleName; } public int insert(T entity) { return getSqlSession().insert( (this.getNampSpace().contains("Entity") ? this.getNampSpace().replace("Entity", "") : this.getNampSpace()) + _INSERT, entity); } public int insertSelective(T record) { return getSqlSession().insert( (this.getNampSpace().contains("Entity") ? this.getNampSpace().replace("Entity", "") : this.getNampSpace()) + _INSERTSELECTIVE, record); } public T selectByPrimaryKey(PK id) { return getSqlSession().selectOne( (this.getNampSpace().contains("Entity") ? this.getNampSpace().replace("Entity", "") : this.getNampSpace()) + _SELECTBYPRIMARYKEY, id); } public int updateByPrimaryKey(T record) { return getSqlSession().update( (this.getNampSpace().contains("Entity") ? this.getNampSpace().replace("Entity", "") : this.getNampSpace()) + _UPDATEBYPRIMARYKEY, record); } public int updateByPrimaryKeySelective(T record) { return getSqlSession().update( (this.getNampSpace().contains("Entity") ? this.getNampSpace().replace("Entity", "") : this.getNampSpace()) + _UPDATEBYPRIMARYKEYSELECTIVE, record); } public int deleteByPrimaryKey(PK id) { return getSqlSession().delete( (this.getNampSpace().contains("Entity") ? this.getNampSpace().replace("Entity", "") : this.getNampSpace()) + _DELETEBYPRIMARYKEY, id); } @SuppressWarnings({ "rawtypes", "unchecked" }) public PageInfo
pageFind(String statementKey, PageForm pageForm, Object parameter, Boolean isSimplePage) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { Map params = new HashMap(); if (parameter != null) { if (parameter instanceof Map) { params.putAll((Map) parameter); } else { Map parameterObject = PropertyUtils.describe(parameter); params.putAll(parameterObject); } } PageHelper.startPage(pageForm.getPage(), pageForm.getRows()); List
list = getSqlSession().selectList(statementKey, params); PageInfo
pageInfo = new PageInfo(list); return pageInfo; } @SuppressWarnings({ "rawtypes", "unchecked" }) public List
findTop(int top, String statementKey, Object parameter) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { Map params = new HashMap(); if (parameter != null) { if (parameter instanceof Map) { params.putAll((Map) parameter); } else { Map parameterObject = PropertyUtils.describe(parameter); params.putAll(parameterObject); } } List
list = getSqlSession().selectList(statementKey, params, new RowBounds(0, top)); return list; } public T findTopOne(String statementKey, Object parameter) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { List
list = findTop(1, statementKey, parameter); return CollectionUtils.isEmpty(list) ? null : list.get(0); } @SuppressWarnings({ "rawtypes", "unchecked" }) public
PageInfo
pageFindModel(String statementKey, PageForm pageForm, Object parameter) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { Map params = new HashMap(); if (parameter != null) { if (parameter instanceof Map) { params.putAll((Map) parameter); } else { Map parameterObject = PropertyUtils.describe(parameter); params.putAll(parameterObject); } } PageHelper.startPage(pageForm.getPage(), pageForm.getRows()); List
list = getSqlSession().selectList(statementKey, params); PageInfo
pageInfo = new PageInfo(list); return pageInfo; } }

2、泛型工具类,GenericsUtils:

import java.lang.reflect.Field;  import java.lang.reflect.Method;  import java.lang.reflect.ParameterizedType;  import java.lang.reflect.Type;  import java.util.ArrayList;  import java.util.List;  import java.util.Random;    import javax.servlet.http.HttpSession;    import org.springframework.web.context.request.RequestContextHolder;  import org.springframework.web.context.request.ServletRequestAttributes;    /**  * 泛型工具类  *   * @author ShunLi  * @notes Created on 2010-1-21
* Revision of last commit:$Revision: 1.1 $
* Author of last commit:$Author: ghp $
* Date of last commit:$Date: 2010-01-25 16:48:17 +0800 (周一, 25 一月 2010) * $
*

*/ public class GenericsUtils { /** * 通过反射,获得指定类的父类的泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport

* * @param clazz * clazz 需要反射的类,该类必须继承范型父类 * @param index * 泛型参数所在索引,从0开始. * @return 范型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回 *
Object.class */ public static Class getSuperClassGenricType(Class clazz, int index) { Type genType = clazz.getGenericSuperclass();// 得到泛型父类 // 如果没有实现ParameterizedType接口,即不支持泛型,直接返回Object.class if (!(genType instanceof ParameterizedType)) { return Object.class; } // 返回表示此类型实际类型参数的Type对象的数组,数组里放的都是对应类型的Class, 如BuyerServiceBean extends // DaoSupport
就返回Buyer和Contact类型 Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); if (index >= params.length || index < 0) { throw new RuntimeException("你输入的索引" + (index < 0 ? "不能小于0" : "超出了参数的总数")); } if (!(params[index] instanceof Class)) { return Object.class; } return (Class) params[index]; } /** * 通过反射,获得指定类的父类的第一个泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport
* * @param clazz * clazz 需要反射的类,该类必须继承泛型父类 * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回 *
Object.class */ @SuppressWarnings("unchecked") public static Class getSuperClassGenricType(Class clazz) { return getSuperClassGenricType(clazz, 0); } /** * 通过反射,获得方法返回值泛型参数的实际类型. 如: public Map
getNames(){} * * @param Method * method 方法 * @param int index 泛型参数所在索引,从0开始. * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回 *
Object.class */ @SuppressWarnings("unchecked") public static Class getMethodGenericReturnType(Method method, int index) { Type returnType = method.getGenericReturnType(); if (returnType instanceof ParameterizedType) { ParameterizedType type = (ParameterizedType) returnType; Type[] typeArguments = type.getActualTypeArguments(); if (index >= typeArguments.length || index < 0) { throw new RuntimeException("你输入的索引" + (index < 0 ? "不能小于0" : "超出了参数的总数")); } return (Class) typeArguments[index]; } return Object.class; } /** * 通过反射,获得方法返回值第一个泛型参数的实际类型. 如: public Map
getNames(){} * * @param Method * method 方法 * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回 *
Object.class */ @SuppressWarnings("unchecked") public static Class getMethodGenericReturnType(Method method) { return getMethodGenericReturnType(method, 0); } /** * 通过反射,获得方法输入参数第index个输入参数的所有泛型参数的实际类型. 如: public void add(Map
maps, List
names){} * * @param Method * method 方法 * @param int index 第几个输入参数 * @return 输入参数的泛型参数的实际类型集合, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回空集合 */ @SuppressWarnings("unchecked") public static List
getMethodGenericParameterTypes(Method method, int index) { List
results = new ArrayList
(); Type[] genericParameterTypes = method.getGenericParameterTypes(); if (index >= genericParameterTypes.length || index < 0) { throw new RuntimeException("你输入的索引" + (index < 0 ? "不能小于0" : "超出了参数的总数")); } Type genericParameterType = genericParameterTypes[index]; if (genericParameterType instanceof ParameterizedType) { ParameterizedType aType = (ParameterizedType) genericParameterType; Type[] parameterArgTypes = aType.getActualTypeArguments(); for (Type parameterArgType : parameterArgTypes) { Class parameterArgClass = (Class) parameterArgType; results.add(parameterArgClass); } return results; } return results; } /** * 通过反射,获得方法输入参数第一个输入参数的所有泛型参数的实际类型. 如: public void add(Map
* maps, List
names){} * * @param Method * method 方法 * @return 输入参数的泛型参数的实际类型集合, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回空集合 */ @SuppressWarnings("unchecked") public static List
getMethodGenericParameterTypes(Method method) { return getMethodGenericParameterTypes(method, 0); } /** * 通过反射,获得Field泛型参数的实际类型. 如: public Map
names; * * @param Field * field 字段 * @param int index 泛型参数所在索引,从0开始. * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回 *
Object.class */ @SuppressWarnings("unchecked") public static Class getFieldGenericType(Field field, int index) { Type genericFieldType = field.getGenericType(); if (genericFieldType instanceof ParameterizedType) { ParameterizedType aType = (ParameterizedType) genericFieldType; Type[] fieldArgTypes = aType.getActualTypeArguments(); if (index >= fieldArgTypes.length || index < 0) { throw new RuntimeException("你输入的索引" + (index < 0 ? "不能小于0" : "超出了参数的总数")); } return (Class) fieldArgTypes[index]; } return Object.class; } /** * 通过反射,获得Field泛型参数的实际类型. 如: public Map
names; * * @param Field * field 字段 * @param int index 泛型参数所在索引,从0开始. * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回 *
Object.class */ @SuppressWarnings("unchecked") public static Class getFieldGenericType(Field field) { return getFieldGenericType(field, 0); } /** * 根据实体得到实体的所有属性 * @param objClass * @return * @throws ClassNotFoundException */ public static String[] getColumnNames(String objClass) throws ClassNotFoundException { String[] wageStrArray = null; if (objClass != null) { Class class1 = Class.forName(objClass); Field[] field = class1.getDeclaredFields();// 这里便是获得实体Bean中所有属性的方法 StringBuffer sb = new StringBuffer(); for (int i = 0; i < field.length; i++) {// 这里不多说了 sb.append(field[i].getName()); // 这是分割符 是为了去掉最后那个逗号 // 比如 如果不去最后那个逗号 最后打印出来的结果是 "id,name," // 去了以后打印出来的是 "id,name" if (i < field.length - 1) { sb.append(","); } } // split(",");这是根据逗号来切割字符串使字符串变成一个数组 wageStrArray = sb.toString().split(","); return wageStrArray; } else { return wageStrArray; } } public static Object[] field2Value(Field[] f, Object o) throws Exception { Object[] value = new Object[f.length]; for (int i = 0; i < f.length; i++) { value[i] = f[i].get(o); } return value; } /** * returns the current http session object * * @return session */ public HttpSession getSession() { HttpSession session=null; ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); HttpSession contextSess = attr == null ? session : attr.getRequest().getSession(true); return contextSess; } /** * 得到实体类 * @param objClass 实体类包含包名 * @return */ public static Class getEntityClass(String objClass){ Class entityClass = null; try { entityClass = Class.forName(objClass); } catch (ClassNotFoundException e) { e.printStackTrace(); } return entityClass; } /** * 定义字符集 * @param * @return */ private static char[] chars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B','C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; //72个字符集 /** * * @param passLength * 随机密码长度 * @param count * 随机密码个数 * @return 随机密码数组 */ public static String getPasswords(int passLength) { String passwords = "";// 新建一个长度为指定需要密码个数的字符串数组 Random random = new Random(); StringBuilder password = new StringBuilder("");// 保存生成密码的变量 for (int m = 1; m <= passLength; m++) {// 内循环 从1开始到密码长度 正式开始生成密码 password.append(chars[random.nextInt(62)]);// 为密码变量随机增加上面字符中的一个 } passwords = password.toString();// 将生成出来的密码赋值给密码数组 return passwords; } }

3、BaseService接口,为什么这层要选择接口来实现呢?有很多需要前后分离的应用,暴露的服务就是接口暴露Service层,所以采用接口。

import java.io.Serializable;  import java.lang.reflect.InvocationTargetException;  import java.util.List;    @SuppressWarnings("hiding")  public interface BaseService
{ public int insert(T record); public int insertSelective(T record); public T selectByPrimaryKey(String id); public int updateByPrimaryKey(T record); public int updateByPrimaryKeySelective(T record); public int deleteByPrimaryKey(String id); public List
findTop(int top, String statementKey, Object parameter) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException; public T findTopOne(String statementKey, Object parameter) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException; }

4、BaseService接口的实现类BaseServiceImpl,需要注入BaseDao(其中必须对BaseDao进行set,否则无法获取具体泛型)

import java.io.Serializable;  import java.lang.reflect.InvocationTargetException;  import java.util.List;    import org.springframework.beans.factory.annotation.Autowired;    import com.alibaba.dubbo.config.annotation.Service;  import com.ivan.api.base.BaseService;  import com.ivan.base.BaseDao;    @Service  public abstract class BaseServiceImpl
implements BaseService
{ @Autowired private BaseDao
baseDao; public BaseDao
getBaseDao() { return baseDao; } public void setBaseDao(BaseDao
baseDao) { this.baseDao = baseDao; } public int insert(T entity) { return baseDao.insert(entity); } public int insertSelective(T record) { return baseDao.insertSelective(record); } public T selectByPrimaryKey(String id) { return baseDao.selectByPrimaryKey(id); } public int updateByPrimaryKey(T record) { return baseDao.updateByPrimaryKey(record); } public int updateByPrimaryKeySelective(T record) { return baseDao.updateByPrimaryKeySelective(record); } public int deleteByPrimaryKey(String id) { return baseDao.deleteByPrimaryKey(id); } public List
findTop(int top, String statementKey, Object parameter) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { return baseDao.findTop(top, statementKey, parameter); } public T findTopOne(String statementKey, Object parameter) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { return baseDao.findTopOne(statementKey, parameter); } }

5、Mapper.xml文件的定义,需要注意的是namespace的命名,会通过这个命名找到具体的mapper文件,进行数据的操作。

id, name, age
delete from user where id = #{id,jdbcType=INTEGER}
insert into user (id, name, age ) values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER} )
insert into user
id,
name,
age,
#{id,jdbcType=VARCHAR},
#{name,jdbcType=VARCHAR},
#{age,jdbcType=INTEGER},
update user
name = #{name,jdbcType=VARCHAR},
age = #{age,jdbcType=INTEGER},
where id = #{id,jdbcType=VARCHAR}
update user set name = #{name,jdbcType=VARCHAR}, age = #{age,jdbcType=INTEGER} where id = #{id,jdbcType=VARCHAR}

6、具体的使用方法:

a、定义UserDao:

@Repository("userDao")  public class UserDao extends BaseDao
{ /** * */ private static final long serialVersionUID = 9152785684346322571L; }

b、定义UserService接口

public interface UserService extends BaseService
{ }

c、实现UserService接口

@Service  public class UserServiceImpl extends BaseServiceImpl
implements UserService{ }

d、调用UserService接口

@Controller  @RequestMapping("/user")  public class UserController {            @SuppressWarnings("unused")      private static final Logger logger = LoggerFactory.getLogger(UserController.class);            @Reference      private UserService userService;  }

 

转载于:https://my.oschina.net/gaoenwei/blog/1811003

你可能感兴趣的文章
编写高性能的java程序
查看>>
Spring 的配置详解
查看>>
linux已经不存在惊群现象
查看>>
上位机和底层逻辑的解耦
查看>>
关于微信二次分享 配置标题 描述 图片??
查看>>
springcloud使用zookeeper作为config的配置中心
查看>>
校园火灾Focue-2---》洗手间的一套-》电梯
查看>>
css控制文字换行
查看>>
bzoj1913
查看>>
L104
查看>>
分镜头脚本
查看>>
链表基本操作的实现(转)
查看>>
邮件发送1
查看>>
[转] libcurl异步方式使用总结(附流程图)
查看>>
编译安装LNMP
查看>>
[转]基于display:table的CSS布局
查看>>
crm 02--->讲师页面及逻辑
查看>>
AS3.0 Bitmap类实现图片3D旋转效果
查看>>
Eigen ,MKL和 matlab 矩阵乘法速度比较
查看>>
带三角的面包屑导航栏(新增递增数字)
查看>>