前段时间了解到Spring JPA,感觉挺好用,但其依赖于Hibernate,本人看到Hibernate就头大(不是说Hibernate不好哈,而是进阶太难),于是做了一个迷你版的Mybatis JPA.
- 一.简介
- 1.1粗糙点
1.)Entity不支持实体类的嵌套;
2.)目前不支持批量操作,不支持分页查询(这个后续会有的);
3.)仅支持单表,单字段作为where条件(我目前是这样理解的,复杂的SQL还是手工构建比较好,更灵活且便于维护,一般的SQL可以使用Mybatis注解,复杂的SQL最好还是用xml构建);
- 1.2优点
1.)mybatis-jpa是基于Mybatis 和Spring增强插件,没有对依赖包(源代码)造成污染.
2.)由mybatis-jpa 解析的Mapper接口中定义的方法(method),将被注册到Mybatis Configuration中,即Mapper的代理和注入由依旧由Mybatis和Spring构建和管理,不影响原有的代码模式和工作模式.
2.)mybatis-jpa SQL的解析和Statement的注册 时机是在Spring applicationContext初始化完成时,只会解析一次,不影响性能.
- 1.3约定
1.)Entity实体类需使用@Entity注解标记,类中字段类型不允许使用基本数据类型(如:使用Integer定义整形而不是int);
2.)不支持Entity的嵌套,即实体中定义其他实体字段类型,mybatis-jpa只支持单表,其无法解析Entity的嵌套无法解析.
3.)按照Mybatis约定,Enum枚举类型默认以enum.name()解析,若要解析为enum.ordinal(),需使用注解@Enumrated(value = EnumType.ORDINAL)标识.
4.)被@MapperDefinition注解标识的Mapper接口,将会在Mybatis中注册一个domainClass.getSimpleName() + "Map"命名的ResultMap类型,且此ResultMap不能用于Mybatis的@ResultMap注解和Mapper.xml中.细说一下原因,Mybatis-jpa是与mybatis的xml加载,注解构建是分离的,举个不太恰当的例子,父容器不能读取子容器中的内容.
5.)基于4,mapper中被@StatementDefinition注解标识的方法会被mybatis-jpa解析并注册到mybatis的configuration中,其中select方法的resultMap=4中被注册的ResultMapid.关于方法的命名与解析规则,见@StatementDefinition注解。
6.)测试代码在test目录,关于设计思路与代码目录会另开博文.
- 1.4代码地址(git): https://github.com/LittleNewbie/mybatis-jpa
- 二.构建方式
- 2.1 配置文件
<!-- 在spring-mybatis配置文件中,增加以下配置即可.详见configs/spring-mybatis.xml --> <!-- Mybatis JPA Mapper 所在包路径 --> <bean class="com.mybatis.jpa.core.MapperEnhancerScaner"> <property name="basePackage" value="com.ybg.mapper" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean>
- 2.2 Entity
示例代码
@Entity /* {@Table}非必须,若无此注解,或其name="",将类名解析为下划线风格 做为表名 */ @Table(name = "user") public class User { /* 非持久化字段 */ @Transient private static final long serialVersionUID = -7788405797990662048L; /* {@Id}必须,主键标识,{@Column}非必须,若无此注解,或其name="",将字段名解析为下划线风格 做为SQL列名 */ @Id @Column(name = "user_Id") private Integer userId; @Column(name = "password_alias") private String password; /* {@Enumerated}非必须,若无此注解,按照Mybatis约定,枚举类型使用{@EnumTypeHandler}解析 */ @Enumerated @Column(name = "state") private DataStateEnum state; @Column(name = "create_Time") private java.util.Date createTime;
2.3 mapper
示例代码
@Repository @MapperDefinition(domainClass = User.class)/*entends MybatisBaseMapper非必须,它只是定义了公共的方法签名,便于风格的统一*/ public interface UserMapper extends MybatisBaseMapper<User> { /* Like 的通配符需要自行添加 */ @StatementDefinition List<User> selectByUserNameLike(String userName); @StatementDefinition List<User> selectByUserIdLessThan(Integer userId); @StatementDefinition List<User> selectByUserIdIsNull(); /*more condition or complex SQL,need yourself build*/ @Select("select * from ybg_test_user where user_name = #{userName} and dept_id = #{deptId}") @ResultMap(value="BaseResultMap") List<User> selectComplex(Map<String, Object> args); /*build with mapper.xml*/ List<User> selectComplex2(Map<String, Object> args);
集成mybatis-jpa,仅需以上3步.
如果你想深入了解,项目代码目录还算清晰,源码中有大量必要的注释,你会发现有部分英文注释,不要慌,是我写的,现在感觉有些代码用英文描述反而会简单一些,用中文反而不能够被很好的理解.
源码调试/阅读入口 com.mybatis.jpa.core.MapperEnhancerScaner -->PersistentMapperEnhancer
近期将整理代码的设计思路,欢迎交流/指正.