国产化适配经验总结
摘要
本文通过实际的实践经验,总结出了服务端 SpringBoot
国产化适配的注意事项
国产化适配清单
- 金蝶AAS V9.0
- 东方通tongweb 7
- 达梦DM8 V8.1.1.126
金蝶AAS适配
常见配置和问题
- jvm
编辑
%domian_home%/bin/startapusic
,搜索MEMORY_JVMOPTS
MEMORY_JVMOPTS=“-Xms512m -Xmx1024m -XX:MaxPermSize=256m”
- 请求
AAS默认是将 DELETE,PUT,TRACE,OPTIONS
这四个请求方式禁用了.
编辑
%domian_home%/config/vm.options
,搜索apusic.http.disabledMethods
apusic.http.disabledMethods=DELETE,PUT,TRACE,OPTIONS
- 端口
编辑
%domian_home%/config/apusic.conf
,搜索Port
ATTRIBUTE NAME=“Port” VALUE=“6888”
- 管理
- 部署FAQ
- java.lang.IllegalStateException异常以及解决
当启动时,出现java.lang.IllegalStateException异常
时,不必惊慌.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9wZspJnp-1609070048601)(https://s3.ax1x.com/2020/12/26/rhbNEd.jpg)]
原因: 当前对客户端的响应已经结束,不能在响应已经结束(或说消亡)后再向客户端(实际上是缓冲区)输出任何内容.总之,该异常不是代码造成的,是部署出了问题.
解决:将整个项目重新部署一下.
具体操作:重新启动AAS.
项目适配
- 排除内嵌tomcat
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 移除嵌入式tomcat插件 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
- 打成war
<packaging>war</packaging>
- 修改启动类,并重写初始化方法
public class WebApplication extends SpringBootServletInitializer {
修改启动类,继承 SpringBootServletInitializer 并重写 configure 方法
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
System.out.println("======WebApplication====start==========");
return builder.sources(new Class[]{WebApplication.class});
}
}
- 注入websoket
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
- 添加serverlet依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
注意:项目未使用redis但引入redis依赖时,AAS启动将报错
东方通tongweb
常见配置和问题
- jvm
- 端口
- 部署和部署
项目适配
- 打成war
<packaging>war</packaging>
- 修改启动类,并重写初始化方法
public class WebApplication extends SpringBootServletInitializer {
修改启动类,继承 SpringBootServletInitializer 并重写 configure 方法
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
System.out.println("======WebApplication====start==========");
return builder.sources(new Class[]{WebApplication.class});
}
}
- 添加serverlet依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
达梦
迁移
- FAQ
乱码解决:指定URL
jdbc:mysql://localhost:3306/meeting?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
Mybatis的代码处理
SQL适配
- 模式名+表名 (注意大写模式名)
<select id="selectAll" resultMap="BaseResultMap">
select
meet_info.id,
meet_info.gmt_create,
meet_info.gmt_modified,
meet_info.name,
meet_info.expect_start_time,
meet_info.expect_end_time,
meet_info.room_id,
meet_info.type_id,
meet_info.summary,
meet_info.status,
is_enabled,
meet_info.is_deleted,
meet_room.room_name AS meet_room,
meet_room.room_location as roomLocation,
meet_type.type_name as meet_type,
creator_id
from "MEETING".meet_info
inner join "MEETING".meet_room on meet_info.room_id = meet_room.id
inner join "MEETING".meet_type on meet_info.type_id = meet_type.id
where meet_info.is_deleted=0
order by meet_info.expect_start_time desc
</select>
- 达梦如果设置了某个列为主键自增,那么
insert
语句就不能指定主键值
正例:
<insert id="insert" parameterType="com.bourne.meet.meeting.domain.MeetBallot" useGeneratedKeys="true"
keyProperty="id" keyColumn="id">
insert into "MEETING".meet_ballot ( gmt_create, gmt_modified,
meet_id, issue_id, start_time,
interval_time, end_time, ballot_status,
is_anonymous, corp_id)
values ( #{gmtCreate,jdbcType=TIMESTAMP}, #{gmtModified,jdbcType=TIMESTAMP},
#{meetId,jdbcType=BIGINT}, #{issueId,jdbcType=BIGINT}, #{startTime,jdbcType=TIMESTAMP},
#{intervalTime,jdbcType=INTEGER}, #{endTime,jdbcType=TIMESTAMP}, #{ballotStatus,jdbcType=CHAR},
#{isAnonymous,jdbcType=BIT}, #{corpId,jdbcType=VARCHAR})
</insert>
反例:
<insert id="insert" parameterType="com.bourne.meet.meeting.domain.MeetBallot" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
insert into meet_ballot (id, gmt_create, gmt_modified,
meet_id, issue_id, start_time,
interval_time, end_time, ballot_status,
is_anonymous, corp_id)
values (#{id,jdbcType=BIGINT}, #{gmtCreate,jdbcType=TIMESTAMP}, #{gmtModified,jdbcType=TIMESTAMP},
#{meetId,jdbcType=BIGINT}, #{issueId,jdbcType=BIGINT}, #{startTime,jdbcType=TIMESTAMP},
#{intervalTime,jdbcType=INTEGER}, #{endTime,jdbcType=TIMESTAMP}, #{ballotStatus,jdbcType=CHAR},
#{isAnonymous,jdbcType=BIT}, #{corpId,jdbcType=VARCHAR})
</insert>
-
数据库连接务必设置IP(这样能避免防火墙和达梦数据库的隔离策略导致的很多问题)
-
达梦不支持函数:
LAST_INSERT_ID()
-
达梦日期时间函数适配
DATE_SUB(NOW(), INTERVAL 1 MONTH) --> NOW() - INTERVAL '1' MONTH
-
不能使用关键字作为列名
-
批量操作不能返回受影响记录数
T}, #{corpId,jdbcType=VARCHAR})
3. 数据库连接务必设置IP(这样能避免防火墙和达梦数据库的隔离策略导致的很多问题)
4. 达梦不支持函数: `LAST_INSERT_ID()`
5. 达梦日期时间函数适配
`DATE_SUB(NOW(), INTERVAL 1 MONTH) --> NOW() - INTERVAL '1' MONTH`
6. 不能使用关键字作为列名
7. 批量操作不能返回受影响记录数