mybatis

The MyBatis SQL mapper framework makes it easier to use a relational database with object-oriented applications. MyBatis couples objects with stored procedures or SQL statements using a XML descriptor or annotations. Simplicity is the biggest advantage of the MyBatis data mapper over object relational mapping tools.

License

License

Categories

Categories

MyBatis Data ORM
GroupId

GroupId

com.github.huangzhouhong
ArtifactId

ArtifactId

mybatis
Last Version

Last Version

0.0.2
Release Date

Release Date

Type

Type

jar
Description

Description

mybatis
The MyBatis SQL mapper framework makes it easier to use a relational database with object-oriented applications. MyBatis couples objects with stored procedures or SQL statements using a XML descriptor or annotations. Simplicity is the biggest advantage of the MyBatis data mapper over object relational mapping tools.
Project URL

Project URL

http://www.mybatis.org/mybatis-3
Project Organization

Project Organization

MyBatis.org
Source Code Management

Source Code Management

http://github.com/huangzhouhong/mybatis-3

Download mybatis

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.huangzhouhong/mybatis/ -->
<dependency>
    <groupId>com.github.huangzhouhong</groupId>
    <artifactId>mybatis</artifactId>
    <version>0.0.2</version>
</dependency>
// https://jarcasting.com/artifacts/com.github.huangzhouhong/mybatis/
implementation 'com.github.huangzhouhong:mybatis:0.0.2'
// https://jarcasting.com/artifacts/com.github.huangzhouhong/mybatis/
implementation ("com.github.huangzhouhong:mybatis:0.0.2")
'com.github.huangzhouhong:mybatis:jar:0.0.2'
<dependency org="com.github.huangzhouhong" name="mybatis" rev="0.0.2">
  <artifact name="mybatis" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.github.huangzhouhong', module='mybatis', version='0.0.2')
)
libraryDependencies += "com.github.huangzhouhong" % "mybatis" % "0.0.2"
[com.github.huangzhouhong/mybatis "0.0.2"]

Dependencies

compile (10)

Group / Artifact Type Version
org.antlr : antlr4-runtime jar 4.7.2
org.antlr : antlr4 jar 4.7.2
ognl : ognl Optional jar 3.2.10
org.javassist : javassist Optional jar 3.24.1-GA
org.slf4j : slf4j-api Optional jar 1.7.26
org.slf4j : slf4j-log4j12 Optional jar 1.7.26
log4j : log4j Optional jar 1.2.17
org.apache.logging.log4j : log4j-core Optional jar 2.11.2
commons-logging : commons-logging Optional jar 1.2
cglib : cglib Optional jar 3.2.10

test (15)

Group / Artifact Type Version
org.junit.jupiter : junit-jupiter-engine jar 5.5.0
org.hsqldb : hsqldb jar 2.4.1
org.apache.derby : derby jar 10.14.2.0
org.mockito : mockito-core jar 2.25.1
org.mockito : mockito-junit-jupiter jar 2.25.1
org.apache.commons : commons-dbcp2 jar 2.6.0
javax.transaction : javax.transaction-api jar 1.3
org.apache.velocity : velocity-engine-core jar 2.0
org.postgresql : postgresql jar 42.2.5
mysql : mysql-connector-java jar 8.0.17
org.assertj : assertj-core jar 3.12.2
eu.codearte.catch-exception : catch-exception jar 1.4.6
org.testcontainers : junit-jupiter jar 1.12.1
org.testcontainers : postgresql jar 1.12.1
org.testcontainers : mysql jar 1.12.1

Project Modules

There are no modules declared in this project.

mybatis拼接SQL的语法较为复杂。为此我实现了一个SQL解析器,能根据变量的上下文,推断如何拼接SQL,避免使用if,trim,where, set,foreach等标签。以下介绍基本的用法。

准备

<dependency>
	<groupId>com.github.huangzhouhong</groupId>
	<artifactId>mybatis</artifactId>
	<version>0.0.2</version>
</dependency>

替换

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.3</version>
</dependency>

1.

	@Sql("select * from blog where state='ACTIVE' and title=#?{title}")
	List<Blog> findActiveBlogWithTitleLike(String title);

#?{}表示参数是可选的,#{}则是必选的。可选参数为null时会根据上下文自动删除。为了保证原有功能不受影响,新增了@Sql注解。 上述相当于:

<select id="findActiveBlogWithTitleLike"
     resultType="Blog">
  SELECT * FROM BLOG
  WHERE state = ‘ACTIVE’
  <if test="title != null">
    AND title like #{title}
  </if>
</select>

2.

接口声明

List<Blog> findBlogLike(String state, String title, Author author);

xml

	<sql id="findBlogLike">
		SELECT * FROM BLOG
		WHERE state = #?{state} AND title like #?{title}
		AND author_name like #?{author.userName}
	</sql>

相当于:

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG
  <where>
    <if test="state != null">
         state = #{state}
    </if>
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>

当某一参数为空,框架能自动删除字符串且处理好andor和逗号等等,所有参数为空(且都为可选)时能自动删除where。总而言之,解析器从上下文推测该如何处理字符串。

3.

	<sql id="updateAuthorIfNecessary">
		update Author set
			user_name=#?{username},
			password=#?{password},
			email=#?{email},
			mobile=#?{mobile}
		where author_id=#{authorId}
	</sql>

同样,不用担心逗号处理的问题,相当于

<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="mobile!= null">mobile=#{mobile}</if>
    </set>
  where author_id=#{author_id}
</update>

4.

接口

	List<Post> selectPostIn(List<Integer> ids);
	<sql id="selectPostIn">
		SELECT *
		FROM POST P
		WHERE post_id in (#{ids})
	</sql>

相当于

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE post_id in
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>
</select>
  1. 解析器会自动判断传到IN子句中的变量是不是集合,如果是集合,则会把它展开成多个变量。
  2. 假设方法签名改成selectPostIn(List<BlogPost> blogPosts);,且要查找所有BlogPost.post_id,可以写成
	<sql id="selectPostIn">
		SELECT *
		FROM POST P
		WHERE post_id in (#{post_id})
	</sql>

也可以写成#{blogPosts.post_id}或者#{list.post_id}。相当于

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE post_id in
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item.post_id}
  </foreach>
</select>

5. insert

接口

	@Sql("insert into blog (blog_id,title) values (#{blogId},#{title})")
	int insert(Blog... blogs);

可以插入一个实体也可以批量插入,用例:

blogMapper.insert(blog1);
blogMapper.insert(blog1,blog2);
blogMapper.insert(blogs);

这里接口只有一个参数,所以#{blogId}#{title}没有歧义。如果有多个参数,可以使用#{blogs.blogId}

6. 替换掉script标签

以往,要在带注解的映射器接口类中使用动态 SQL,可以使用 script 元素。比如:

    @Update({"<script>",
      "update Author",
      "  <set>",
      "    <if test='username != null'>username=#{username},</if>",
      "    <if test='password != null'>password=#{password},</if>",
      "    <if test='email != null'>email=#{email},</if>",
      "    <if test='bio != null'>bio=#{bio}</if>",
      "  </set>",
      "where id=#{id}",
      "</script>"})
    void updateAuthorValues(Author author);

可以写成:

    @Sql({"update Author",
      "set username=#{username},",
      "password=#{password},",
      "email=#{email},",
      "bio=#{bio}",
      "where id=#{id}"})
    void updateAuthorValues(Author author);

总结

  1. 设计目标是框架能理解SQL,并根据上下文能处理变量。
  2. 原有注解不受影响,功能也不变。如果要使用上述功能,只需使用@Sql<sql>,现有项目迁移过来不需要做任何修改。
  3. 本文源码:https://github.com/huangzhouhong/mybatis-demo

讨论群

1044263035

Versions

Version
0.0.2
0.0.1