前段時間瞭解到Spring JPA,感覺挺好用,但其依賴於Hibernate,本人看到Hibernate就頭大(不是說Hibernate不好哈,而是進階太難),於是做了一個迷你版的Mybatis JPA. 一.簡介 1.1粗糙點 1.)Entity不支持實體類的嵌套; 2.)目前不支持批量操作,不支 ...
前段時間瞭解到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
近期將整理代碼的設計思路,歡迎交流/指正.