`
panhuan
  • 浏览: 20080 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

IBatis (MyBatis): Handling Joins: Advanced Result Mapping, Association, Collecti

 
阅读更多

Pre-Requisites

For this tutorial I am using:

IDE: Eclipse (you can use your favorite one)
DataBase: MySQL
Libs/jars: MybatisMySQL conector and JUnit (for testing)

This is how your project should look like:

Sample Database

Please run the script into your database before getting started with the project implementation. You will find the script (with dummy data) inside the sql folder.

1 – POJOs – Beans

I represented the beans here with a UML model, but you can download the complete source code in the end of this article.

The goal of this post is to demonstrate how to retrieve all the blog information from the database, but as you can see, the class Blog contains an association (Author) and a collection of Posts (and it contains a collection of Tags). And we are going to try to retrieve all this information at once.

So we are going to demonstrate One-to-one, one-to-many and many-to-many relationships using iBatis/Mybatis.

2 – Advanced Result Mapping

The result map on the code above is an advanced result mapping. As I already mentioned on previous posts, the resultMap element is the most important and powerful element in MyBatis.

MyBatis was created with one idea in mind: Databases aren’t always what you want or need them to be. While we’d love every database to be perfect 3rd normal form or BCNF, they aren’t. And it would be great if it was possible to have a single database map perfectly to all of the applications that use it, it’s not. Result Maps are the answer that MyBatis provides to this problem.

The resultMap element has a number of sub-elements and a structure worthy of some discussion. The following is a conceptual view of the resultMap element.

  • constructor – used for injecting results into the constructor of a class upon instantiation
  • id – an ID result; flagging results as ID will help improve overall performance
  • result – a normal result injected into a field or JavaBean property
  • association – a complex type association; many results will roll up into this type
  • collection – a collection of complex types
  • discriminator – uses a result value to determine which resultMap to use.

Best Practice: Always build ResultMaps incrementally. Unit tests really help out here. If you try to build a gigantic resultMap like the one above all at once, it’s likely you’ll get it wrong and it will be hard to work with. Start simple, and evolve it a step at a time. And unit test! The downside to using frameworks is that they are sometimes a bit of a black box (open source or not). Your best bet to ensure that you’re achieving the behaviour that you intend, is to write unit tests. It also helps to have them when submitting bugs.

 

Our goal is to write the following result map:

?
1
2
3
4
5
6
7
8
9
< resultMap id = "resultBlog" type = "Blog" >
     < id property = "id" column = "idBlog" />
     < result property = "name" column = "blogname" />
     < result property = "url" column = "blogurl" />
     < association property = "author" column = "idBlog" javaType = "Author"
         select = "selectAuthor" />
     < collection property = "posts" column = "idBlog" javaType = "ArrayList"
         ofType = "Post" select = "selectPosts" resultMap = "resultTag" />
</ resultMap >

But let’s take a step at the time. We are going to start retrieving only the Blog data, so our initial result map and query is going to look like this:

?
1
2
3
4
5
6
7
8
9
< resultMap id = "resultBlog" type = "Blog" >
     < id property = "id" column = "idBlog" />
     < result property = "name" column = "blogname" />
     < result property = "url" column = "blogurl" />
</ resultMap >
 
< select id = "selectBlog" resultMap = "resultBlog" >
     SELECT idBlog, name as blogname, url as blogurl FROM BLOG
</ select >

So far, so good. Let’s take another step.

Association

Now let’s also try to retrieve the Author data.

The association element deals with a “has-one ” type relationship. For example, in our example, a Blog has one Author. An association mapping works mostly like any other result. You specify the target property, the column to retrieve the value from, the javaType of the property (which MyBatis can figure out most of the time), the jdbcType if necessary and a typeHandler if you want to override the retrieval of the result values.

Where the association differs is that you need to tell MyBatis how to load the association. MyBatis can do so in two different ways:

  • Nested Select: By executing another mapped SQL statement that returns the complex type desired.
  • Nested Results: By using nested result mappings to deal with repeating subsets of joined results.

We are going to take a look at the Nested Select first.

Here is our resultMap with Author association.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
< resultMap id = "resultBlog" type = "Blog" >
     < id property = "id" column = "idBlog" />
     < result property = "name" column = "blogname" />
     < result property = "url" column = "blogurl" />
     < association property = "author" column = "idBlog" javaType = "Author"
         select = "selectAuthor" />
</ resultMap >
 
< select id = "selectBlog" resultMap = "resultBlog" >
     SELECT idBlog, name as blogname, url as blogurl FROM BLOG
</ select >
 
< select id = "selectAuthor" parameterType = "int" resultType = "Author" >
     SELECT idAuthor as id, name, email FROM AUTHOR WHERE idBlog = #{idBlog}
</ select >

Take a look at the select=”selectAuthor” atribute. This means MyBatis is going to execute the author select statment to retrieve all the authors that belong to the blog. To make the relationship between blog and author we specify the column=”idBlog” , so we can filter the authors list.

Note that we set the javaType=”Author”. We are using an Alias (remember?). This is because the columns we are retrieving from database match with Author atributes, so we do not need to specify a resultMap for author.

That’s it. We have two select statements: one to load the Blog, the other to load the Author, and the Blog’s resultMap describes that the “selectAuthor” statement should be used to load its author property.

All other properties will be loaded automatically assuming their column and property names match.

While this approach is simple, it will not perform well for large data sets or lists. This problem is knownas the “N+1 Selects Problem ”. In a nutshell, the N+1 selects problem is caused like this:

  • You execute a single SQL statement to retrieve a list of records (the “+1”).
  • For each record returned, you execute a select statement to load details for each (the “N”).

This problem could result in hundreds or thousands of SQL statements to be executed. This is notalways desirable.The upside is that MyBatis can lazy load such queries, thus you might be spared the cost of thesestatements all at once. However, if you load such a list and then immediately iterate through it toaccess the nested data, you will invoke all of the lazy loads, and thus performance could be very bad.

We are going to show how to avoid the N+1 Select Problem later.

Collection

We are retrieving Blog and Author information from database. So we have to retrieve the Post information now. And a Blog contains a list of Posts, and a Post contains a list of Tags. We are dealing with two relationships here: first one is a one-to-many (Blog-Post) and the second one is a many-to-many (Post-Tag). We are going to show you how to do it.

We are also going to use a Nested Select to retrieve Posts.

Let’s take a look at the resultMap with Post collection:

?
1
2
3
4
5
6
7
8
9
< resultMap id = "resultBlog" type = "Blog" >
     < id property = "id" column = "idBlog" />
     < result property = "name" column = "blogname" />
     < result property = "url" column = "blogurl" />
     < association property = "author" column = "idBlog" javaType = "Author"
         select = "selectAuthor" />
     < collection property = "posts" column = "idBlog" javaType = "ArrayList"
         ofType = "Post" select = "selectPosts" resultMap = "resultTag" />
</ resultMap >

The collection element works almost identically to the association. In fact, it’s so similar, to document the similarities would be redundant. So let’s focus on the differences.To continue with our example above, a Blog only had one Author. But a Blog has many Posts.

To map a set of nested results to a List like this, we use the collection element. Just like the association element, we can use a nested select, or nested results from a join.

There are a number things you’ll notice immediately, but for the most part it looks very similar to the association element we learned about above. First, you’ll notice that we’re using the collection element. Then you’ll notice that there’s a new “ofType” attribute. This attribute is necessary to distinguish between the JavaBean (or field) property type and the type that the collection contains.

To handle the Many-to-Many relationship between Post and Tag, we are also going to use a collection element, but we don’t need to use nested results for it:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
< resultMap id = "resultPosts" type = "Post" >
     < id property = "id" column = "idPost" />
     < result property = "title" column = "title" />
     < collection property = "tags" column = "idPost" javaType = "ArrayList"
         ofType = "Tag" resultMap = "resultTag" />
</ resultMap >
 
< resultMap id = "resultTag" type = "Tag" >
     < id property = "id" column = "idTag" />
     < result property = "value" column = "value" />
</ resultMap >
 
< select id = "selectPosts" parameterType = "int" resultType = "Post"
     resultMap = "resultPosts" >
     SELECT
     P.idPost as idPost, P.title as title,
     T.idTag as idTag, T.value as value
     FROM Post P
     left outer join Post_Tag PT on P.idPost = PT.idPost
     left outer join Tag T on PT.idTag = T.idTag
     WHERE P.idBlog = #{idBlog}
</ select >

And we are done! Let’s see how the Blog.xml file looks like:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<? xml version = "1.0" encoding = "UTF-8" ?>
<!DOCTYPE mapper
   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
< mapper namespace = "Blog" >
 
     < resultMap id = "resultBlog" type = "Blog" >
         < id property = "id" column = "idBlog" />
         < result property = "name" column = "blogname" />
         < result property = "url" column = "blogurl" />
         < association property = "author" column = "idBlog" javaType = "Author" select = "selectAuthor" />
         < collection property = "posts" column = "idBlog" javaType = "ArrayList" ofType = "Post"
             select = "selectPosts" resultMap = "resultTag" />
     </ resultMap >
 
     < resultMap id = "resultPosts" type = "Post" >
         < id property = "id" column = "idPost" />
         < result property = "title" column = "title" />
         < collection property = "tags" column = "idPost" javaType = "ArrayList" ofType = "Tag"
             resultMap = "resultTag" />
     </ resultMap >
 
     < resultMap id = "resultTag" type = "Tag" >
         < id property = "id" column = "idTag" />
         < result property = "value" column = "value" />
     </ resultMap >
 
     < select id = "selectBlog" resultMap = "resultBlog" >
         SELECT idBlog, name as blogname, url as blogurl FROM BLOG
     </ select >
 
    < select id = "selectAuthor" parameterType = "int" resultType = "Author" >
         SELECT idAuthor as id, name, email FROM AUTHOR WHERE idBlog = #{idBlog}
    </ select >
 
    < select id = "selectPosts" parameterType = "int" resultType = "Post" resultMap = "resultPosts" >
         SELECT
             P.idPost as idPost, P.title as title,
             T.idTag as idTag, T.value as value
         FROM Post P
             left outer join Post_Tag PT on P.idPost = PT.idPost
             left outer join Tag T on PT.idTag = T.idTag
         WHERE P.idBlog = #{idBlog}
    </ select >
 
</ mapper >

Solution to N+1 Selects Problem

As you could read above, the N+1 Selects Problem can happen while you are retrieving data.

How to solve it?

Using Nested Results : By using nested result mappings to deal with repeating subsets of joined results.

What we have to do is to write a single query to retrieve all the data (Blog + Author + Posts + Tags), and hadle the mapping in a single ResultMapping.

Very Important : id elements play a very important role in Nested Result mapping. You should alwaysspecify one or more properties that can be used to uniquely identify the results. The truth is that MyBatis will still work if you leave it out, but at a severe performance cost. Choose as few properties as possible that can uniquely identify the result. The primary key is an obvious choice (even if composite).
This is how the Blog.xml will look like is we use NestedResults:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<? xml version = "1.0" encoding = "UTF-8" ?>
<!DOCTYPE mapper
   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
< mapper namespace = "BlogBestPractice" >
 
    < resultMap id = "resultBlog" type = "Blog" >
         < id property = "id" column = "idBlog" />
         < result property = "name" column = "blogName" />
         < result property = "url" column = "url" />
         < association property = "author" column = "idBlog" javaType = "Author" >
             < id property = "id" column = "idAuthor" />
             < result property = "name" column = "authorName" />
             < result property = "email" column = "email" />
         </ association >
         < collection property = "posts" column = "idBlog" javaType = "ArrayList" ofType = "Post" >
             < id property = "id" column = "idPost" />
             < result property = "title" column = "title" />
             < collection property = "tags" column = "idBlog" javaType = "ArrayList" ofType = "Tag" >
                 < id property = "id" column = "idTag" />
                 < result property = "value" column = "value" />
             </ collection >
         </ collection >
     </ resultMap >
 
     < select id = "selectBlogBestPractice" resultMap = "resultBlog" >
         SELECT
             B.idBlog as idBlog, B.name as blogName, B.url as url,
             A.idAuthor as idAuthor, A.name as authorName, A.email as email ,
             P.idPost as idPost, P.title as title,
             T.idTag as idTag, T.value as value
         FROM BLOG as B
             left outer join Author A on B.idBlog = A.idBlog
             left outer join Post P on P.idBlog = B.idBlog
             left outer join Post_Tag PT on P.idPost = PT.idPost
             left outer join Tag T on PT.idTag = T.idTag
     </ select >
 
</ mapper >
Notice that this is a best practice. You should try to avoid the N+1 Selects problem.

3 – BlogDAO

Now that we have all the configuration we need, let’s write our DAO:
There are 2 methods: the first one will retrieve the blog data using the first approach: Nested Select and the second method will use the second approach: Nested Results.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.loiane.dao;
 
import java.util.List;
 
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
 
import com.loiane.model.Blog;
 
public class BlogDAO {
 
     /**
      * Returns the list of all Contact instances from the database.
      * @return the list of all Contact instances from the database.
      */
     @SuppressWarnings ( "unchecked" )
     public List<Blog> select(){
 
         SqlSessionFactory sqlSessionFactory = MyBatisConnectionFactory.getSqlSessionFactory();
         SqlSession session = sqlSessionFactory.openSession();
 
         try {
             List<Blog> list = session.selectList( "Blog.selectBlog" );
             return list;
         } finally {
             session.close();
         }
     }
 
     /**
      * Returns the list of all Contact instances from the database avoiding the N + 1
      * problem
      * @return the list of all Contact instances from the database.
      */
     @SuppressWarnings ( "unchecked" )
     public List<Blog> selectN1ProblemSolution(){
 
         SqlSessionFactory sqlSessionFactory = MyBatisConnectionFactory.getSqlSessionFactory();
         SqlSession session = sqlSessionFactory.openSession();
 
         try {
             List<Blog> list = session.selectList( "BlogBestPractice.selectBlogBestPractice" );
             return list;
         } finally {
             session.close();
         }
     }
}

4 – Annotations

As there is an article explaining iBatis/MyBatis annotations already, I am going to list the differents annotations, ok?
We are going to write 3 selects (one for Blog, another one for Author and another one for Posts and Tags). It is the same thing we did using XML:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.loiane.data;
 
import java.util.List;
 
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
 
import com.loiane.model.Author;
import com.loiane.model.Blog;
import com.loiane.model.Post;
 
public interface BlogMapper {
 
     final String SELECT_POSTS = "SELECT  P.idPost as idPost, P.title as title, T.idTag as idTag, T.value as value " +
             "FROM Post P left outer join Post_Tag PT on P.idPost = PT.idPost " +
             "left outer join Tag T on PT.idTag = T.idTag WHERE P.idBlog = #{idBlog}" ;
 
     /**
      * Returns the list of all Blog instances from the database.
      * @return the list of all Blog instances from the database.
      */
     @Select ( "SELECT idBlog, name as blogname, url as blogurl FROM BLOG" )
     @Results (value = {
         @Result (property= "id" , column= "idBlog" ),
         @Result (property= "name" , column= "blogname" ),
         @Result (property= "url" , column= "blogurl" ),
         @Result (property= "author" , column= "idBlog" , javaType=Author. class , one= @One (select= "selectAuthor" )),
         @Result (property= "posts" , column= "idBlog" , javaType=List. class , many= @Many (select= "selectBlogPosts" ))
     })
     List<Blog> selectAllBlogs();
 
     /**
      * Returns the list of all Author instances from the database of a Blog
      * @param idBlog
      * @return the list of all Author instances from the database of a Blog
      */
     @Select ( "SELECT idAuthor as id, name, email FROM AUTHOR WHERE idBlog = #{idBlog}" )
     Author selectAuthor(String idBlog);
 
     /**
      * Returns the list of all Post instances from the database of a Blog
      * @param idBlog
      * @return the list of all Post instances from the database of a Blog
      */
     @Select (SELECT_POSTS)
     @Results (value = {
         @Result (property= "id" , column= "idPost" ),
         @Result (property= "title" , column= "title" ),
         @Result (property= "tags" , column= "idPost" , javaType=List. class , many= @Many )
     })
     List<Post> selectBlogPosts(String idBlog);
 
}
We are going to set the has-one or has-many relationships using @One or @Many annotations.

@ Result

A single result mapping between a column and a property or field.
Attributes: id, column, property, javaType, jdbcType, typeHandler, one , many .
The id attribute is a boolean value that indicates that the property should be used for comparisons (similar to <id> in the XML mappings).
The one attribute is for single associations, similar to <association>, and the many attribute is for collections, similar to <collection>. They are named as they are to avoid class naming conflicts.

@One

A mapping to a single property value of a complex type.
Attributes: select, which is the fully qualified name of a mapped statement (i.e. mapper method) that can load an instance of the appropriate type.
Note : You will notice that join mapping is not supported via the Annotations API. This is due to the limitation in Java Annotations that does not allow for circular references.

@Many

A mapping to a collection property of a complex types.
Attributes: select, which is the fully qualified name of a mapped statement (i.e. mapper method) that can load a collection of instances of the appropriate types.
Note : You will notice that join mapping is not supported via the Annotations API. This is due to the limitation in Java Annotations that does not allow for circular references.

5 – SqlMapConfig.xml

This is how our SqlMapConfig.xml looks like:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<? xml version = "1.0" encoding = "UTF-8" ?>
<!DOCTYPE configuration
     PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 
< configuration >
 
     < typeAliases >
         < typeAlias alias = "Blog" type = "com.loiane.model.Blog" />
         < typeAlias alias = "Author" type = "com.loiane.model.Author" />
         < typeAlias alias = "Post" type = "com.loiane.model.Post" />
         < typeAlias alias = "Tag" type = "com.loiane.model.Tag" />
     </ typeAliases >
 
     < environments default = "development" >
         < environment id = "development" >
           < transactionManager type = "JDBC" />
             < dataSource type = "POOLED" >
                 < property name = "driver" value = "com.mysql.jdbc.Driver" />
                 < property name = "url" value = "jdbc:mysql://localhost:3306/blog_ibatis " />
                 < property name = "username" value = "root" />
                 < property name = "password" value = "root" />
             </ dataSource >
        </ environment >
     </ environments >
 
     < mappers >
        < mapper resource = "com/loiane/data/Blog.xml" />
        < mapper resource = "com/loiane/data/BlogBestPractice.xml" />
     </ mappers >
 
</ configuration >

6 - MyBatisConnectionFactory

As you can see, we set alias and 2 mappers on the SqlMapConfig.xml. But we also have a annotation mapper in this project.
We have to set it on the MyBatisConnectionFactory. This is how you can use both: XML and annotations, though I thing it is best if you use only one.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.loiane.dao;
 
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 
import com.loiane.data.BlogMapper;
 
public class MyBatisConnectionFactory {
 
     private static SqlSessionFactory sqlSessionFactory;
 
     static {
 
         try {
 
             String resource = "SqlMapConfig.xml" ;
             Reader reader = Resources.getResourceAsReader(resource);
 
             if (sqlSessionFactory == null ) {
                 sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
 
                 sqlSessionFactory.getConfiguration().addMapper(BlogMapper. class );
             }
         }
 
         catch (FileNotFoundException fileNotFoundException) {
             fileNotFoundException.printStackTrace();
         }
         catch (IOException iOException) {
             iOException.printStackTrace();
         }
     }
 
     public static SqlSessionFactory getSqlSessionFactory() {
 
         return sqlSessionFactory;
     }
}

Download

If you want to download the complete sample project, you can get it from my GitHub account: https://github.com/loiane/ibatis-handling-joins

If you want to download the zip file of the project, just click on download:

There are more articles about iBatis to come. Stay tooned!

分享到:
评论

相关推荐

    ibatis mybatis crud 完整代码

    在IT行业中,`iBatis` 和 `MyBatis` 是两种非常流行的持久层框架,它们主要用于简化Java应用程序中的数据库操作。本篇文章将深入探讨这两个框架,并基于`CRUD`(Create, Read, Update, Delete)操作来阐述如何使用它们...

    ibatis mybatis 分页 crud 完整代码

    在IT行业中,数据库操作是应用程序开发的核心部分,而Ibatis和Mybatis作为Java领域的两个流行持久层框架,为开发者提供了方便的数据访问接口。本资源"ibatis mybatis 分页 crud 完整代码"包含了这两个框架在CRUD...

    ibatis2.X升级mybatis3.X之曲径通幽处

    Ibatis和Mybatis都是广泛使用的Java ORM(对象关系映射)框架,它们帮助开发者将数据库操作与业务逻辑解耦。本篇文章将探讨从ibatis2.x升级到mybatis3.x的过程,揭示其中的技术变迁和核心变化。 Ibatis2.x是一款轻...

    从iBatis迁移到MyBatis

    标题 "从iBatis迁移到MyBatis" 暗示了本次讨论的主题是关于数据库持久层框架的升级,从较早的iBatis转向更现代的MyBatis。iBatis是一个Java语言中的SQL映射框架,而MyBatis是在iBatis的基础上发展起来的,提供了更多...

    Ibatis/mybatis代码生成工具

    《Ibatis/mybatis代码生成工具详解》 在Java开发领域,Ibatis和Mybatis作为两款广泛应用的持久层框架,极大地简化了数据库操作。为了进一步提高开发效率,开发者们设计了一系列的代码生成工具,如"Ibatis Helper"和...

    myBatis和ibatis的区别

    ### myBatis与ibatis的区别 #### 一、概述 myBatis与ibatis是两款在Java领域中非常流行的持久层框架,它们均基于SQL映射机制,为开发者提供了便捷的方式来处理数据库操作。两者间的关系密切,ibatis是myBatis的...

    ibatis2mybatis-master.zip

    标题“ibatis2mybatis-master.zip”所指的是一款工具或服务,用于将基于iBATIS的数据访问框架的代码自动转换为使用MyBatis框架的代码。iBATIS和MyBatis都是Java开发中常用的持久层框架,它们帮助开发者简化数据库...

    Ibatis MyBatis dtd+jar+odbc+jdbc

    收集这些资源方便小伙伴下载,如果没有资源分,可以给我留言哦,免分发放! sql-map-2.dtd、 ...ibatis-2.3.0.677.jar、 mybatis-3.2.7、 mybatis-3.4.4、 ojdbc14.jar、 mysql-connector-java-5.1.20-bin.jar

    ibatis2mybatis-master

    可以帮你将 ibatis 2.x sqlmap 文件转换为 myBatis 3.x mapper 文件,该工具是使用了 Ant 构建任务进行 XSTL 转换和一些语法文字替换 该工具下载下来使用非常简单,把你要转换的所有 sqlmap 文件放到 source 文件夹...

    IBatisDemo:Ibatis的一个简单Demo

    IBatis .NET 是MyBatis(原名iBATIS)在.NET平台上的实现,它提供了一种将业务逻辑与数据访问层解耦的方法。通过XML或注解定义SQL语句,开发者可以灵活控制数据库操作,同时避免了编写大量重复的ADO.NET代码。 **2....

    ibatis和mybatis对比

    ibatis和mybatis对比

    iBatis和MyBatis对比

    在Java EE开发领域,iBatis和MyBatis是两个广受欢迎的持久层框架,它们都提供了SQL映射的功能,帮助开发者处理数据库操作。iBatis作为早期的代表,以其简洁和灵活性赢得了开发者们的青睐,特别是对于熟悉SQL的程序员...

    Grails-MyBatis:用于 Grails 框架的 MyBatis 插件

    Grails-MyBatis 用于 Grails 框架的 MyBatis 插件 基于原始 Grails-iBatis 插件:Brian Sanders ( ) Grails 插件主页: : 修改: 命名约定的一些变化 添加了对多个数据源的完全支持 Grails 2.0 插件重构 最小 ...

    搭建IBatis一:mysql环境搭建之被虐的酸爽篇

    标题中的“搭建IBatis一:mysql环境搭建之被虐的酸爽篇”表明这是一个关于如何在计算机环境中配置和使用IBatis框架与MySQL数据库的教程,其中可能涉及了作者在搭建过程中遇到的问题和解决方法。从描述中的链接可以...

    ibatis和mybatis的区别

    在里面总结了ibatis和mybatis的主要区别,包括xml文件等

    mybatis和ibatis代码生成工具

    MyBatis和iBatis是两个著名的Java持久层框架,它们都致力于简化数据库与Java代码之间的交互。在Java开发中,代码生成工具可以极大地提高开发效率,减少手动编写重复的CRUD(创建、读取、更新、删除)操作。本压缩包...

    MyBatis(iBATIS) 学习

    《MyBatis(iBATIS) 学习指南》 MyBatis,原名iBATIS,是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML...

    2011最新ibatis+Mybatis+Spring整合文档全集以及案例

    《2011最新ibatis+Mybatis+Spring整合文档全集以及案例》是一份珍贵的资源,包含了关于这三个著名Java技术的详细信息和实践案例。这篇文章将深入探讨ibatis、Mybatis和Spring框架的整合,以及它们在实际开发中的应用...

    springMvc_ibatis_mybatis

    Spring MVC、iBatis 和 MyBatis 是Java开发中常用的三个框架,它们分别在Web层、数据访问层有着重要作用。让我们深入探讨这三个框架的核心概念、使用场景以及它们之间的关系。 **Spring MVC** Spring MVC是Spring...

    mybatis:mybatis原始码

    - **org.apache.ibatis.mapping**: 定义了Mapping相关的类,如MapperRegistry、MappedStatement等,它们负责维护SQL语句和其绑定的方法。 - **org.apache.ibatis.reflection**: 反射相关的工具类,用于动态调用Java...

Global site tag (gtag.js) - Google Analytics