开发问题及解决方案【190125】
2019/01/25
问题列表
序号 | 分类 | 问题 | 备注 |
---|---|---|---|
1 | IBM MQ | 配置用户名密码 | 已解决 |
2 | SqlServer | 查询条件忽略大小写 | 已解决 |
3 | 配置多数据源 | 使用mybatis配置多个数据源 | 已解决 |
4 | js date | 在js中实现时间的格式化 | 已解决 |
5 | @Component | SSM中出现使用@Component的同名类 | 已解决 |
6 | JSON | JSONArray和JSONObject只能解析对应形式 | 已解决 |
7 | POST | post参数的传入方式 | 已解决 |
8 | SqlServer | 查询多条数据,拼成一条 | 已解决 |
9 | SqlServer | 如何关联两个数据库的表 | 已解决 |
10 | Quartz | Spring整合quertz的配置 | 已解决 |
解决方案
1.1 IBM MQ配置信息如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms-4.0.xsd">
<bean id="connectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType" value="1"/>
<property name="queueManager" value="********"/>
<property name="hostName" value="*****************"/>
<property name="port" value="*******"/>
<property name="channel" value="*******"/>
<property name="CCSID" value="1381"/>
</bean>
<bean id="myConnectionFactory"
class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<property name="username" value="mqm"/>
<property name="password" value="Password1$"/>
<property name="targetConnectionFactory" ref="connectionFactory"/>
</bean>
<bean id="queueDes" class="com.ibm.mq.jms.MQQueue">
<property name="baseQueueManagerName" value="INT_NB"/>
<property name="baseQueueName" value="NB_QUENE"/>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="myConnectionFactory"/>
<property name="defaultDestination" ref="queueDes"/>
<property name="pubSubDomain" value="false"/> <!-- 队列 -->
</bean>
<!-- 2.监听器 -->
<bean id="msgListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<property name="delegate">
<bean class="com.sinosoft.uwca.listener.mq.MsgReceiver"/>
</property>
</bean>
<bean id="container" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="myConnectionFactory"/>
<property name="destination" ref="queueDes"/>
<property name="messageListener" ref="msgListener"/>
</bean>
</beans>
UserCredentialsConnectionFactoryAdapter
提供获取消息时的用户验证。
2.1 使用upper lower
条件与值均为大写或均为小写。
select * from tablename where lower(condition) = 'value';
select * from tablename where upper(condition) = 'VALUE';
3.1 使用自定义函数
jndi配置数据源
- 在web.xml中需要配置
resource-ref
, 并使用res-ref-name
关联
<resource-ref>
<res-ref-name>jdbc/prm</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
<resource-ref>
<res-ref-name>jdbc/prmods</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
- 配置数据源注意web.xml中的
res-ref-name
就是指的name
对应的值
<Context>
<Resource auth="Container" driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
initialSize="5" maxActive="120" maxIdle="5" maxWait="5000" name="jdbc/prm"
password="Devs123$" type="javax.sql.DataSource" url="jdbc:sqlserver://10.164.27.37:1433;DatabaseName=NB-Workflow"
username="NBWorkflowadmin" />
<Resource auth="Container" driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
initialSize="5" maxActive="120" maxIdle="5" maxWait="5000" name="jdbc/prmods"
password="Devs123$" type="javax.sql.DataSource" url="jdbc:sqlserver://10.164.27.37:1433;DatabaseName=NB-Middle"
username="NBWorkflowadmin" />
</Context>
- 配置mybatis映射 需要注意
jndiName
也需要与上面SQLServerDriver的name
对应
<!-- 加载配置信息1 -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>config</value>
</list>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"
scope="singleton">
<property name="jndiName" value="java:comp/env/jdbc/prm" />
<property name="resourceRef" value="true" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:mappers/**/*.xml" />
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
<constructor-arg index="1" value="BATCH" />
</bean>
<!-- uw语句映射器:自动扫描 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.sinosoft.uwca.persistence" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<!-- 加载配置信息2 -->
<bean id="messageSourceMiddle"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>config</value>
</list>
</property>
</bean>
<bean id="dataSourceMiddle" class="org.springframework.jndi.JndiObjectFactoryBean"
scope="singleton">
<property name="jndiName" value="java:comp/env/jdbc/prmods" />
<property name="resourceRef" value="true" />
</bean>
<bean id="sqlSessionFactoryMiddle" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSourceMiddle" />
<property name="mapperLocations" value="classpath:mapperods/**/*.xml" />
</bean>
<bean id="sqlSessionMiddle" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactoryMiddle" />
<constructor-arg index="1" value="BATCH" />
</bean>
<!-- uw语句映射器:自动扫描 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.sinosoft.uwca.mapperods" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryMiddle" />
</bean>
- 最后上面用到的config其实查找的是config目录下的mybatis配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="cacheEnabled" value="true" />
<setting name="lazyLoadingEnabled" value="true" />
<setting name="multipleResultSetsEnabled" value="true" />
<setting name="useColumnLabel" value="true" />
<setting name="useGeneratedKeys" value="false" />
<setting name="defaultExecutorType" value="SIMPLE" />
<setting name="defaultStatementTimeout" value="100" />
<setting name="safeRowBoundsEnabled" value="false" />
<setting name="mapUnderscoreToCamelCase" value="false" />
<setting name="localCacheScope" value="SESSION" />
<setting name="jdbcTypeForNull" value="OTHER" />
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString" />
</settings>
</configuration>
4.1 使用自定义函数
// 时间格式化 pattern 为日期格式
function SimpleDateFormat(pattern){
var fmt = {};
fmt.pattern = pattern;
fmt.parse = function(source){
try{
return new Date(source);
}catch(e){
return null;
}
};
fmt.format = function(date){
if(date === undefined || date == null || date===""){
return "";
}
try{
date = new Date(date);
}catch(e){
return "";
}
var strTime = this.pattern;//时间表达式的正则
var o = {
"M+": date.getMonth() + 1, //月份
"d+": date.getDate(), //日
"H+": date.getHours(), //小时
"m+": date.getMinutes(), //分
"s+": date.getSeconds(), //秒
"q+": Math.floor((date.getMonth() + 3) / 3), //季度
"S": date.getMilliseconds() //毫秒
};
if (/(y+)/.test(strTime)){
strTime = strTime
.replace(RegExp.$1, (date.getFullYear() + "")
.substr(4 - RegExp.$1.length));
}
for (var k in o){
if(o.hasOwnProperty(k)){
if (new RegExp("(" + k + ")").test(strTime)){
strTime = strTime.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
}
return strTime;
};
return fmt;
}
5.1 需要使用不同的name进行区分
@Component
public class Man {
......
}
Spring不能区分不同包下的同名类,因此产生bean时会产生同名的bean,项目启动是会有Annotation-specified bean name...
错误,需要设置一个不同于默认值(此处为man)的value即可
@Component("mansec")
public class Man {
......
}
6.1 统一使用JSONArray解析
一般出现在XML转JSON之后解析
比如<a>节点在xml格式的报文中出现了次数可能为1次或多次,当使用工具类转换时,就会产生两种JSON报文,而这两种报文又只能分别使用JSONObject和JSONArray进行解析。
为了兼容,可以将JSONObject封装到JSONArray中,如下:
private JSONArray convertJSONArray(JSONObject jsonParentObj, String str) {
JSONArray jsonArray = jsonParentObj.optJSONArray(str);
JSONObject jsonObject = jsonParentObj.optJSONObject(str);
if(jsonObject != null && jsonArray == null) {
jsonArray = new JSONArray();
jsonArray.put(jsonObject);
}
return jsonArray;
}
7.1 传入Map类型
@RequestMapping(value = "/CalPrem" , method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
@ResponseBody
public Object CalPrem(@RequestParam Map<String,Object> map, HttpServletRequest request) throws InterruptedException {
......................
}
7.2 传入String类型 一般为json字符串
@RequestMapping(value="/updatePolicy", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
@ResponseBody
public String updatePolicyStatus(@RequestBody String requestString) throws JSONException {
........
}
8.1 使用 stuff 和 for xml path
当查询结果出现多条数据时。如果想使其以","分割或者其他符号分割,拼装成一条数据。可以使用下面的方法:
select stuff((select ','+clntpf.SURNAME from UW_NB_LA_CLNTPF_ODS clntpf where clntpf.CLNTNUM
in (select lifepf.LIFCNUM from UW_NB_LA_LIFEPF_ODS lifepf where lifepf.CHDRNUM = '41592420' ) for xml path('')), 1, 1, '')
这里使用了stuff(src, addr, len, str)
,效果为将字符串src从addr位置开始将len长度的字符替换为str。
for xml path(var)
效果是将多条查询结果拼成以var为标签的xml报文。当var为’'时,效果为字符串而非xml。
如下:
select ','+ lifepf.LIFCNUM from UW_NB_LA_LIFEPF_ODS lifepf where lifepf.CHDRNUM = '41592420' for xml path('')
--结果:,74427921,74427921,74427916,74427916
select ','+ lifepf.LIFCNUM from UW_NB_LA_LIFEPF_ODS lifepf where lifepf.CHDRNUM = '41592420' for xml path('body')
--结果:<body>,74427921</body><body>,74427921</body><body>,74427916</body><body>,74427916</body>
select ','+ lifepf.LIFCNUM from UW_NB_LA_LIFEPF_ODS lifepf where lifepf.CHDRNUM = '41592420' for xml path
--结果:<row>,74427921</row><row>,74427921</row><row>,74427916</row><row>,74427916</row>
9.1 使用…
有这个问题其实还是对基础的数据库表访问不清楚。
--访问数据库的方法
select * from [database-table]..studentinfo;
10.1 常见配置
为了年前能出这一期,这个问题其实是凑得。我有罪~其实也方便自己拷贝。
-
配置任务
<!-- 短信批处理 --> <bean id="autoSendSMSJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"> <ref bean="tAutoSmsServiceI" /> </property> <property name="targetMethod"> <value>sendSmsMessage</value> </property> <!-- 指定concurrent属性,false表示非并发执行 --> <property name="concurrent"> <value>false</value> </property> </bean>
-
触发器
<bean id="autoSendSmsTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail"> <ref bean="autoSendSMSJob" /> </property> <property name="cronExpression"> <!-- 每隔五分钟整时发送 --> <value>0 0/5 * * * ?</value> </property> </bean>
-
调度器
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <!-- 添加触发器 --> <property name="triggers"> <list> <ref bean="autoSendSmsTrigger" /> </list> </property> </bean>
基础知识可以参考下面的链接:
https://www.cnblogs.com/zhenyuyaodidiao/p/4755649.html
备注
Nikola Zhang: 3.1继续扩展到不同数据库系统, 不同架构