How to solve design problem in my application using Spring + iBatis

We use Spring + iBatis in all our DAOs to retrieve data from stored procedures.

There are two main JNDI connections. one goes in datawarehouseand the other goes in livedb.

the SP package has recently been moved from a living wage to a data warehouse and vice versa.

This creates problems on the part of java because:

Now, each DAO does not directly relate to a data warehouse or liveb. In the DAO, there may be methods related to the data warehouse, and others may be related to liveb. To do this, we need to change sqlMapClientTemplate(because Spring does dao has a one-to-one mapping with a JNDI connection). Therefore, we do this:

this.setSqlMapClientTemplate(getSqlTemplDW()); //get connection to DW
getSqlMapClientTemplate().queryForList("dw_sps.somemapping", parmMap);
this.setSqlMapClientTemplate(getSqlTempl()); //set connection to live db

as you can see ... this makes us have a lot of the same code in a bunch of places.

Questions

Is this considered a design flaw for one DAO to talk to two different JNDIs? (I know this is not a design error in classic Taoist JDBC, but is it different from Spring + iBatis?)

the getSqlTemplDW () method you see looks like this:

public SqlMapClientTemplate getSqlTemplDW() {
    SqlMapClient scl = (SqlMapClient) ApplicationInitializer.getApplicationContext().getBean("SqlMapClientDW");
    DataSource dsc = (DataSource) ApplicationInitializer.getApplicationContext().getBean("DataSourceDW");
    return new SqlMapClientTemplate(dsc, scl);
}

as you can see i am using javax.sql.DataSource. However, we were told not to use this import! So now I'm stuck. I cannot use this import (i.e. I cannot change the connections in my DAO). Therefore, I get suggestions that each Tao should have only one to one mapping to JNDI.

I want to know ... is there a way around this?

Skeleton

spring-for-ibatis.xml

<bean id="datasource1" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/RSRC/asdf/sdf/oltp"/>
</bean>

<bean id="datasource2" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/RSRC/asdf/efs/dw"/>
</bean>

<bean id="sqlMapClient1" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
  <property name="configLocation" value="classpath:sql-map-config-oracle.xml"/>
  <property name="dataSource" ref="datasource1"/>
</bean>

<bean id="sqlMapClient2" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
  <property name="configLocation" value="classpath:sql-map-config-dw.xml"/>
  <property name="dataSource" ref="datasource2"/>
</bean>

<!--dao bean-->
<bean id="examinationIfaceDAO" class="some.path.ExaminationIbatisDAO">
  <property name="sqlMapClient" ref="sqlMapClient1"/>
  <property name="dataSource" ref="datasource1"/>
</bean>

SQL-map-config-oracle.xml

<sqlMapConfig>
   <settings enhancementEnabled="true" useStatementNamespaces="true" />
        <sqlMap resource="iBatis_file_with_sps_to_live_db.xml"/>
</sqlMapConfig>

Sql-map-config-dw.xml

<sqlMapConfig>
   <settings enhancementEnabled="true" useStatementNamespaces="true" />
    <sqlMap resource="iBatis_file_with_sps_to_dw.xml" />
</sqlMapConfig>

Interface for exam

 public interface ExaminationIfaceDAO {
    public boolean goToDW(String userId);
    public boolean goToLiveDB(String userId);
 }

ExaminationIbatisDAO

 public class ExaminationIbatisDAO implements EexaminationIfaceDAO {
    public boolean goToDW(String userId) {
        HashMap paramMap = new HashMap();
        paramMap.put("userId", userId);
        //following line will break as it does not know about this mapping file
        getSqlMapClientTemplate().queryForObject("iBatis_file_with_sps_to_dw.isAuthorized", paramMap);
        return true;
    }
    public boolean goToLiveDB(String userId) {
        HashMap paramMap = new HashMap();
        paramMap.put("userId", userId);
        //following line will be ok as it knows about this mapping file
        getSqlMapClientTemplate().queryForObject("iBatis_file_with_sps_to_live_db.isAuthorized", paramMap);
        return true;
    }
 }

-

examDAO = (ExaminationIfaceDAO)ApplicationInitializer.getApplicationContext().getBean("eexaminationIfaceDAO");
boolean b = reexamDAO.goToDW("myuserid");
+3
3

( ) , , , DAO spring beans. : "spring dao JNDI"; . ( spring) DataSource beans ( ) SqlMapClientTemplate beans. DAO SqlMapClientTemplate beans ( ) , . - ?

: , , , dao, , getSqlMapClientTemplate(), : getSqlMapClientTemplateDb1() getSqlMapClientTemplateDb2() - .

, .

, DAO , . , / , . , , IUserDao public User getUser(int id) - say- UserDaoPostgresql UserDaoMysql; ( ). , - DAO, , (, Spring) , , . ( , , - ), dao ( ) .

. , Postgresql , - Mysql db ( Pg db db, ). , DAO , , IUserDao getUser(int userid) getUserHistory(int userid), , ( ) . DAO.

, , .

+1

JDBC , , . , , , ( RDBMS ).

0

It would be best to reorganize your DAOs. Something like that.

public interface ExaminationIfaceDAO {
   boolean checkUser(String userId);
}

public class OracleExaminationDAO implements ExaminationIfaceDAO{
   public boolean checkUser(String userId){
      //TO:DO
   }
}
public class DWExaminationDAO implements ExaminationIfaceDAO{
  public boolean checkUser(String userId){
      //TO:DO
  }
}

Your DAOs appear to be single, and it is not recommended that you switch data sources like this. You can also consider creating two different beans of the same type with one livb data source and one with a dw data source. And use the appropriate bean for your task.

<bean id="examinationDBDAO" class="some.path.ExaminationIbatisDAO">
 <property name="sqlMapClient" ref="sqlMapClient1"/>
 <property name="dataSource" ref="datasource1"/>
</bean>
<bean id="examinationDWDAO" class="some.path.ExaminationIbatisDAO">
 <property name="sqlMapClient" ref="sqlMapClient1"/>
 <property name="dataSource" ref="datasource2"/>
</bean>
0
source

Source: https://habr.com/ru/post/1750273/


All Articles