Skip to content

Commit aae96f7

Browse files
committed
更新文档
1 parent 8adf924 commit aae96f7

File tree

5 files changed

+391
-3
lines changed

5 files changed

+391
-3
lines changed

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,17 @@ http://repo1.maven.org/maven2/javax/persistence/persistence-api/1.0/
9292

9393
###通用Mapper 3.x.x
9494

95-
1. [Mapper3变化]()
95+
1. [Mapper3变化](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/1.Changes.md)
9696

97-
2. [Mapper随意搭配通用接口]()
97+
2. [如何集成通用Mapper](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper/1.Integration.md)
9898

99-
3. [快速开发自己的通用接口]()
99+
3. [如何使用通用Mapper](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper/2.Use.md)
100+
101+
4. [高级应用](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/4.Professional.md)
102+
103+
5. [Mapper3通用接口大全](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/5.Mappers.md)
104+
105+
6. [快速开发自己的通用接口](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/6.MyMapper.md)
100106

101107
###通用Mapper 2.x.x
102108

wiki/mapper3/1.Changes.md

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
#通用Mapper3变化
2+
3+
##精简项目,拆分为二
4+
5+
本项目2.x版本包含了通用`Mapper<T>``EntityMapper`(以及`SqlMapper`)。
6+
7+
我本人更喜欢`Mapper<T>`这种形式,并且这种形式扩展容易,使用起来方便,和自己手写或者MBG生成的没有区别,所以我更重视`Mapper<T>`的发展。
8+
9+
因此在3.x版本中将`EntityMapper`(包含`SqlMapper`)独立为另一个项目,这个独立的项目只会完善修复bug,不会有新的功能。建议大家使用`Mapper<T>`
10+
11+
`EntityMapper`项目地址:稍后补充。
12+
13+
##细化接口,拆分为一
14+
15+
`Mapper<T>`包含了很多通用的方法,但并不是所有人都需要这些方法,也行其中的某些方法不需要,不想用,这在Mapper2.x是没法解决的。
16+
17+
还有一种情况就是,如果我的业务中需要一个我自己通用的接口方法,如果我开发了一个自己的接口,我可能还要给所有已经存在的Mapper接口(如`CountryMapper`)去继承该接口。
18+
19+
Mapper3的主要目标就是解决上面两个问题。
20+
21+
首先是将`Mapper<T>`接口细化,拆分,每一个原接口的方法,都独立为一个接口。
22+
23+
例如`List<T> select(T record);`方法原来只是`Mapper<T>`中的一个方法,现成成了`SelectMapper<T>`接口中的唯一方法:
24+
25+
```java
26+
public interface SelectMapper<T> {
27+
@SelectProvider(type = MapperProvider.class, method = "dynamicSQL")
28+
List<T> select(T record);
29+
}
30+
```
31+
32+
所有的方法都按照上面的方式进行了拆分。
33+
34+
拆分后我需要那些方法,我就继承那些方法。<b>你会不会觉得这样变的更麻烦了?</b>
35+
36+
##接口可以自定义搭配继承
37+
38+
接上面的问题,<b>你会不会觉得这样变的更麻烦了?</b>
39+
40+
我们看看`BaseSelectMapper<T>`接口:
41+
42+
```java
43+
/**
44+
* 通用Mapper接口,基础查询
45+
*
46+
* @param <T> 不能为空
47+
* @author liuzh
48+
*/
49+
public interface BaseSelectMapper<T> extends
50+
SelectOneMapper<T>,
51+
SelectMapper<T>,
52+
SelectCountMapper<T>,
53+
SelectByPrimaryKeyMapper<T> {
54+
}
55+
```
56+
57+
有没有发现什么,`BaseSelectMapper<T>`中并不包含任何方法,但是继承了4个通用的select查询方法。
58+
59+
如果我想使用这4种通用的查询方法,我并不需要去一个个继承这4个方法,我只需要继承`BaseSelectMapper<T>`即可。
60+
61+
如果你已经豁然开朗,你可能知道该如何使用了,如果还迷糊,再看下面的例子。
62+
63+
<b>为了不影响Mapper2以前版本的使用,`Mapper<T>`接口和以前没什么区别,只是多了一些方法。</b>
64+
65+
```java
66+
public interface Mapper<T> extends
67+
BaseMapper<T>,
68+
ExampleMapper<T>,
69+
RowBoundsMapper<T> {
70+
}
71+
```
72+
73+
看上面代码,如果你继承`Mapper<T>`,那么以前使用Mapper2的项目不需要做任何改变。
74+
75+
<b>总结:你完全可以自定义一个`MyMapper<T>`,然后继承你想要的接口方法,在你自己的项目中,继承你自己的`MyMapper<T>`即可。</b>
76+
77+
熟悉Mapper2多接口的可能会发现一个问题,以Spring中配置Mapper的部分代码为例:
78+
79+
```xml
80+
<bean class="com.github.abel533.mapperhelper.MapperInterceptor">
81+
<property name="properties">
82+
<!-- 属性一行一个,具体属性参考mybatis-config.xml中的属性 -->
83+
<value>
84+
mappers=com.github.abel533.mapper.Mapper
85+
</value>
86+
</property>
87+
</bean>
88+
```
89+
90+
在Mapper2中,如果你继承了多个通用接口,`mappers`需要把所有的通用接口都配置上,中间用逗号`,`隔开。
91+
92+
像Mapper3中,提供了这么多的接口,难道都要一个个配置上吗?
93+
94+
##继承接口自动注册,只需要配置基础接口
95+
96+
这句话说着也不顺,举个例子。
97+
98+
###第一种
99+
100+
如果我自己的整个项目中只用到了`Mapper<T>`接口,那么只配置一个`mappers=com.github.abel533.mapper.Mapper`即可。
101+
102+
`Mapper<T>`继承的所有父接口都会自动注册,因为父接口会自动注册,所以`mappers`配置`Mapper<T>`之后,所有的父接口都是可以单独用的。
103+
104+
也就是说我项目中的接口,可以自由搭配`Mapper<T>`父接口中的所有单独的接口。
105+
106+
###第二种
107+
108+
如果我创建了自己的`com.xxx.MyMapper<T>`,并且项目中只用到了自己的`com.xxx.MyMapper<T>`,那么只需要配置`mappers=com.xxx.MyMapper<T>`即可。
109+
110+
从这一点应该很容易看出来,项目中的代码和通用Mapper完全解耦,如果你不喜欢代码中包含`com.github.abel533`奇怪的包名,你可以自己创建一个基础接口。
111+
112+
<b>个人建议创建一个自己的通用接口,方便将来的自由扩展和搭配</b>
113+
114+
###第三种
115+
116+
如果你使用的接口互相没有继承关系,那么你需要把这些接口都配置在`mappers`属性上,和Mapper2一样。
117+
118+
##极其简单的扩展方式
119+
120+
除了Mapper2中支持的两种方式外([Mapper2扩展文档](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper/3.ExtendMapper.md)]
121+
122+
增加了一种简单的方式,看下面一个例子:
123+
124+
```java
125+
public interface InsertListMapper<T> {
126+
/**
127+
* 批量插入,支持数据库自增字段,支持回写
128+
*
129+
* @param recordList
130+
* @return
131+
*/
132+
@Options(useGeneratedKeys = true, keyProperty = "id")
133+
@InsertProvider(type = SpecialProvider.class, method = "dynamicSQL")
134+
int insertList(List<T> recordList);
135+
}
136+
```
137+
138+
这是一个批量插入的接口,这里限制自增属性为`id`
139+
140+
我们看看实现类`SpecialProvider`中的`insertList`(方法名必须和接口方法名一致)方法:
141+
142+
```java
143+
public String insertList(MappedStatement ms) {
144+
final Class<?> entityClass = getSelectReturnType(ms);
145+
//获取表的各项属性
146+
EntityHelper.EntityTable table = EntityHelper.getEntityTable(entityClass);
147+
//开始拼sql
148+
StringBuilder sql = new StringBuilder();
149+
sql.append("insert into ");
150+
sql.append(table.getName());
151+
sql.append("(");
152+
boolean first = true;
153+
for (EntityHelper.EntityColumn column : table.getEntityClassColumns()) {
154+
if(!first) {
155+
sql.append(",");
156+
}
157+
sql.append(column.getColumn());
158+
first = false;
159+
}
160+
sql.append(") values ");
161+
sql.append("<foreach collection=\"list\" item=\"record\" separator=\",\" >");
162+
sql.append("(");
163+
first = true;
164+
for (EntityHelper.EntityColumn column : table.getEntityClassColumns()) {
165+
if(!first) {
166+
sql.append(",");
167+
}
168+
sql.append("#{record.").append(column.getProperty()).append("}");
169+
first = false;
170+
}
171+
sql.append(")");
172+
sql.append("</foreach>");
173+
return sql.toString();
174+
}
175+
```
176+
177+
从获取表的各项属性后,完全就是一个拼SQL的过程,这个过程需要注意的是,这里拼的是XML中的形式。
178+
179+
上面就是两次循环列,最后拼个sql,sql形式如下:
180+
181+
```xml
182+
insert into 表(id,xxx,xxx,...)
183+
values
184+
<foreach collection="list" item="record" separtor=",">
185+
(#{record.id},#{record.xxx},...)
186+
</foreach>
187+
```
188+
189+
相信这种简单的拼字符串难不倒任何一个人,只要你能在xml写出来,就能在这儿拼出来。

wiki/mapper3/4.Professional.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#高级应用
2+
3+
如果你在使用通用Mapper过程中已经得心应手,并且几乎没有遇到过任何问题。那么,你可以看该部分内容。
4+
5+
如果你对Mapper2已经很熟悉,想使用Mapper3新的方式,你也可以看该部分内容。
6+
7+
但是在Mapper3相关的文档中,更多是按照Mapper2的方式来讲的。
8+
9+
[Mapper3变化](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/1.Changes.md)中提到了许多新的变化。
10+
11+
如果使用这些新的特性,是这部分的主要内容。
12+
13+
在看下面内容前,请先阅读[Mapper3变化](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/1.Changes.md)
14+
15+
##接口可以自定义搭配继承
16+
17+
如果你想按需选择接口,不想使用`Mapper<T>`包含的那么多的方法,你可以创建自己的`MyMapper<T>`,自己搭配想要的方法。
18+
19+
Mapper3提供的全部的方法,可以查看[Mapper3通用接口大全](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/5.Mappers.md)
20+
21+
##如何创建自己的`MyMapper<T>`呢?
22+
23+
这里只是简单的举例,仅供参考。
24+
25+
###我需要那些方法?
26+
27+
1. 假设我有一类表的操作仅设计到查询操作,不需要`insert,update,delete`等操作。
28+
29+
我可能会选择`SelectMapper<T>`,`SelectOneMapper<T>``SelectRowBoundsMapper<T>`,`SelectByExampleRowBoundsMapper<T>`接口。
30+
31+
那么我的`MyMapper<T>`就是下面的样子:
32+
33+
```java
34+
public interface MyMapper<T> extends
35+
SelectMapper<T>,
36+
SelectOneMapper<T>,
37+
SelectRowBoundsMapper<T>,
38+
SelectByExampleRowBoundsMapper<T> {
39+
40+
}
41+
```
42+
43+
2. 假设我项目中需要用到批量插入和基本才CRUD操作,那么`MyMapper<T>`就是下面的样子:
44+
45+
```java
46+
public interface MyMapper<T> extends
47+
BaseMapper<T>,
48+
InsertListMapper<T> {
49+
50+
}
51+
```
52+
53+
3. 假如我想用`Mapper<T>`的所有方法和`MySql<T>`的方法,那么`MyMapper<T>`就是下面的样子:
54+
55+
```java
56+
public interface MyMapper<T> extends
57+
Mapper<T>,
58+
MySqlMapper<T> {
59+
60+
}
61+
```
62+
63+
4. 或者不想在代码中`com.github.abel533.xxx`的包名,那么只需要创建让`MyMapper<T>`如下:
64+
65+
```java
66+
public interface MyMapper<T> extends Mapper<T> {
67+
68+
}
69+
```
70+
71+
只有这里会出现`com.github.abel533.xxx`,其他使用的地方都和`com.github.abel533.xxx`无关。
72+
73+
设计好自己的`MyMapper<T>`后,还需要进行配置。
74+
75+
###配置`MyMapper<T>`
76+
77+
```xml
78+
<bean class="com.github.abel533.mapperhelper.MapperInterceptor">
79+
<property name="properties">
80+
<value>
81+
mappers=com.xxx.xxx.MyMapper
82+
</value>
83+
</property>
84+
</bean>
85+
```
86+
只需要按照上面的方式配置即可。
87+
88+
如果我自己定义了`MyMapper`,`MyMapper2`,`MyMapper3`,可以如下配置:
89+
90+
```xml
91+
<bean class="com.github.abel533.mapperhelper.MapperInterceptor">
92+
<property name="properties">
93+
<value>
94+
mappers=com.xxx.xxx.MyMapper,com.xxx.xxx.MyMapper2,com.xxx.xxx.MyMapper3
95+
</value>
96+
</property>
97+
</bean>
98+
```
99+
100+
如果你觉得配置太长不方法,你可以这样:
101+
102+
```java
103+
public interface AllMapper<T> extends
104+
MyMapper<T>,
105+
MyMapper2<T>,
106+
MyMapper3<T> {
107+
108+
}
109+
```
110+
111+
然后配置`mappers=com.xxx.xxx.AllMapper`即可。
112+
113+
##Mapper3通用接口大全
114+
115+
Mapper3提供的全部接口,一可以看源码,二可以看[Mapper3通用接口大全](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/5.Mappers.md)
116+
117+
##如何开发自己的通用接口
118+
119+
Mapper3提供了更简单容易理解的方式,你可以看[快速开发自己的通用接口](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/6.MyMapper.md)
120+
121+
除了新增的这种方式外,还有Mapper2支持的两种方式,你可以看[如何开发自己的通用Mapper](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper/3.ExtendMapper.md)
File renamed without changes.

0 commit comments

Comments
 (0)