maven配置的项目环境框架:spring mvc + mybatis + sap iq数据库
在后台管理界面有用户和组织关系维护的界面,但是进行组织关系维护操作的时候经常会报错,提示user表找不到,但其实是存在的,而且刷新以后就又可以正常显示了(虽然有时候要多刷新很多次)
首先是报错信息(复制黏贴会比较乱,就截了个图,大家将就看下):
然后是mybatis配置
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 自动扫描 -->
<context:component-scan base-package="com.shanshan.bo" />
<!-- 引入配置文件 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties" />
</bean>
<!--dataSource管理-->
<bean id="dynamicDataSource" class="com.shanshan.bo.utils.DynamicDataSource" >
<property name="targetDataSources">
<map key-type="java.lang.String">
<!--通过不同的key决定用哪个dataSource-->
<entry value-ref="mdataDataSource" key="mdataDataSource"></entry>
<entry value-ref="devDataSource" key="devDataSource"></entry>
</map>
</property>
<!--设置默认的dataSource-->
<property name="defaultTargetDataSource" ref="mdataDataSource">
</property>
</bean>
<!--多个数据源dataSource-->
<bean id="mdataDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${iq.mdata.driver}" />
<property name="url" value="${iq.mdata.url}" />
<property name="username" value="${iq.mdata.username}" />
<property name="password" value="${iq.mdata.password}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="${initialSize}"></property>
<!-- 连接池最大数量 -->
<property name="maxActive" value="${maxActive}"></property>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${maxIdle}"></property>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="${minIdle}"></property>
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="${maxWait}"></property>
</bean>
<bean id="devDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${iq.dev.driver}" />
<property name="url" value="${iq.dev.url}" />
<property name="username" value="${iq.dev.username}" />
<property name="password" value="${iq.dev.password}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="${initialSize}"></property>
<!-- 连接池最大数量 -->
<property name="maxActive" value="${maxActive}"></property>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${maxIdle}"></property>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="${minIdle}"></property>
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="${maxWait}"></property>
</bean>
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dynamicDataSource" />
<!-- mybatis的配置文件 -->
<!-- <property name="configLocation" value="/WEB-INF/mybatis/mybatis-config.xml"></property> -->
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:com/shanshan/bo/mapping/*.xml"></property>
</bean>
<!-- DAO接口所在包名,Spring会自动查找其下的类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.shanshan.bo.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
<!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dynamicDataSource" />
</bean>
</beans>
报错信息中提到的SsFundDimPortaluserMapper.xml文件内容
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.shanshan.bo.mapper.SsFundDimPortaluserMapper" >
<resultMap id="UserResultMap" type="com.shanshan.bo.po.SsFundDimPortaluser" >
<result column="USER_ID" property="userId" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="USER_CODE" property="userCode" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="USER_NAME" property="userName" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="USER_PASSWORD" property="userPassword" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="BO_USER" property="boUser" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="BO_PASSWORD" property="boPassword" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="NC_USER" property="ncUser" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="DEFAULT_ORG" property="defaultOrg" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="ISADMIN" property="isAdmin" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="USER_GROUP" property="userGroup" jdbcType="VARCHAR" javaType="java.lang.String" />
</resultMap>
<sql id="columns">
USER_CODE, USER_NAME, USER_PASSWORD, BO_USER, BO_PASSWORD, NC_USER, DEFAULT_ORG, ISADMIN, USER_GROUP
</sql>
<insert id="insert" parameterType="com.shanshan.bo.po.SsFundDimPortaluser" >
insert into SS_FUND_DIM_PORTALUSER (USER_ID, USER_CODE, USER_NAME, USER_PASSWORD,
BO_USER, BO_PASSWORD, NC_USER, DEFAULT_ORG, ISADMIN, USER_GROUP)
values (#{userId,jdbcType=VARCHAR}, #{userCode,jdbcType=VARCHAR}, #{userName,jdbcType=VARCHAR},
#{userPassword,jdbcType=VARCHAR}, #{boUser,jdbcType=VARCHAR}, #{boPassword,jdbcType=VARCHAR},
#{ncUser,jdbcType=VARCHAR}, #{defaultOrg,jdbcType=VARCHAR}, #{isAdmin,jdbcType=VARCHAR}, #{userGroup,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.shanshan.bo.po.SsFundDimPortaluser" >
insert into SS_FUND_DIM_PORTALUSER
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="userId != null" >
USER_ID,
</if>
<if test="userCode != null" >
USER_CODE,
</if>
<if test="userName != null" >
USER_NAME,
</if>
<if test="userPassword != null" >
USER_PASSWORD,
</if>
<if test="boUser != null" >
BO_USER,
</if>
<if test="boPassword != null" >
BO_PASSWORD,
</if>
<if test="ncUser != null" >
NC_USER,
</if>
<if test="defaultOrg != null" >
DEFAULT_ORG,
</if>
<if test="isAdmin != null" >
ISADMIN,
</if>
<if test="userGroup != null" >
USER_GROUP,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="userId != null" >
#{userId,jdbcType=VARCHAR},
</if>
<if test="userCode != null" >
#{userCode,jdbcType=VARCHAR},
</if>
<if test="userName != null" >
#{userName,jdbcType=VARCHAR},
</if>
<if test="userPassword != null" >
#{userPassword,jdbcType=VARCHAR},
</if>
<if test="boUser != null" >
#{boUser,jdbcType=VARCHAR},
</if>
<if test="boPassword != null" >
#{boPassword,jdbcType=VARCHAR},
</if>
<if test="ncUser != null" >
#{ncUser,jdbcType=VARCHAR},
</if>
<if test="defaultOrg != null" >
#{defaultOrg,jdbcType=VARCHAR},
</if>
<if test="isAdmin != null" >
#{isAdmin,jdbcType=VARCHAR},
</if>
<if test="userGroup != null" >
#{userGroup,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<select id="selectAll" resultMap="UserResultMap">
select <include refid="columns"></include> from SS_FUND_DIM_PORTALUSER order by user_code
</select>
<select id="selectByUserCode" parameterType="String" resultMap="UserResultMap">
select <include refid="columns"></include> from SS_FUND_DIM_PORTALUSER
where USER_CODE = #{userCode,jdbcType=VARCHAR}
</select>
<update id="updateByUserCode" parameterType="com.shanshan.bo.po.SsFundDimPortaluser">
update SS_FUND_DIM_PORTALUSER
<trim prefix="set" suffixOverrides="," >
<if test="userName != null" >
USER_NAME = #{userName,jdbcType=VARCHAR},
</if>
<if test="userPassword != null" >
USER_PASSWORD = #{userPassword,jdbcType=VARCHAR},
</if>
<if test="boUser != null" >
BO_USER = #{boUser,jdbcType=VARCHAR},
</if>
<if test="boPassword != null" >
BO_PASSWORD = #{boPassword,jdbcType=VARCHAR},
</if>
<if test="ncUser != null" >
NC_USER = #{ncUser,jdbcType=VARCHAR},
</if>
<if test="defaultOrg != null" >
DEFAULT_ORG = #{defaultOrg,jdbcType=VARCHAR},
</if>
<if test="isAdmin != null" >
ISADMIN = #{isAdmin,jdbcType=VARCHAR},
</if>
<if test="userGroup != null" >
USER_GROUP = #{userGroup,jdbcType=VARCHAR},
</if>
</trim>
where USER_CODE = #{userCode,jdbcType=VARCHAR}
</update>
<delete id="deleteByUserCode" parameterType="String">
delete from SS_FUND_DIM_PORTALUSER where USER_CODE = #{userCode,jdbcType=VARCHAR}
</delete>
</mapper>
因为我这里涉及到多数据库连接,在mybatis的配置文件中有动态配置的过程,另外还有两个java文件来实现动态分配连接哪个数据库用户。个人猜测是有影响的,因为我一开始只连一个数据库用户的时候基本没有这个报错(可能有,但偶发,而且刷新一下肯定就好了,不像现在刷新好几次都不一定好用),但不能证明
自问自答吧,问题原因我也找到了。
因为使用的是多数据库连接配置,然后我有设置过一个默认连接,如果不是连接默认数据库查询数据,在查询之前会修改连接配置。
比如默认连接A数据库,同时还有B数据库连接存在。当修改连接到B数据库查询数据以后,再去连接A数据库查询数据的时候,我以为是会自动应用默认连接配置,但是实际上还是会应用B数据库的连接配置,此时就会导致查不到表的情况,因此报错。
解决方案是在配置了默认连接的基础上,还在每次查询数据之前,不论是连A还是B,都重新设置一个数据库连接。