0%

EasyUi Demo

ComboBox自定义多选下拉加模糊搜索的功能

  1. 添加控件引用
1
2
3
4
5
6
<tr>
<th>多选模糊搜素</th>
<td>
<select id="comboboxid" name="comboboxname" class="easyui-combobox" placeholder="aa" multiline="true" data-options="required:false,prompt:'不选默认为全部'" style="width:228px;height: 29px;"></select>
</td>
</tr>

其中prompt:'不选默认为全部'为背景提示语,multiline="true"为控件显示多行滚动条

  1. <script type="text/javascript"></script>添加js功能代码
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
$(function() {
var lent=0;
$('#comboboxid').combobox({
url:'${pageContext.request.contextPath}/invitationCodeController/tree?checkAuthority=1',
multiple:true,
valueField:'invatationcode',
textField: 'invatationcode',
value: '${setInvitationCodes}',
onBeforeLoad:function(param){
console.log("user",'${user.getMemberUnitId()}');
param.memberUnitId='${user.getMemberUnitId()}';
console.log("param",param);
},
formatter: function (row) {
row.codeRemark= row.invatationcode+"("+row.remark+")";
return row.codeRemark;
},
filter:function(q,row){
return row.codeRemark.indexOf(q)!=-1;
},
onSelect: function (row) {
console.log("onSelect",row);
var values=$(this).combobox('getValues');
var getData=$(this).combobox('getData');
console.log("getdata",getData);
var valuesT=[];
for(i=0;i<values.length;i++){
for (ii=0;ii<getData.length;ii++){
if (values[i]==getData[ii].invatationcode){
valuesT.push(values[i]);
console.log("有效",valuesT);
}
}
}
if (lent==valuesT.length-1){
console.log("==");
lent= valuesT.length;
$(this).combobox('setValues',valuesT);
}else {
console.log("!=")
}
}
});
});

数据请求设置 url:'${pageContext.request.contextPath}/invitationCodeController/tree?checkAuthority=1',

参数设置,其中'${user.getMemberUnitId()}'是从java后端传过来,等于&memberUnitId=${user.getMemberUnitId()}'

1
2
3
4
5
onBeforeLoad:function(param){
console.log("user",'${user.getMemberUnitId()}');
param.memberUnitId='${user.getMemberUnitId()}';
console.log("param",param);
},

valueField:'invatationcode', textField: 'invatationcode',一个id一个展示的值,展示的值通过formatter自定义,显示样式为27490008(测试)

1
2
3
4
formatter: function (row) {
row.codeRemark= row.invatationcode+"("+row.remark+")";
return row.codeRemark;
},

value: '${setInvitationCodes}',这句设置是从java后端获取出数值,默认选择或加载的值,在输入框会显示该值

设置模糊搜索,通过过滤函数filter意思是row中包含q查询参数就显示

1
2
3
filter:function(q,row){
return row.codeRemark.indexOf(q)!=-1;
},

上面设置完了模糊搜索加多选是实现了,但是输入的模糊查找的字符不会自动去掉,下面设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
onSelect: function (row) {
console.log("onSelect",row);
var values=$(this).combobox('getValues');
var getData=$(this).combobox('getData');
console.log("getdata",getData);
var valuesT=[];
for(i=0;i<values.length;i++){
for (ii=0;ii<getData.length;ii++){
if (values[i]==getData[ii].invatationcode){
valuesT.push(values[i]);
console.log("有效",valuesT);
}
}
}
if (lent==valuesT.length-1){
console.log("==");
lent= valuesT.length;
$(this).combobox('setValues',valuesT);
}else {
console.log("!=")
}
}

通过遍历源数据 var getData=$(this).combobox('getData');和选中的数据(输入框的数据) var values=$(this).combobox('getValues');对比得到有效的选中数据,但是还需要在合适的时间设置有效选择数据

onSelect方法在输入框输入字和选择时都会触发,因此加个判断if (lent==valuesT.length-1)当选中有效数据每增加1个时触发因此比较长度即可,lent为全局变量,做历史长度存储

数据返回json格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[
{
"invatationcode": "27491007",
"createdate": 1510284005000,
"updatedate": 1510284005000,
"flag": 1,
"remark": "我是账号备注"
},
.........
{
"invatationcode": "27490008",
"createdate": 1510284334000,
"updatedate": 1510284334000,
"flag": 1,
"remark": "测试",
}
]

自动生成代码

maven形式

  1. pom.xml添加依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <dependencies>
    ...
    <!--Mybatis Mapper代码生成用-->
    <dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
    <version>1.3.6</version>
    </dependency>
    ...
    </dependencies>
  2. pom.xml添加插件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <plugins>
    <!--mybatis生成代码插件-->
    <plugin>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-maven-plugin</artifactId>
    <version>1.3.6</version>
    <!--指定配置文件路径-->
    <configuration>
    <overwrite>true</overwrite>
    <configurationFile>path/generactorConfig.xml</configurationFile>
    </configuration>
    </plugin>
    </plugins>
  3. 配置generactorConfig.xml文件,改配置来源Mybatis系列—Mybatis插件使用(自动生成Mapper,分页)

    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
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
    <generatorConfiguration>
    <!-- 指定oracle/mysql的驱动包的路径 千万别放中文路径下 -->
    <classPathEntry location="C://Users//Administrator//.DataGrip2018.1//config//jdbc-drivers//MySQL Connector//J//5.1.46//mysql-connector-java-5.1.46.jar"/>
    <!-- 配置数据源和生成的代码所存放的位置 -->
    <!-- targetRuntime="MyBatis3" 生成条件查询等 -->
    <context id="testTable" targetRuntime="MyBatis3Simple">
    <!--设置生成的Java文件的编码格式-->
    <property name="javaFileEncoding" value="UTF-8"></property>
    <!--格式化java代码-->
    <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"></property>
    <!--格式化xml代码-->
    <property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"></property>
    <!--javaBean 实现序列化接口-->
    <plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin>
    <!--javaBean生成toString() 方法-->
    <plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
    <commentGenerator>
    <!--生成代码时,是否生成注释 true:不 false:是-->
    <property name="suppressAllComments" value="true"></property>
    </commentGenerator>
    <!--数据库配置-->
    <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://192.168.204.182:3306/manage?useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull&amp;serverTimezone=UTC" userId="root" password="lfadmin"></jdbcConnection>
    <!--
    java类型处理器
    用于处理DB中的类型到Java中的类型,默认使用JavaTypeResolverDefaultImpl;
    注意一点,默认会先尝试使用Integer,Long,Short等来对应DECIMAL和 NUMERIC数据类型;
    -->
    <javaTypeResolver type="org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl">
    <property name="forceBigDecimals" value="false"></property>
    </javaTypeResolver>

    <!--生成实体-->
    <javaModelGenerator targetPackage="com.willson.facade.pojo.plot" targetProject="../facade/src/main/java">
    <property name="enableSubPackages" value="true"/>
    </javaModelGenerator>
    <!--生成mapper.xml文件-->
    <sqlMapGenerator targetPackage="plot" targetProject="src/main/resources/mapper">
    <property name="enableSubPackages" value="true"></property>
    </sqlMapGenerator>
    <!--生成dao接口-->
    <javaClientGenerator type="XMLMAPPER" targetPackage="com.willson.service.mapper.plot" targetProject="src/main/java">
    <property name="enableSubPackages" value="true"></property>
    </javaClientGenerator>
    <!--为哪些表生成代码 tableName=表名字 domainObjectName 生成实体类名字-->
    <table tableName="tb_plot_herbaceous_plant" domainObjectName="herbaceousPlant" />

    </context>
    </generatorConfiguration>
  4. 最后在右侧maven projects->plugins->mybatis-generator:generate运行就会生成了

    1530182957362

##注解式

基本格式,接口加@Mapper

1
2
3
4
5
6
7
8
9
package com.xhzg.xhzg.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface UserMapper {
@Select("select * from user where username=#{username}")
User loadUserByUsername(String username);
}

常用注解

1
@Select("select * from user where username=#{username}") //查询语

实现插入数据后返回自增id:

1
2
3
@Insert("INSERT INTO picturedetail(userid,detail) VALUES(#{userid}, #{detail})")
@Options(useGeneratedKeys = true, keyProperty = "picturedetailid")
int insertPictureDetail(PictureDetail pictureDetail);

Options(useGeneratedKeys = true, keyProperty = "自增id")用于返回自增id,返回后id读取直接从传入的

PictureDetail类里获取即可,不是通过返回值接收

实现where if 查询语句

通过 @SelectProvider(type实现

1
2
@SelectProvider(type = Provider.class,method = "queryPaperByParam")
List<Paper> selectPaper(Paper paper);

查询provider类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Provider {
private final String TBL_PAPER = "paper"; //表名
//查询方法,和注解里的名字要一致
public String queryPaperByParam(Paper paper) {
SQL sql = new SQL().SELECT("*").FROM(TBL_PAPER);

if (!StringUtils.isEmpty(paper.getPapername())) {
sql.WHERE("papername LIKE '%"+paper.getPapername()+"%'");
}
if (paper.getPaperid()!=0) {
sql.WHERE("paperid = #{paperid}");
}
return sql.toString();
}
}

xml式

Mybatis Generator Example

1.OR条件的使用

1
2
--?=keyword
select * from TBL_TEST WHERE ( NAME like ? ) or( SEX like ? ) and Class='1班';

等效于

1
2
3
4
5
6
7
8
9
TblTestExample example = new TblTestExample();
if (!StringUtil.isEmpty(keyword)) {
keyword="%"+keyword+"%"; //必须加,不然查不到
example.or().andNameLike(keyword); //根据关键字查找
example.or().andSexLike(keyword);//必须分开写,不然不是or
}
example.createCriteria().andClassEqualTo("1班"); //限定会员单位
}
List<TblTest> testList = testMapper.selectByExample(example);

问题

  1. Mapper method 'com.xxx' has an unsupported return type: class com.xxx.User问题原因是mapper 中insert只能返回int,因此修改返回类型即可

  2. nested exception is org.apache.ibatis.builder.BuilderException: Error invoking SqlProvider method (com.xhzg.xhzg.mapper.Provider.queryflowerByParam). Cannot invoke a method that holds named argument(@Param) using a specifying parameterObject. In this case, please specify a 'java.util.Map' object.错误解决:指定@param

    1
    2
    3
    4
    //provider知道@param  
    public String queryflowerByParam(@Param("classid") int classid) {}
    @SelectProvider(type = Provider.class,method = "queryflowerByParam")
    List<FlowerInfoEntiy> selectFlowerinfo(@Param("classid") int classid);

详情

generactorConfig.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- 配置生成器 -->
<generatorConfiguration>
<!-- 可以用于加载配置项或者配置文件,在整个配置文件中就可以使用${propertyKey}的方式来引用配置项
resource:配置资源加载地址,使用resource,MBG从classpath开始找,比如com/myproject/generatorConfig.properties
url:配置资源加载地质,使用URL的方式,比如file:///C:/myfolder/generatorConfig.properties.
注意,两个属性只能选址一个;

另外,如果使用了mybatis-generator-maven-plugin,那么在pom.xml中定义的properties都可以直接在generatorConfig.xml中使用
<properties resource="" url="" />
-->

<!-- 在MBG工作的时候,需要额外加载的依赖包
location属性指明加载jar/zip包的全路径
<classPathEntry location="/Program Files/IBM/SQLLIB/java/db2java.zip" />
-->

<!--
context:生成一组对象的环境
id:必选,上下文id,用于在生成错误时提示
defaultModelType:指定生成对象的样式
1,conditional:类似hierarchical;
2,flat:所有内容(主键,blob)等全部生成在一个对象中;
3,hierarchical:主键生成一个XXKey对象(key class),Blob等单独生成一个对象,其他简单属性在一个对象中(record class)
targetRuntime:
1,MyBatis3:默认的值,生成基于MyBatis3.x以上版本的内容,包括XXXBySample;
2,MyBatis3Simple:类似MyBatis3,只是不生成XXXBySample;
introspectedColumnImpl:类全限定名,用于扩展MBG
-->
<context id="mysql" defaultModelType="hierarchical" targetRuntime="MyBatis3Simple" >

<!-- 自动识别数据库关键字,默认false,如果设置为true,根据SqlReservedWords中定义的关键字列表;
一般保留默认值,遇到数据库关键字(Java关键字),使用columnOverride覆盖
-->
<property name="autoDelimitKeywords" value="false"/>
<!-- 生成的Java文件的编码 -->
<property name="javaFileEncoding" value="UTF-8"/>
<!-- 格式化java代码 -->
<property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
<!-- 格式化XML代码 -->
<property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>

<!-- beginningDelimiter和endingDelimiter:指明数据库的用于标记数据库对象名的符号,比如ORACLE就是双引号,MYSQL默认是`反引号; -->
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>

<!-- 必须要有的,使用这个配置链接数据库
@TODO:是否可以扩展
-->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql:///pss" userId="root" password="admin">
<!-- 这里面可以设置property属性,每一个property属性都设置到配置的Driver上 -->
</jdbcConnection>

<!-- java类型处理器
用于处理DB中的类型到Java中的类型,默认使用JavaTypeResolverDefaultImpl;
注意一点,默认会先尝试使用Integer,Long,Short等来对应DECIMAL和 NUMERIC数据类型;
-->
<javaTypeResolver type="org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl">
<!--
true:使用BigDecimal对应DECIMAL和 NUMERIC数据类型
false:默认,
scale>0;length>18:使用BigDecimal;
scale=0;length[10,18]:使用Long;
scale=0;length[5,9]:使用Integer;
scale=0;length<5:使用Short;
-->
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>


<!-- java模型创建器,是必须要的元素
负责:1,key类(见context的defaultModelType);2,java类;3,查询类
targetPackage:生成的类要放的包,真实的包受enableSubPackages属性控制;
targetProject:目标项目,指定一个存在的目录下,生成的内容会放到指定目录中,如果目录不存在,MBG不会自动建目录
-->
<javaModelGenerator targetPackage="com._520it.mybatis.domain" targetProject="src/main/java">
<!-- for MyBatis3/MyBatis3Simple
自动为每一个生成的类创建一个构造方法,构造方法包含了所有的field;而不是使用setter;
-->
<property name="constructorBased" value="false"/>

<!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
<property name="enableSubPackages" value="true"/>

<!-- for MyBatis3 / MyBatis3Simple
是否创建一个不可变的类,如果为true,
那么MBG会创建一个没有setter方法的类,取而代之的是类似constructorBased的类
-->
<property name="immutable" value="false"/>

<!-- 设置一个根对象,
如果设置了这个根对象,那么生成的keyClass或者recordClass会继承这个类;在Table的rootClass属性中可以覆盖该选项
注意:如果在key class或者record class中有root class相同的属性,MBG就不会重新生成这些属性了,包括:
1,属性名相同,类型相同,有相同的getter/setter方法;
-->
<property name="rootClass" value="com._520it.mybatis.domain.BaseDomain"/>

<!-- 设置是否在getter方法中,对String类型字段调用trim()方法 -->
<property name="trimStrings" value="true"/>
</javaModelGenerator>


<!-- 生成SQL map的XML文件生成器,
注意,在Mybatis3之后,我们可以使用mapper.xml文件+Mapper接口(或者不用mapper接口),
或者只使用Mapper接口+Annotation,所以,如果 javaClientGenerator配置中配置了需要生成XML的话,这个元素就必须配置
targetPackage/targetProject:同javaModelGenerator
-->
<sqlMapGenerator targetPackage="com._520it.mybatis.mapper" targetProject="src/main/resources">
<!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>


<!-- 对于mybatis来说,即生成Mapper接口,注意,如果没有配置该元素,那么默认不会生成Mapper接口
targetPackage/targetProject:同javaModelGenerator
type:选择怎么生成mapper接口(在MyBatis3/MyBatis3Simple下):
1,ANNOTATEDMAPPER:会生成使用Mapper接口+Annotation的方式创建(SQL生成在annotation中),不会生成对应的XML;
2,MIXEDMAPPER:使用混合配置,会生成Mapper接口,并适当添加合适的Annotation,但是XML会生成在XML中;
3,XMLMAPPER:会生成Mapper接口,接口完全依赖XML;
注意,如果context是MyBatis3Simple:只支持ANNOTATEDMAPPER和XMLMAPPER
-->
<javaClientGenerator targetPackage="com._520it.mybatis.mapper" type="ANNOTATEDMAPPER" targetProject="src/main/java">
<!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
<property name="enableSubPackages" value="true"/>

<!-- 可以为所有生成的接口添加一个父接口,但是MBG只负责生成,不负责检查
<property name="rootInterface" value=""/>
-->
</javaClientGenerator>

<!-- 选择一个table来生成相关文件,可以有一个或多个table,必须要有table元素
选择的table会生成一下文件:
1,SQL map文件
2,生成一个主键类;
3,除了BLOB和主键的其他字段的类;
4,包含BLOB的类;
5,一个用户生成动态查询的条件类(selectByExample, deleteByExample),可选;
6,Mapper接口(可选)

tableName(必要):要生成对象的表名;
注意:大小写敏感问题。正常情况下,MBG会自动的去识别数据库标识符的大小写敏感度,在一般情况下,MBG会
根据设置的schema,catalog或tablename去查询数据表,按照下面的流程:
1,如果schema,catalog或tablename中有空格,那么设置的是什么格式,就精确的使用指定的大小写格式去查询;
2,否则,如果数据库的标识符使用大写的,那么MBG自动把表名变成大写再查找;
3,否则,如果数据库的标识符使用小写的,那么MBG自动把表名变成小写再查找;
4,否则,使用指定的大小写格式查询;
另外的,如果在创建表的时候,使用的""把数据库对象规定大小写,就算数据库标识符是使用的大写,在这种情况下也会使用给定的大小写来创建表名;
这个时候,请设置delimitIdentifiers="true"即可保留大小写格式;

可选:
1,schema:数据库的schema;
2,catalog:数据库的catalog;
3,alias:为数据表设置的别名,如果设置了alias,那么生成的所有的SELECT SQL语句中,列名会变成:alias_actualColumnName
4,domainObjectName:生成的domain类的名字,如果不设置,直接使用表名作为domain类的名字;可以设置为somepck.domainName,那么会自动把domainName类再放到somepck包里面;
5,enableInsert(默认true):指定是否生成insert语句;
6,enableSelectByPrimaryKey(默认true):指定是否生成按照主键查询对象的语句(就是getById或get);
7,enableSelectByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询语句;
8,enableUpdateByPrimaryKey(默认true):指定是否生成按照主键修改对象的语句(即update);
9,enableDeleteByPrimaryKey(默认true):指定是否生成按照主键删除对象的语句(即delete);
10,enableDeleteByExample(默认true):MyBatis3Simple为false,指定是否生成动态删除语句;
11,enableCountByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询总条数语句(用于分页的总条数查询);
12,enableUpdateByExample(默认true):MyBatis3Simple为false,指定是否生成动态修改语句(只修改对象中不为空的属性);
13,modelType:参考context元素的defaultModelType,相当于覆盖;
14,delimitIdentifiers:参考tableName的解释,注意,默认的delimitIdentifiers是双引号,如果类似MYSQL这样的数据库,使用的是`(反引号,那么还需要设置context的beginningDelimiter和endingDelimiter属性)
15,delimitAllColumns:设置是否所有生成的SQL中的列名都使用标识符引起来。默认为false,delimitIdentifiers参考context的属性

注意,table里面很多参数都是对javaModelGenerator,context等元素的默认属性的一个复写;
-->
<table tableName="userinfo" >

<!-- 参考 javaModelGenerator 的 constructorBased属性-->
<property name="constructorBased" value="false"/>

<!-- 默认为false,如果设置为true,在生成的SQL中,table名字不会加上catalog或schema; -->
<property name="ignoreQualifiersAtRuntime" value="false"/>

<!-- 参考 javaModelGenerator 的 immutable 属性 -->
<property name="immutable" value="false"/>

<!-- 指定是否只生成domain类,如果设置为true,只生成domain类,如果还配置了sqlMapGenerator,那么在mapper XML文件中,只生成resultMap元素 -->
<property name="modelOnly" value="false"/>

<!-- 参考 javaModelGenerator 的 rootClass 属性
<property name="rootClass" value=""/>
-->

<!-- 参考javaClientGenerator 的 rootInterface 属性
<property name="rootInterface" value=""/>
-->

<!-- 如果设置了runtimeCatalog,那么在生成的SQL中,使用该指定的catalog,而不是table元素上的catalog
<property name="runtimeCatalog" value=""/>
-->

<!-- 如果设置了runtimeSchema,那么在生成的SQL中,使用该指定的schema,而不是table元素上的schema
<property name="runtimeSchema" value=""/>
-->

<!-- 如果设置了runtimeTableName,那么在生成的SQL中,使用该指定的tablename,而不是table元素上的tablename
<property name="runtimeTableName" value=""/>
-->

<!-- 注意,该属性只针对MyBatis3Simple有用;
如果选择的runtime是MyBatis3Simple,那么会生成一个SelectAll方法,如果指定了selectAllOrderByClause,那么会在该SQL中添加指定的这个order条件;
-->
<property name="selectAllOrderByClause" value="age desc,username asc"/>

<!-- 如果设置为true,生成的model类会直接使用column本身的名字,而不会再使用驼峰命名方法,比如BORN_DATE,生成的属性名字就是BORN_DATE,而不会是bornDate -->
<property name="useActualColumnNames" value="false"/>


<!-- generatedKey用于生成生成主键的方法,
如果设置了该元素,MBG会在生成的<insert>元素中生成一条正确的<selectKey>元素,该元素可选
column:主键的列名;
sqlStatement:要生成的selectKey语句,有以下可选项:
Cloudscape:相当于selectKey的SQL为: VALUES IDENTITY_VAL_LOCAL()
DB2 :相当于selectKey的SQL为: VALUES IDENTITY_VAL_LOCAL()
DB2_MF :相当于selectKey的SQL为:SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1
Derby :相当于selectKey的SQL为:VALUES IDENTITY_VAL_LOCAL()
HSQLDB :相当于selectKey的SQL为:CALL IDENTITY()
Informix :相当于selectKey的SQL为:select dbinfo('sqlca.sqlerrd1') from systables where tabid=1
MySql :相当于selectKey的SQL为:SELECT LAST_INSERT_ID()
SqlServer :相当于selectKey的SQL为:SELECT SCOPE_IDENTITY()
SYBASE :相当于selectKey的SQL为:SELECT @@IDENTITY
JDBC :相当于在生成的insert元素上添加useGeneratedKeys="true"和keyProperty属性
<generatedKey column="" sqlStatement=""/>
-->

<!--
该元素会在根据表中列名计算对象属性名之前先重命名列名,非常适合用于表中的列都有公用的前缀字符串的时候,
比如列名为:CUST_ID,CUST_NAME,CUST_EMAIL,CUST_ADDRESS等;
那么就可以设置searchString为"^CUST_",并使用空白替换,那么生成的Customer对象中的属性名称就不是
custId,custName等,而是先被替换为ID,NAME,EMAIL,然后变成属性:id,name,email;

注意,MBG是使用java.util.regex.Matcher.replaceAll来替换searchString和replaceString的,
如果使用了columnOverride元素,该属性无效;

<columnRenamingRule searchString="" replaceString=""/>
-->


<!-- 用来修改表中某个列的属性,MBG会使用修改后的列来生成domain的属性;
column:要重新设置的列名;
注意,一个table元素中可以有多个columnOverride元素哈~
-->
<columnOverride column="username">
<!-- 使用property属性来指定列要生成的属性名称 -->
<property name="property" value="userName"/>

<!-- javaType用于指定生成的domain的属性类型,使用类型的全限定名
<property name="javaType" value=""/>
-->

<!-- jdbcType用于指定该列的JDBC类型
<property name="jdbcType" value=""/>
-->

<!-- typeHandler 用于指定该列使用到的TypeHandler,如果要指定,配置类型处理器的全限定名
注意,mybatis中,不会生成到mybatis-config.xml中的typeHandler
只会生成类似:where id = #{id,jdbcType=BIGINT,typeHandler=com._520it.mybatis.MyTypeHandler}的参数描述
<property name="jdbcType" value=""/>
-->

<!-- 参考table元素的delimitAllColumns配置,默认为false
<property name="delimitedColumnName" value=""/>
-->
</columnOverride>

<!-- ignoreColumn设置一个MGB忽略的列,如果设置了改列,那么在生成的domain中,生成的SQL中,都不会有该列出现
column:指定要忽略的列的名字;
delimitedColumnName:参考table元素的delimitAllColumns配置,默认为false

注意,一个table元素中可以有多个ignoreColumn元素
<ignoreColumn column="deptId" delimitedColumnName=""/>
-->
</table>

</context>

</generatorConfiguration>

环境准备

1
2
3
4
sudo docker rm $(docker ps -a -q) #移除所有已停止的镜像
sudo docker swarm leave
sudo docker swarm init --advertise-addr 10.14.0.1
sudo docker swarm join --token SWMTKN-1-1ue26optqse6n6gcaitf6ns7qyiyqo7o6eb6genabxkof6rhid-d6f802lv5logrupqeop0087fx 10.14.0.1:2377

安装sameersbn/gitlab

1
2
3
4
5
6
#工作节点拉取镜像
sudo docker pull sameersbn/gitlab:10.2.2
sudo docker pull sameersbn/redis:latest
sudo docker pull sameersbn/postgresql:9.6-2
#创建目录,创建到了Dropbox目录
mkdir -p docker/gitlab/postgresql docker/gitlab/redis docker/gitlab/gitlab

下载wget https://raw.githubusercontent.com/sameersbn/docker-gitlab/master/docker-compose.yml并修改

为如下内容,主要替换版本version: '3'和添加deploy以及配置参数

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
version: '3'

services:
redis:
restart: always
image: sameersbn/redis:latest
command:
- --loglevel warning
volumes:
- ~/Dropbox/docker/gitlab/redis:/var/lib/redis:Z
deploy:
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints: [node.role == worker]

postgresql:
restart: always
image: sameersbn/postgresql:9.6-2
volumes:
- ~/Dropbox/docker/gitlab/postgresql:/var/lib/postgresql:Z
environment:
- DB_USER=gitlab
- DB_PASS=mimais163
- DB_NAME=gitlabhq_production
- DB_EXTENSION=pg_trgm
deploy:
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints: [node.role == worker]

gitlab:
restart: always
image: sameersbn/gitlab:10.2.2
depends_on:
- redis
- postgresql
ports:
- "14008:80"
- "14002:22"
volumes:
- ~/Dropbox/docker/gitlab/gitlab:/home/git/data:Z
environment:
- DEBUG=false

- DB_ADAPTER=postgresql
- DB_HOST=postgresql
- DB_PORT=5432
- DB_USER=gitlab
- DB_PASS=******
- DB_NAME=gitlabhq_production

- REDIS_HOST=redis
- REDIS_PORT=6379

- TZ=Asia/Kolkata
- GITLAB_TIMEZONE=Kolkata

- GITLAB_HTTPS=false
- SSL_SELF_SIGNED=false

- GITLAB_HOST=iexxk.com
- GITLAB_PORT=14008
- GITLAB_SSH_PORT=14002
- GITLAB_RELATIVE_URL_ROOT=
- GITLAB_SECRETS_DB_KEY_BASE=CvpwfRsb5sNpmGRcX5fQFzTNtdkd5pNMK623PVP9rkwLsTDW4VlXMLmT4bKRLVzC
- GITLAB_SECRETS_SECRET_KEY_BASE=cFdsD8xSKVCShL76hpWP3NdjTCm3XbtV7d3BXB9XZNHclq8n743s3vFTkMg3DppJ
- GITLAB_SECRETS_OTP_KEY_BASE=P8rH42vPgg5pZ34Nt8t3pwnCBcPXNkjqV8kTxBlQCkFkSCXGhXvDRSGm2bBx593q

- GITLAB_ROOT_PASSWORD=******
- GITLAB_ROOT_EMAIL=xuan.fong1@163.com

- GITLAB_NOTIFY_ON_BROKEN_BUILDS=true
- GITLAB_NOTIFY_PUSHER=false

- GITLAB_EMAIL=notifications@example.com
- GITLAB_EMAIL_REPLY_TO=noreply@example.com
- GITLAB_INCOMING_EMAIL_ADDRESS=reply@example.com

- GITLAB_BACKUP_SCHEDULE=daily
- GITLAB_BACKUP_TIME=01:00

- SMTP_ENABLED=false
- SMTP_DOMAIN=www.example.com
- SMTP_HOST=smtp.qq.com
- SMTP_PORT=465
- SMTP_USER=
- SMTP_PASS=password
- SMTP_STARTTLS=true
- SMTP_AUTHENTICATION=login

- IMAP_ENABLED=false
- IMAP_HOST=imap.gmail.com
- IMAP_PORT=993
- IMAP_USER=mailer@example.com
- IMAP_PASS=password
- IMAP_SSL=true
- IMAP_STARTTLS=false

- OAUTH_ENABLED=false
- OAUTH_AUTO_SIGN_IN_WITH_PROVIDER=
- OAUTH_ALLOW_SSO=
- OAUTH_BLOCK_AUTO_CREATED_USERS=true
- OAUTH_AUTO_LINK_LDAP_USER=false
- OAUTH_AUTO_LINK_SAML_USER=false
- OAUTH_EXTERNAL_PROVIDERS=

- OAUTH_CAS3_LABEL=cas3
- OAUTH_CAS3_SERVER=
- OAUTH_CAS3_DISABLE_SSL_VERIFICATION=false
- OAUTH_CAS3_LOGIN_URL=/cas/login
- OAUTH_CAS3_VALIDATE_URL=/cas/p3/serviceValidate
- OAUTH_CAS3_LOGOUT_URL=/cas/logout

- OAUTH_GOOGLE_API_KEY=
- OAUTH_GOOGLE_APP_SECRET=
- OAUTH_GOOGLE_RESTRICT_DOMAIN=

- OAUTH_FACEBOOK_API_KEY=
- OAUTH_FACEBOOK_APP_SECRET=

- OAUTH_TWITTER_API_KEY=
- OAUTH_TWITTER_APP_SECRET=

- OAUTH_GITHUB_API_KEY=
- OAUTH_GITHUB_APP_SECRET=
- OAUTH_GITHUB_URL=
- OAUTH_GITHUB_VERIFY_SSL=

- OAUTH_GITLAB_API_KEY=
- OAUTH_GITLAB_APP_SECRET=

- OAUTH_BITBUCKET_API_KEY=
- OAUTH_BITBUCKET_APP_SECRET=

- OAUTH_SAML_ASSERTION_CONSUMER_SERVICE_URL=
- OAUTH_SAML_IDP_CERT_FINGERPRINT=
- OAUTH_SAML_IDP_SSO_TARGET_URL=
- OAUTH_SAML_ISSUER=
- OAUTH_SAML_LABEL="Our SAML Provider"
- OAUTH_SAML_NAME_IDENTIFIER_FORMAT=urn:oasis:names:tc:SAML:2.0:nameid-format:transient
- OAUTH_SAML_GROUPS_ATTRIBUTE=
- OAUTH_SAML_EXTERNAL_GROUPS=
- OAUTH_SAML_ATTRIBUTE_STATEMENTS_EMAIL=
- OAUTH_SAML_ATTRIBUTE_STATEMENTS_NAME=
- OAUTH_SAML_ATTRIBUTE_STATEMENTS_FIRST_NAME=
- OAUTH_SAML_ATTRIBUTE_STATEMENTS_LAST_NAME=

- OAUTH_CROWD_SERVER_URL=
- OAUTH_CROWD_APP_NAME=
- OAUTH_CROWD_APP_PASSWORD=

- OAUTH_AUTH0_CLIENT_ID=
- OAUTH_AUTH0_CLIENT_SECRET=
- OAUTH_AUTH0_DOMAIN=

- OAUTH_AZURE_API_KEY=
- OAUTH_AZURE_API_SECRET=
- OAUTH_AZURE_TENANT_ID=
deploy:
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints: [node.role == worker]

启动运行

1
2
3
4
5
6
7
docker stack deploy -c docker-compose.yml gitlab
#查看gitlab
docker stack ps gitlab
#停止删除gitlab
docker stack rm gitlab
#创建符合链接,解决ubuntu非root用户导致Dropbox路径不一样,待测试
ln -s /home/xuan/Dropbox /root/Dropbox

wsl安装nodejs8.x

1
2
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install nodejs

wsl安装hexo-cli

1
2
3
4
5
6
7
cd /mnt/f/
sudo npm install -g hexo-cli
hexo --version #1.0.4
hexo init hexo && cd hexo
hexo new hello #创建新文章
hexo g #生产静态页面
hexo s #启动本地测试服务

hexo安装next主题

1
2
3
4
git clone https://github.com/iissnan/hexo-theme-next themes/next
#复制next主题到hexo\themes目录下,修改配置文件_config.yml中的theme为next
hexo clean
hexo g && hexo s

hexo引入gitment评论

参考:Gitment:使用 GitHub Issues 搭建评论系统

简介:Gitment 是作者实现的一款基于 GitHub Issues 的评论系统。

hexo\themes\next\_config.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  #菜单
tags: /tags/ || tags
updated: 2018-01-28 21:41:27
categories: /categories/ || th
#样式
scheme: Pisces
#评论
gitment:
enable: true
mint: true # RECOMMEND, A mint on Gitment, to support count, language and proxy_gateway
count: true # Show comments count in post meta area
lazy: false # Comments lazy loading with a button
cleanly: false # Hide 'Powered by ...' on footer, and more
language: # Force language, or auto switch by theme
github_user: xuanfong1 # MUST HAVE, Your Github ID
github_repo: hexo # MUST HAVE, The repo you use to store Gitment comments
client_id: ff47a05197bc142b8dc0 # MUST HAVE, Github client id for the Gitment
client_secret: b52d05ee5566230edfcf653efab9fd9fce6756c8 # EITHER this or proxy_gateway, Github access secret token for the Gitment
proxy_gateway: # Address of api proxy, See: https://github.com/aimingoo/intersect
redirect_protocol: # Protocol of redirect_uri with force_redirect_protocol when mint enabled

Hexo配置next主题配置

常见问题

leancould开启评论需要在控制台先创建Counter Class

自动部署原理流程

graph LR
O[本地新增博客文件] --> |git push|A[github:hexo分支] 
A --> |hexo编译源码|B[Travis CI编译]
B --> |静态网页文件 git push|C[github:master分支]
C --> D(博客显示)

搭建步骤

流程

  1. 注册Travis CI
  2. github生成access token
  3. 在travis同步项目,以及配置token
  4. github添加空白分支
  5. 在空白分支里放入Hexo源码
  6. 添加Travis CI配置文件
  7. 注意Hexo源码里theme文件里面的过滤文件删掉,不然会上传不了主题,造成博客空白
  8. 然后push到新建的空白分支

资源

hexo编译源码地址:https://github.com/xuanfong1/xuanfong1.github.io/tree/hexo

静态网页生产文件地址:https://github.com/xuanfong1/xuanfong1.github.io/tree/master

参考

使用 Travis CI 自动部署 Hexo

场景需求

有时需要新建一个完全独立的空白分支,作为资源存储等,例如hexo博客源码

解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
git clone git@xxxxxxxxx.git #克隆项目到本地,需要提前配置号ssh key等权限
git checkout --orphan <新的分支名> #创建新的空白分支
#如果提示error: The following untracked working tree files would be overwritten by checkout:
git clean -d -fx #会清除所有git clone下的所有文件,只剩.git
#然后重新执行
git checkout --orphan <新的分支名> #会提示一下unable to create,无视,只要分支名改变就算成功
git rm -rf . #清除所有git文件历史,为了空白分支
git commit -m "提交信息"
git push origin <新的分支名> #推送远程分支
#提示该错误error: src refspec hexo does not match any.
#解决因为不能提交空分支,重新添加文件,提交分支
git add README.md
git commit -m "提交信息"
git push origin <新的分支名> #推送远程分支

DropBox介绍

DropBox是一款同步软件,中文名多宝盒,类似网盘,由于平台兼容性比较好,这里用来做ubuntu和windos笔记存储等,还用到了docker数据卷同步(性能待测试)

Linux安装

对应的图文百度经验教程

centos7多宝盒切换账号和安装管理脚本

centos7命令行安装多宝箱

1
2
3
4
5
6
cd ~ #下载安装目录
wget https://clientupdates.dropboxstatic.com/dbx-releng/client/dropbox-lnx.x86_64-39.4.49.tar.gz #下载
tar xzf dropbox-lnx.x86_64-39.4.49.tar.gz #解压
ls #解压后用ls,查看不到改文件,因为是.开头的
cd ~/. <按TAB键> #可以看到
proxychains4 ~/.dropbox-dist/dropboxd #安装,需要使用代理,proxychains4安装见前面的文章
授权:

启动后有很多日志,然后复制输出的网址去浏览器访问,不需要本机,任何电脑浏览器都可以

注销:

如果注销账号可以去网页版,取消授权,然后再次执行安装命令可以重新授权

管理工具下载安装与使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#下载dropbox.py
proxychains4 wget -O dropbox.py https://www.dropbox.com/download?dl=packages/dropbox.py
chmod +x dropbox.py
#停止dropbox
./dropbox.py stop
killall dropbox
#安装demon(可忽略这一步,这一步是设置系统服务失败遗留)
proxychains4 ./dropbox.py start -i
#安装完成后会自动启动,如果ctrl+c停止不了可以在开一个终端执行./dropbox.py stop
#移动管理工具到安装目录
mv dropbox.py /root/.dropbox/dropbox.py
#添加全局命令,使用链接模式
ln -sf /root/.dropbox/dropbox.py /usr/bin/dropbox
#设置代理
dropbox proxy manual socks5 127.0.0.1 1080
dropbox start #启动
dropbox status #查看状态
dropbox stop #停止

额外,这里把dropbox设置成systemctl并未成功,所以未添加开机启动,开机需要手动执行dropbox start

proxychains4介绍

proxychains4是一款linux代理设置软件,在需要代理的命令前加proxychains4就可了。

Linux安装

对应的图文百度经验教程

centos7 安装使用proxychains4

1
2
3
4
5
6
7
8
yum -y install gcc automake autoconf libtool make #安装make编译工具
git clone https://github.com/rofl0r/proxychains-ng.git #下载,需要先安装git
cd proxychains-ng
./configure #配置
sudo make && sudo make install #编译安装
sudo cp ./src/proxychains.conf /etc/proxychains.conf #提取配置文件
cd .. && rm -rf proxychains-ng #删除安装文件
sudo vim /etc/proxychains.conf #编辑配置文件(修改最后一行为 socks5 127.0.0.1 1080)这个对应你的代理地址

测试

1
2
proxychains4 wget www.google.com #如果没提示错误,然后当前目录会多一个index.html
rm index.html #清除测试垃圾

使用

1
2
3
4
proxychains4 <命令>
#eg
proxychains4 bash #该终端的命令自动代理 ,退出exit
proxychains4 firefox #火狐浏览器代理模式

安装

Get Docker CE for Ubuntu

1
2
3
4
#查看可安装版本
apt-cache madison docker-ce
#安装指定版本(降级)
sudo apt install docker-ce=17.09.1~ce-0~ubuntu
  1. docker-ce | 17.12.0~ce-0~ubuntu 安装gitlab出现 Failed to find a load balance… 错误

    解决降级版本17.09.1解决

挂载卷Volume与Bind

Volume 数据卷

会把container的一个目录映射到一个数据卷,一个目录只能映射一个数据卷,不需要新建目录

graph LR
A[containner目录] --> |映射| B[数据卷]
Bind 绑定本地目录

container的一个目录会加载本地目录,因此需要在本地提前新建该目录,不然启动会找不到目录

graph LR
A[本地目录] --> |指向| B[containner目录]
方案选型与测试

方案有

启动顺序

[[vishnubob]/**wait-for-it

entrypoint vs cmd

entrypoint 必须执行服务话

cmd 命令型,可执行

总结:

  1. 如果用wait-for支持alpine,使用sh,wait-for-it使用bash
  2. dockercompose会覆盖dockerfile里面的cmd命令
  3. 通过挂载形式把脚本放进去执行,或者通过dockerfile 构建时构建进去
  4. 在容器内进行测试时,发现不能跟/actuator/health,会连接超时,
  5. 直接执行时,如果服务没启动也会超时,但是可以跟可以跟参数-t设置为0不超时,会一直等待
1
2
3
4
#不能加/actuator/health,请求超时,不能用wait-for-it.sh  ,不支持alpine ,经测试感觉怪,还使用 depends_on
command: ["./wait-for.sh", "config-server:14030", "--", "java","-jar","app.jar"]
depends_on:
- config-server

镜像升级

portainer升级命令

docker service update --image portainer/portainer:latest portainer_portainer

然后重启portainer服务

docker service upadte 命令参数详解
  • --force 强制更新重启服务,无论是否配置或镜像改变都更新

  • --image <image:tag> 制定更新的镜像

  • --with-registry-auth 私有仓库需要携带该参数,否则提示

    1
    2
    3
    image 192.168.1.230:14005/manage/test/ygl/app:latest could not be accessed on a registry to record
    its digest. Each node will access 192.168.1.230:14005/manage/test/ygl/app:latest independently,
    possibly leading to different nodes running different
1
2
# 登陆仓库
docker login 192.168.1.230:14005 -u admin -p password

节点升级

docker node update --role manager node

该命令只会更改角色,部分权限并没有立即更新,因此执行服务操作时有可能提示该错误Error response from daemon: rpc error: code = DeadlineExceeded desc = context deadline exceeded

立即生效更新节点为manger 执行docker node promote node

服务发现

服务发现组件记录了(大规模)分布式系统中所有服务的信息,人们或者其它服务可以据此找到这些服务。 DNS 就是一个简单的例子。当然,复杂系统的服务发现组件要提供更多的功能,例如,服务元数据存储、健康监控、多种查询和实时更新等。

环境

ID Hostname(role) IP 端口(不包括必须的)
ywtryezli3s9hvhnmzgndi118 xuanps(manager) 10.14.0.1:2377 TCP14000-14020
n8jomnk98nrog10tsspp3u38u localhost.localdomain(worker) 10.14.0.4 TCP14000-14020
kpbotld5edj55azexhbjfixai xuan-ubuntu(worker) 192.168.123.2

镜像:marshalw/hello-service

创建服务docker service create -p 3000:3000 --name hello-service marshalw/hello-service:0.1.0

然后再三台主机都能访问下面任何一个地址

1
2
3
4
curl http://10.14.0.4:14000/hello/name
curl http://10.14.0.1:14000/hello/name
curl http://192.168.123.2:14000/hello/name
curl http://112.74.51.136:14000/hello/name