java生成统一的增删改函数

原创
2018/08/27 11:27
阅读数 9

现在的一些Java开发平台,都自带代码生成器,省去对每个POJO对象,都写一遍增删改查的工作。但是,对于类型比较简单的POJO对象,可以生成统一的增删改函数,减少代码量。

首先,要定义表和字段注解,供生成相关SQL使用,table注解:

package com.tiger.testApp.anno;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyTable {
	//表名
	String name() default "";
}

column注解:

package com.tiger.testApp.anno;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyColumn {

	//字段中文名
	String name() default "";
	//字段备注
	String memo() default "";
	//字段长度
	int length() default 1;
	//是否必须
	boolean isRequire() default true;
	//是否扩展字段(不在数据库表中)
	boolean isExtend() default false;
	//是否主键
	boolean isPk() default false;
}

定义一个“公司”的POJO,作为例子使用:

package com.tiger.testApp.pojo;

import java.io.Serializable;
import java.util.Date;

import com.tiger.testApp.anno.MyColumn;
import com.tiger.testApp.anno.MyTable;

@MyTable(name="t_test")
public class Company implements Serializable{
	
	private static final long serialVersionUID = -2249450432413118162L;
	
	@MyColumn(isPk=true,name="公司唯一标识")
	private String companyId;
	
	private String companyName;
	
	private String companyCode;
	
	private Integer companyType;
	
	private Date registorDate;
	
	@MyColumn(isExtend=true)
	private String testColumn;
	
	public Company() {}

	public String getCompanyName() {
		return companyName;
	}

	public void setCompanyName(String companyName) {
		this.companyName = companyName;
	}

	public String getCompanyCode() {
		return companyCode;
	}

	public void setCompanyCode(String companyCode) {
		this.companyCode = companyCode;
	}

	public Integer getCompanyType() {
		return companyType;
	}

	public void setCompanyType(Integer companyType) {
		this.companyType = companyType;
	}

	public Date getRegistorDate() {
		return registorDate;
	}

	public void setRegistorDate(Date registorDate) {
		this.registorDate = registorDate;
	}

	public String getTestColumn() {
		return testColumn;
	}

	public void setTestColumn(String testColumn) {
		this.testColumn = testColumn;
	}

	public String getCompanyId() {
		return companyId;
	}

	public void setCompanyId(String companyId) {
		this.companyId = companyId;
	}

}

一、生成统一保存方法:

保存方法请求地址:

 /**
	     * 保存公司信息信息
	     */
	    @RequestMapping(value="/add",method=RequestMethod.POST)
	    public int add(@RequestBody Company c, HttpServletRequest req) {

我们要做的是,根据这两个参数生成保存需要的sql语句:

 /**根据实体map生成sql
	     * @param map       接收的实体对象
	     * @param tableName 表名
	     * @return
	     */
	    private String getInsertSQL(Map<String,Object> map,  String tableName) {
	    	if(map == null || map.keySet().size()<1) {
	    		return null;
	    	}
	    	StringBuffer sb  = new StringBuffer("insert into " + tableName + "(");
	    	StringBuffer cols = new StringBuffer("");
	    	StringBuffer vals = new StringBuffer("");
	    	for(String key: map.keySet()) {
	    		cols.append("," + getColumnName(key));
	    		vals.append(",'" + map.get(key) + "'");
	    	}
	    	sb.append(cols.toString().substring(1))
	    	.append(") values (")
	    	.append(vals.toString().substring(1))
	    	.append(")");
	    	return sb.toString();
	    }

其中,tableName通过company类的Mytable注解的name获取;getColumnName是把实体属性改成数据库列名,也可以通过Column注解直接获取:

 /**
	     * 实体属性转为数据库表的列名
	     * @param key 源字符串
	     * @return 转换后的字符串
	     */
	    public static String getColumnName(String key){
		     if(key==null||"".equals(key)){
		    	 return "";
		     }
		     key=String.valueOf(key.charAt(0)).toUpperCase().concat(key.substring(1));
		     StringBuffer sb=new StringBuffer();
		     Pattern pattern=Pattern.compile("[A-Z]([a-z\\d]+)?");
		     Matcher matcher=pattern.matcher(key);
		     while(matcher.find()){
		      String word=matcher.group();
		      sb.append(word.toUpperCase());
		      sb.append(matcher.end()==key.length()?"":"_");
		     }
		     return sb.toString();
	    }

最后得到的SQL语句为:

insert into t_test(COMPANY_TYPE,COMPANY_NAME,TEST_COLUMN) values ('2','联研院','程序员')

二、生成统一更新方法:

 /**根据实体map生成更新sql
	     * @param map		实体参数
	     * @param tableName 表名
	     * @return
	     */
	    private String getUpdateSQL(Map<String,Object> map, Object obj) {
	    	if(map == null || map.keySet().size()<1) {
	    		return null;
	    	}
	    	List<String> pkList = getPks(obj);
	    	if(pkList == null || pkList.size()<1) {
	    		System.out.println("对象没有主键信息,无法更新");
	    		return null;
	    	}
	    	StringBuffer sb  = new StringBuffer(" update " + getTableName(obj.getClass()) + " set ";
	    	StringBuffer cols = new StringBuffer("");
	    	for(String key: map.keySet()) {
	    		cols.append("," + getColumnName(key) + "=" + "'" + map.get(key) + "'");
	    	}
	    	sb.append(cols.toString().substring(1)).append(" where ");
	    	for(String pk : pkList) {
	    		 sb.append(pk).append("=").append("'" + map.get(pk) + "'");
	    	}
	    	return sb.toString();
	    }

其中,getPks为获取表的主键:

 /**获取实体对象的主键
	     * @param obj
	     * @return
	     */
	    private List<String> getPks(Object obj){
	    	List<String> list = new ArrayList<String>();
	    	 Field[] fields = obj.getClass().getDeclaredFields();
			 for(Field f : fields){
				   try {
					 if("serialVersionUID".equals(f.getName())) {
						 continue;
					 }
					 MyColumn myc = (MyColumn) f.getDeclaredAnnotation(MyColumn.class);
					 if(myc == null) {
						 continue;
					 }
					 if(myc.isPk()) {
						 list.add(f.getName());
					 }
				   } catch (IllegalArgumentException e) {
				     e.printStackTrace();
				    } catch (Exception e) {
				     e.printStackTrace();
				    }
			 }
	    	return list;
	    }

生成的更新SQL语句:

update t_test set COMPANY_ID='113',COMPANY_TYPE='2',COMPANY_NAME='联研院',TEST_COLUMN='程序员' where companyId='113'

三、生成统一的删除函数:

这个更简单,就不上源码了,生成的SQL为:

delete from t_test where companyId='113'

这样的话,有再多的POJO,增删改只需要这三个函数,节省了大量的代码。对于复杂的POJO,或者增删改功能中需要其他逻辑的,还是需要自己单独写逻辑的,用代码生成器估计也得自己补充一些逻辑代码吧。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部