EP框架之ORM
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为主,结合自身封装的注解和接口进行辅助开发,并没有太多干预开源框架本身的职责,这里并不想重新造轮子,达到方便快捷的目的即可。