EP框架之ORM

  |   0 评论   |   0 浏览

  ORM是一个开发框架最基础也是最重要的部分,EP框架目前是采用MyBatis作为基础ORM框架,上层再封装了一层注解,加上一个基础的操作接口封装io.github.junxworks.ep.core.orm.BaseMapper,主要目的还是辅助开发人员进行开发,少编写重复性sql,但是复杂sql还是需要借助Mybatis来进行编写。EP框架提供了一个eclipse插件(https://e.coding.net/hy_wangxing/junxworks/io.github.junxworks.tools.git),用于生成Entity实体类。生成的实体类如下所示:

package io.github.junxworks.ep.demo.modules.table.entity;

import io.github.junxworks.ep.core.orm.annotations.Table;
import io.github.junxworks.ep.core.orm.annotations.PrimaryKey;
import io.github.junxworks.ep.core.orm.annotations.Column;
import java.util.Date;

/**
 * <p>Entity Class</p>
 * <p>Table: d_student</p>
 *
 * @since 2021-3-29 20:35:22 Generated by JunxPlugin
 */

@Table(tableName = "d_student", tableComment = "")
public class DStudent {

	@PrimaryKey
	@Column(name = "id", type = "BIGINT", length = "19", nullable = "false", comment = "编号")
	private Long id;

	@Column(name = "student_name", type = "VARCHAR", length = "20", nullable = "true", comment = "姓名")
	private String studentName;

	@Column(name = "student_no", type = "VARCHAR", length = "20", nullable = "true", comment = "学号")
	private String studentNo;

	@Column(name = "birthday", type = "TIMESTAMP", length = "19", nullable = "true", comment = "生日")
	private Date birthday;

	public Long getId() {
		return this.id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getStudentName() {
		return this.studentName;
	}

	public void setStudentName(String studentName) {
		this.studentName = studentName;
	}

	public String getStudentNo() {
		return studentNo;
	}

	public void setStudentNo(String studentNo) {
		this.studentNo = studentNo;
	}

	public Date getBirthday() {
		return this.birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
}

  实体这块用到了3个注解,@Table注解,通过这个注解,在解析sql的时候可以解析到表名,@PrimaryKey通过这个注解,标识唯一主键,在DB规范中,每个表都必须有一个唯一的主键。@Column就是对数据库每一个列名的映射,映射了一些列属性,常用的属性,但是EP框架本身只用到了列名,其他属性并没有用到,这里仅做提示作用。在EP框架中写Mapper是比较方便的,直接写一个mapper接口,继承BaseMapper,就能拥有BaseMapper所有的接口功能。

package io.github.junxworks.ep.demo.modules.table.mapper;

import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import io.github.junxworks.ep.core.orm.BaseMapper;
import io.github.junxworks.ep.demo.modules.table.dto.StudentConditionDto;
import io.github.junxworks.ep.demo.modules.table.vo.StudentVo;

@Mapper
public interface TableDemoMapper extends BaseMapper {

	/**
	 * Query student by id.
	 *
	 * @param id the id
	 * @return the student vo
	 */
	@Select("select * from d_student where id=#{id}")
	StudentVo queryStudentById(Long id);

	/**
	 * Query student list by condition.
	 *
	 * @param condition the condition
	 * @return the list
	 */
	List<StudentVo> queryStudentListByCondition(StudentConditionDto condition);
}

  如上面的Mapper所示,继承了BaseMapper过后,就拥有了BaseMapper的功能接口,BaseMapper有种Mybatis-Plus的感觉,但是设计BaseMapper的时候还没有用过Mybatis-plus,后面才知道有那个Mybatis功能增强框架,但是涉及BaseMapper的时候没有想实现Mybatis-plus那么复杂的功能,只辅助开发人员少写代码,仅此而已。BaseMapper设计得相对比较灵活,并没有用泛型把实体限制死,SQL是根据传入的对象类现解析而来,因此在用的时候也会少些很多代码。下面看看BaseMapper的接口方法:

package io.github.junxworks.ep.core.orm;

import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;

public interface BaseMapper {

	/**
	 * Insert without null.
	 *
	 * @param entity the entity
	 * @return the int
	 */
	@InsertProvider(type = MybatisObjectSqlProvider.class, method = "insertWithoutNull")
	@Options(useGeneratedKeys = true, keyProperty = "id")
	public int insertWithoutNull(Object entity);

	/**
	 * Insert batch.
	 *
	 * @param entities the entities
	 * @return the int
	 */
	@InsertProvider(type = MybatisObjectSqlProvider.class, method = "insertBatch")
	public int insertBatch(List<?> entities);

	/**
	 * Insert with null.
	 *
	 * @param entity the entity
	 * @return the int
	 */
	@InsertProvider(type = MybatisObjectSqlProvider.class, method = "insertWithNull")
	@Options(useGeneratedKeys = true, keyProperty = "id")
	public int insertWithNull(Object entity);

	/**
	 * Update without null.
	 *
	 * @param entity the entity
	 * @return the int
	 */
	@UpdateProvider(type = MybatisObjectSqlProvider.class, method = "updateWithoutNull")
	public int updateWithoutNull(Object entity);

	/**
	 * Update with null.
	 *
	 * @param entity the entity
	 * @return the int
	 */
	@UpdateProvider(type = MybatisObjectSqlProvider.class, method = "updateWithNull")
	public int updateWithNull(Object entity);

	/**
	 * Delete by PK.
	 *
	 * @param entity the entity
	 * @return the int
	 */
	@DeleteProvider(type = MybatisObjectSqlProvider.class, method = "deleteByPK")
	public int deleteByPK(Object entity);

	/**
	 * Delete by PK.
	 *
	 * @param <T> the generic type
	 * @param entity the entity
	 * @param id the id
	 * @return the int
	 */
	@DeleteProvider(type = MybatisObjectSqlProvider.class, method = "deleteByID")
	public int deleteOneById(@Param("class")Class entity, @Param("id") Long id);

	/**
	 * 返回 one by PK 属性.
	 *
	 * @param <T> the generic type
	 * @param entity the entity
	 * @param id the id
	 * @return one by PK 属性
	 */
	@SelectProvider(type = MybatisObjectSqlProvider.class, method = "getOneByPK")
	public Map<String,Object> selectMapByID(@Param("class")Class entity, @Param("id") Long id);

	/**
	 * 指定pkName获取实体
	 *
	 * @param <T> the generic type
	 * @param entity the entity
	 * @param pkName the pk name
	 * @param id the id
	 * @return one by PK 属性
	 */
	@SelectProvider(type = MybatisObjectSqlProvider.class, method = "getOneByPKNameAndValue")
	public Map<String,Object> selectMapByPKNameAndValue(@Param("class")Class entity,  @Param("pkName")String pkName, @Param("id") Long id);
}

  都是一些比较常用的方法,我觉得大部分在开发时候已经够用了,当然有一个常用方法没有,就是根据ID查询单个实体,这个方法比较常用,在EP1.0.5版本中会在新增的TBaseMapper中加上。介绍到这里,可以看到整个ORM框架还是以Mybatis为主,结合自身封装的注解和接口进行辅助开发,并没有太多干预开源框架本身的职责,这里并不想重新造轮子,达到方便快捷的目的即可。