您的位置:首页 > 其它

mybatis3通用crud的研究二

2016-03-22 14:25 417 查看
这次把代码贴全吧

首先是Mapper接口的基类

[java] view
plain copy

package org.sol.util.mybatis;

import java.util.List;

import org.apache.ibatis.annotations.DeleteProvider;

import org.apache.ibatis.annotations.InsertProvider;

import org.apache.ibatis.annotations.SelectProvider;

import org.apache.ibatis.annotations.UpdateProvider;

/**

* MyBatis CRUD基接口

* @author ALLEN.HU

*

* @param <T> 处理的POJO对象

*/

public interface BaseMapper<T extends MyBatisPojo> {

/**

* 基于泛型的SELECT的返回类型,无法达到运行时改变对象签名

* 目前无解

* @param obj

* @return

*/

public List<T> select(T obj);

public List<T> selectByPage(T obj);

//@SelectProvider(type = SelectTemplate.class,method = "count")

//public int count(T obj);

/**

* Insert语句从CUDTemplate类中生成

* @param obj

*/

@InsertProvider(type = CUDTemplate.class,method = "insert")

public void insert(T obj);

/**

* Update语句从CUDTemplate类中生成

* @param obj

*/

@UpdateProvider(type = CUDTemplate.class,method = "update")

public void update(T obj);

/**

* Delete语句从CUDTemplate类中生成

* @param obj

*/

@DeleteProvider(type = CUDTemplate.class,method = "delete")

public void delete(T obj);

}

然后是POJO的基类

[java] view
plain copy

package org.sol.util.mybatis;

import java.io.Serializable;

import java.lang.reflect.Field;

import java.lang.reflect.Modifier;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import javax.persistence.Column;

import javax.persistence.Id;

import javax.persistence.Table;

import org.json.JSONObject;

import org.sol.util.mybatis.exception.PojoStructureException;

/**

* MyBatis用POJO基类

* @author Allen.Hu

*

*/

public class MyBatisPojo implements Serializable{

private static final long serialVersionUID = 1L;

/**

* 获取POJO对应的表名

* 需要POJO中的属性定义@Table(name)

* @return

*/

public String tablename() {

Table table = this.getClass().getAnnotation(Table.class);

if(table != null)

return table.name();

else

throw new PojoStructureException("undefine POJO @Table, need Tablename(@Table(name))");

}

/**

* 获取POJO中的主键字段名

* 需要定义@Id

* @return

*/

public String id() {

for(Field field : this.getClass().getDeclaredFields()) {

if(field.isAnnotationPresent(Id.class))

return field.getName();

}

throw new RuntimeException("undefine POJO @Id");

}

/**

* 用于存放POJO的列信息

*/

private transient static Map<Class<? extends MyBatisPojo>,List<String>> columnMap = new HashMap<Class<? extends MyBatisPojo>, List<String>>();

private boolean isNull(String fieldname) {

try {

Field field = this.getClass().getDeclaredField(fieldname);

return isNull(field);

} catch (SecurityException e) {

e.printStackTrace();

} catch (NoSuchFieldException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

}

return false;

}

private boolean isNull(Field field) {

try {

field.setAccessible(true);

return field.get(this) == null;

} catch (SecurityException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

return false;

}

/**

* 用于计算类定义

* 需要POJO中的属性定义@Column(name)

*/

public void caculationColumnList() {

if(columnMap.containsKey(this.getClass()))

return;

Field[] fields = this.getClass().getDeclaredFields();

List<String> columnList = new ArrayList<String>(fields.length);

for(Field field : fields) {

if(field.isAnnotationPresent(Column.class))

columnList.add(field.getName());

}

columnMap.put(this.getClass(), columnList);

}

/**

* 获取用于WHERE的 有值字段表

* @return

*/

public List<WhereColumn> returnWhereColumnsName() {

Field[] fields = this.getClass().getDeclaredFields();

List<WhereColumn> columnList = new ArrayList<WhereColumn>(fields.length);

for(Field field : fields) {

if(field.isAnnotationPresent(Column.class) && !isNull(field))

columnList.add(new WhereColumn(field.getName(), field.getGenericType().equals(String.class)));

}

return columnList;

}

/**

* Where条件信息

* @author HUYAO

*

*/

public class WhereColumn {

public String name;

public boolean isString;

public WhereColumn(String name,boolean isString) {

this.name = name;

this.isString = isString;

}

}

/**

* 用于获取Insert的字段累加

* @return

*/

public String returnInsertColumnsName() {

StringBuilder sb = new StringBuilder();

List<String> list = columnMap.get(this.getClass());

int i = 0;

for(String column : list) {

if(isNull(column))

continue;

if(i++ != 0)

sb.append(',');

sb.append(column);

}

return sb.toString();

}

/**

* 用于获取Insert的字段映射累加

* @return

*/

public String returnInsertColumnsDefine() {

StringBuilder sb = new StringBuilder();

List<String> list = columnMap.get(this.getClass());

int i = 0;

for(String column : list) {

if(isNull(column))

continue;

if(i++ != 0)

sb.append(',');

sb.append("#{").append(column).append('}');

}

return sb.toString();

}

/**

* 用于获取Update Set的字段累加

* @return

*/

public String returnUpdateSet() {

StringBuilder sb = new StringBuilder();

List<String> list = columnMap.get(this.getClass());

int i = 0;

for(String column : list) {

if(isNull(column))

continue;

if(i++ != 0)

sb.append(',');

sb.append(column).append("=#{").append(column).append('}');

}

return sb.toString();

}

public Integer getId(){return 0;}

/**

* 转化POJO为JSON格式

* 需要org.json包支持,可以在json官网下载源码,或自己实现json编码

* @return

*/

public String toJSONString() {

JSONObject json = new JSONObject(this);

return json.toString();

}

/**

* 打印类字段信息

*/

@Override

public String toString() {

Field[] fields = this.getClass().getDeclaredFields();

StringBuilder sb = new StringBuilder();

sb.append('[');

for(Field f : fields) {

if(Modifier.isStatic(f.getModifiers()) || Modifier.isFinal(f.getModifiers()))

continue;

Object value = null;

try {

f.setAccessible(true);

value = f.get(this);

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

if(value != null)

sb.append(f.getName()).append('=').append(value).append(',');

}

sb.append(']');

return sb.toString();

}

/**

* 以下为一些分页信息,如不需要可以删除

*/

private int page;

private int pageSize;

public int getPage() {

return page;

}

public void setPage(int page) {

this.page = page;

}

public int getPageSize() {

return pageSize;

}

public void setPageSize(int pageSize) {

this.pageSize = pageSize;

}

}

其中用到的Exception定义

[java] view
plain copy

package org.sol.util.mybatis.exception;

public class PojoStructureException extends RuntimeException{

private static final long serialVersionUID = 1L;

public PojoStructureException(String msg) {

super(msg);

}

public PojoStructureException(String msg,Throwable e) {

super(msg,e);

}

}

最后是用于构建SQL的模板

[java] view
plain copy

package org.sol.util.mybatis;

import static org.apache.ibatis.jdbc.SqlBuilder.*;

public class CUDTemplate<T extends MyBatisPojo> {

public String insert(T obj) {

BEGIN();

INSERT_INTO(obj.tablename());

obj.caculationColumnList();

VALUES(obj.returnInsertColumnsName(), obj.returnInsertColumnsDefine());

return SQL();

}

public String update(T obj) {

String idname = obj.id();

BEGIN();

UPDATE(obj.tablename());

obj.caculationColumnList();

SET(obj.returnUpdateSet());

WHERE(idname + "=#{" + idname + "}");

return SQL();

}

public String delete(T obj) {

String idname = obj.id();

BEGIN();

DELETE_FROM(obj.tablename());

WHERE(idname + "=#{" + idname + "}");

return SQL();

}

}

实际使用时,只需要构建一个继承MyBatisPOJO的实体对象,和一个继承BaseMapper的映射器就可以了

例子:

[java] view
plain copy

import javax.persistence.Column;

import javax.persistence.Id;

import javax.persistence.Table;

import org.sol.util.mybatis.MyBatisPojo;

@Table(name = "testTable")

public class TestTable extends MyBatisPojo{

private static final long serialVersionUID = 1L;

// 一个很简单的示例表,仅有2列,主键列id,和一个Varchar列name

// 以@Id标识的字段,表示这个字段是主键

@Id

private Integer id;

// 以@Column标识的字段,表示这个字段是一般列

@Column

private String name;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

}

对应的Mapper

[java] view
plain copy

// 只需要继承BaseMapper,就可以直接实现根据主键的Update,Insert,Delete操作

// 如果需要其他附加动作,也可以增加xml文件,完全没有冲突

public interface InfoShopMapper extends BaseMapper<TestTable>{

}

其他操作与MyBatis原始操作一样

另外,希望有高人能提供生成通用Select的办法

转载:http://blog.csdn.net/beiouwolf/article/details/7347797
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: