原创

Hibernate生成SQL语句过程复现


Hibernate生成SQL语句过程复现

文件目录结构:

├── entity -- 数据库的实体类包
|    ├── ABean -- 表A对应的数据类型
|    ├── BBean -- 表B对应的数据类型
├── dao -- dao包
|    ├── impl -- 实现包
|    |    ├── BaseDaoImpl -- dao层基类
|    |    ├── ADaoImpl -- dao层A表对应的类
|    |    ├── BDaoImpl -- dao层B表对应的类
|    ├── BaseDao -- dao层基类接口
|    ├── ADao -- A类接口
|    ├── BDao -- B类接口

先创建好需要用到的bean,即ABeanBBean

/**
 * @Author: 陌攻
 * @Description: 表A对应的数据类型
 * @Date: 2021/1/6 13:16
 * @Modified By:
 */
@Entity
@Table(name="a_table")
public class ABean {
    private Long id;
    private Date createTime;
	private Date updateTime;
    @Id
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
    
    @Column(name="CREATE_TIME")
    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    
    @Column(name="UPDATE_TIME")
    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
}
/**
 * @Author: 陌攻
 * @Description: 表B对应的数据类型
 * @Date: 2021/1/6 13:16
 * @Modified By:
 */
@Entity
@Table(name="b_table")
public class BBean {
    private Long id;
    private Date createTime;
	private ABean aBean;
    @Id
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
    
    @Column(name="CREATE_TIME")
    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    
	@ManyToOne(cascade=CascadeType.MERGE,optional=true,fetch=FetchType.LAZY)
	@JoinColumn(name="id")
    public ABean getABean() {
        return aBean;
    }

    public void setABean(ABean aBean) {
        this.aBean = aBean;
    }
}

创建dao层基类接口:

/**
 * @Author: 陌攻
 * @Description: dao层基类接口
 * @Date: 2021/1/6 13:16
 * @Modified By:
 */
public interface BaseDao<T> {
    
	/**
	 * 创建对应的实体类插入语句
	 * @param obj
	 * @return
	 */
	String createInsertSQLString(T obj);
	/**
	 * 单表修改使用;;生成对应的修改语句
	 * @param obj
	 * @return
	 */
	String createUpdateSQLString(T obj);
	/**
	 * 单表删除使用;;生成对应的删除语句
	 * @param list
	 * @return
	 */
    String createDelSQLString(List<String> list);
}

实现基类接口,下面的代码中为了直观显示直接把sql语句和值拼接在一起输出。

/**
 * @Author: 陌攻
 * @Description: dao层基类,为了方便不做封装
 * @Date: 2021/1/6 13:16
 * @Modified By:
 */
public class BaseDaoImpl<T> implements BaseDao<T>{
    
	private Class<T> clazz;
    
	//单表插入使用:生成对应的插入语句
	@Override
	public String createInsertSQLString(T obj) {
        //获取类对象
		Class<?> aClass = obj.getClass();
        //获取类头部的Table注解
		Table table = aClass.getAnnotation(Table.class);
        //存放插入语句的字段名
		StringBuffer stringBuffer0 = new StringBuffer();
        //存放插入语句的插入值
		StringBuffer stringBuffer1 = new StringBuffer();
		try {
			for (int i = 0; i < aClass.getMethods().length; i++) {
				Column column = aClass.getMethods()[i].getAnnotation(Column.class);
				Id id = aClass.getMethods()[i].getAnnotation(Id.class);
				JoinColumn joinColumn = aClass.getMethods()[i].getAnnotation(JoinColumn.class);
                //判断否有@Column注解
				if (column != null && aClass.getMethods()[i].invoke(obj)!=null) {
					stringBuffer0.append(column.name());//列名
					Object col = aClass.getMethods()[i].invoke(obj);
					if(col instanceof Date){
						Date d = (Date) col;
						stringBuffer1.append("to_date('");
						stringBuffer1.append(DateUtils.getTimeStr(d));//填充值
						stringBuffer1.append("', 'yyyy-mm-dd hh24:mi:ss')");
					}else{
						stringBuffer1.append("'");
						stringBuffer1.append(col.toString());//填充值
						stringBuffer1.append("'");
					}
					stringBuffer0.append(",");
					stringBuffer1.append(",");
                    //判断否有@JoinColumn注解
				} else if (joinColumn != null && aClass.getMethods()[i].invoke(obj)!=null) {
					Object invoke = aClass.getMethods()[i].invoke(obj);
					for (int j = 0; j < invoke.getClass().getMethods().length; j++) {
						Id annotation3 = invoke.getClass().getMethods()[j].getAnnotation(Id.class);
						if (annotation3 != null) {
							stringBuffer0.append(joinColumn.name());//列名
							stringBuffer1.append("'");
							stringBuffer1.append(invoke.getClass().getMethods()[j].invoke(invoke).toString());//填充值
							stringBuffer1.append("'");

							stringBuffer0.append(",");
							stringBuffer1.append(",");
							break;
						}
					}
                    //判断否有@Id注解
				} else if (id != null) {
					String name = aClass.getMethods()[i].getName();//"getId"
					name = name.substring(3).toUpperCase();//去除"get",转换成大写
					stringBuffer0.append(name);//列名
					stringBuffer1.append("'");
					stringBuffer1.append(UUID.randomUUID().toString().replaceAll("-",""));//填充值
					stringBuffer1.append("'");

					stringBuffer0.append(",");
					stringBuffer1.append(",");
				}
			}
			stringBuffer0.deleteCharAt(stringBuffer0.length() - 1);
			stringBuffer1.deleteCharAt(stringBuffer1.length() - 1);
		}catch (Exception e){
			System.out.println(e.toString());
		}
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append(" insert into ");
		stringBuffer.append(table.name());
		stringBuffer.append(" ( ");
		stringBuffer.append(stringBuffer0);
		stringBuffer.append(" ) values ( ");
		stringBuffer.append(stringBuffer1);
		stringBuffer.append(" )");
		return stringBuffer.toString();
//		System.out.println("SQL:"+stringBuffer.toString());
	}
    
    
    
	//单表修改使用;;生成对应的修改语句
	@Override
	public String createUpdateSQLString(T obj) {
		Class<?> aClass = obj.getClass();
		Table table = aClass.getAnnotation(Table.class);
		StringBuffer stringBuffer0 = new StringBuffer();

		String name ="",idValue="";
		try {
			for (int i = 0; i < aClass.getMethods().length; i++) {
				Column column = aClass.getMethods()[i].getAnnotation(Column.class);
				Id id = aClass.getMethods()[i].getAnnotation(Id.class);
				JoinColumn joinColumn = aClass.getMethods()[i].getAnnotation(JoinColumn.class);
				if (column != null && aClass.getMethods()[i].invoke(obj)!=null) {
					stringBuffer0.append(column.name());//列名
					stringBuffer0.append("=");
					Object col = aClass.getMethods()[i].invoke(obj);
					if(col instanceof Date){
						Date d = (Date) col;
						stringBuffer0.append("to_date('");
						stringBuffer0.append(DateUtils.getTimeStr(d));//填充值
						stringBuffer0.append("', 'yyyy-mm-dd hh24:mi:ss')");
					}else{
						stringBuffer0.append("'");
						stringBuffer0.append(col.toString());//填充值
						stringBuffer0.append("'");
					}
					stringBuffer0.append(",");
				} else if (joinColumn != null && aClass.getMethods()[i].invoke(obj)!=null) {
					Object invoke = aClass.getMethods()[i].invoke(obj);
					for (int j = 0; j < invoke.getClass().getMethods().length; j++) {
						Id annotation3 = invoke.getClass().getMethods()[j].getAnnotation(Id.class);
						if (annotation3 != null) {
							stringBuffer0.append(joinColumn.name());//列名
							stringBuffer0.append("='");
							stringBuffer0.append(invoke.getClass().getMethods()[j].invoke(invoke).toString());//填充值
							stringBuffer0.append("'");

							stringBuffer0.append(",");
							break;
						}
					}
				} else if (id != null) {
					name = aClass.getMethods()[i].getName();//"getId"
					name = name.substring(3).toUpperCase();//去除"get",转换成大写
					idValue=aClass.getMethods()[i].invoke(obj).toString();//填充值
				}
			}
			stringBuffer0.deleteCharAt(stringBuffer0.length() - 1);
		}catch (Exception e){
			System.out.println(e.toString());
		}
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append(" update ");
		stringBuffer.append(table.name());
		stringBuffer.append(" set ");
		stringBuffer.append(stringBuffer0);
		stringBuffer.append(" where ");
		stringBuffer.append(name);
		stringBuffer.append(" = '");
		stringBuffer.append(idValue);
		stringBuffer.append("'");
		return stringBuffer.toString();
//		System.out.println("SQL:"+stringBuffer.toString());
	}
    
    
    
    
	//单表删除使用;;生成对应的删除语句
	@Override
	public String createDelSQLString(List<String> list) {
//		Class<?> aClass = clazz.getClass();
		Table table = clazz.getAnnotation(Table.class);
		StringBuffer stringBuffer0 = new StringBuffer();

		String name ="";
		try {
			for (int i = 0; i < clazz.getMethods().length; i++) {
				Id id = clazz.getMethods()[i].getAnnotation(Id.class);
				if (id != null) {
					name = clazz.getMethods()[i].getName();//"getId"
					name = name.substring(3).toUpperCase();//去除"get",转换成大写
				}
			}
			for (String id:list) {
				stringBuffer0.append("'");
				stringBuffer0.append(id);
				stringBuffer0.append("'");
				stringBuffer0.append(",");
			}
			stringBuffer0.deleteCharAt(stringBuffer0.length() - 1);
		}catch (Exception e){
			System.out.println(e.toString());
		}
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append(" delete from ");
		stringBuffer.append(table.name());
		stringBuffer.append(" where ");
		stringBuffer.append(name);//id
		stringBuffer.append(" in ( ");
		stringBuffer.append(stringBuffer0);
		stringBuffer.append(" )");
		return stringBuffer.toString();
//		System.out.println("SQL:"+stringBuffer.toString());
	}

}

创建dao层A表对应的接口和类:

public interface ADao extends BaseDao<ABean>{
}
@Repository("ADaoImpl")
public class ADaoImpl extends BaseDaoImpl<ABean> implements ADao {
    
}

创建dao层B表对应的接口和类:

public interface BDao extends BaseDao<BBean>{
}
@Repository("BDaoImpl")
public class BDaoImpl extends BaseDaoImpl<BBean> implements BDao {
    
}

最后在服务层调用即可生成对应的sql。

java
  • 作者:陌攻(联系作者)
  • 发表时间:2022-03-06 12:59
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 公众号转载:请在文末添加作者公众号二维码
  • 评论