mybatis使用xml配置多个不同数据源,分别读取

2 篇文章 0 订阅
1 篇文章 0 订阅

转载自https://www.cnblogs.com/chenzhanxun/articles/4654203.html 

mybatis如何配置使用多个数据源? 
一、数据库连接properties配置文件,两个数据源的地址:

hd.jdbc.driverClassName=com.mysql.jdbc.Driver  
hd.jdbc.url=jdbc:mysql://127.0.0.1::3306/hd?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true  
hd.jdbc.username=root  
hd.jdbc.password=root  
  
ho.jdbc.driverClassName=com.mysql.jdbc.Driver  
ho.jdbc.url=jdbc:mysql://127.0.0.1:3306/ho?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true  
ho.jdbc.username=root  
ho.jdbc.password=root  


二、mybatis配置文件,配置两个environment: 

<?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>  
    <properties resource="mybatis/jdbc.properties"/>  
    <environments default="HO">  
        <environment id="HD">  
            <transactionManager type="JDBC" />  
            <dataSource type="POOLED">  
                <property name="driver" value="${hd.jdbc.driverClassName}" />  
                <property name="url" value="${hd.jdbc.url}" />  
                <property name="username" value="${hd.jdbc.username}" />  
                <property name="password" value="${hd.jdbc.password}" />  
            </dataSource>  
        </environment>  
        <environment id="HO">  
            <transactionManager type="JDBC" />  
            <dataSource type="POOLED">  
                <property name="driver" value="${ho.jdbc.driverClassName}" />  
                <property name="url" value="${ho.jdbc.url}" />  
                <property name="username" value="${ho.jdbc.username}" />  
                <property name="password" value="${ho.jdbc.password}" />  
            </dataSource>  
        </environment>  
    </environments>  
</configuration>  

三、获取SqlSessionFactory,获取Mapper代理,便于在执行完Mapper方法后关闭SqlSession。 
SqlSessionFactory的获取: 

/** 
 * 根据mybatis.xml中配置的不同的environment创建对应的SqlSessionFactory 
 * @author boyce 
 * @version 2014-3-27 
 */  
public final class DataSourceSqlSessionFactory {  
    private static final String CONFIGURATION_PATH = "mybatis/mybatis.xml";  
      
    private static final Map<DataSourceEnvironment, SqlSessionFactory> SQLSESSIONFACTORYS   
        = new HashMap<DataSourceEnvironment, SqlSessionFactory>();  
      
    /** 
     * 根据指定的DataSourceEnvironment获取对应的SqlSessionFactory 
     * @param environment 数据源environment 
     * @return SqlSessionFactory 
     */  
    public static SqlSessionFactory getSqlSessionFactory(DataSourceEnvironment environment) {  
          
        SqlSessionFactory sqlSessionFactory = SQLSESSIONFACTORYS.get(environment);  
        if (ObjectUtils.isNotNull(sqlSessionFactory))  
            return sqlSessionFactory;  
        else {  
            InputStream inputStream = null;  
            try {  
                inputStream = Resources.getResourceAsStream(CONFIGURATION_PATH);  
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, environment.name());  
                  
                logger.info("Get {} SqlSessionFactory successfully.", environment.name());  
            } catch (IOException e) {  
                logger.warn("Get {} SqlSessionFactory error.", environment.name());  
                logger.error(e.getMessage(), e);  
            }  
            finally {  
                IOUtils.closeQuietly(inputStream);  
            }  
              
            SQLSESSIONFACTORYS.put(environment, sqlSessionFactory);  
            return sqlSessionFactory;  
        }  
    }  
      
    /** 
     * 配置到Configuration.xml文件中的数据源的environment的枚举描述 
     * @author boyce 
     * @version 2014-3-27 
     */  
    public static enum DataSourceEnvironment {  
        HD,  
        HO;  
    }  
}  

定义一个统一的Mapper标识接口,每一个具体的Mapper接口继承该接口: 

/** 
 * Mapper Interface 
 * @author boyce 
 * @version 2014-3-28 
 */  
public interface Mapper {  
}  

定义一个Mapper代理工厂: 

/** 
 * Mapper Factory 
 * @author boyce 
 * @version 2014-3-28 
 */  
public final class MapperFactory {  
    private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MapperFactory.class);  
    /** 
     * Create a mapper of environment by Mapper class 
     * @param clazz Mapper class  
     * @param environment A datasource environment 
     * @return a Mapper instance 
     */  
    @SuppressWarnings("unchecked")  
    public static <T> T createMapper(Class<? extends Mapper> clazz, DataSourceEnvironment environment) {  
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory(environment);  
        SqlSession sqlSession = sqlSessionFactory.openSession();  
        Mapper mapper = sqlSession.getMapper(clazz);  
        return (T)MapperProxy.bind(mapper, sqlSession);  
    }  
      
    /** 
     * Mapper Proxy  
     * executing mapper method and close sqlsession 
     * @author boyce 
     * @version 2014-4-9 
     */  
    private static class MapperProxy implements InvocationHandler {  
        private Mapper mapper;  
        private SqlSession sqlSession;  
          
        private MapperProxy(Mapper mapper, SqlSession sqlSession) {  
            this.mapper = mapper;  
            this.sqlSession = sqlSession;  
        }  
          
        @SuppressWarnings("unchecked")  
        private static Mapper bind(Mapper mapper, SqlSession sqlSession) {  
            return (Mapper) Proxy.newProxyInstance(mapper.getClass().getClassLoader(),  
                    mapper.getClass().getInterfaces(), new MapperProxy(mapper, sqlSession));  
        }  
  
        /** 
         * execute mapper method and finally close sqlSession 
         */  
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
            Object object = null;  
            try {  
                object = method.invoke(mapper, args);  
            } catch(Exception e) {  
                e.printStackTrace();  
                logger.error(e.getMessage(), e);  
            } finally {  
                sqlSession.close();  
            }  
            return object;  
        }  
    }  
      
    //Get a SqlSessionFactory of environment  
    private static SqlSessionFactory getSqlSessionFactory(DataSourceEnvironment environment) {  
        return DataSourceSqlSessionFactory.getSqlSessionFactory(environment);  
    }  

大功告成,客户端使用: 

UserMapper mapper = MapperFactory.createMapper(UserMapper.class, DataSourceEnvironment.HD);  
User user = mapper.getUserById(162L);  
System.out.println(user);  

OK,到此基本上所有的工作就完成了,以上的方式就可以支持多个数据源了。 
但是代码还不够优雅,以上代码我们发现DataSourceEnvironment这个枚举变量在客户端,MapperFactory以及DataSourceEnvironment 
中传来传去,我们应该尽量减少一个类对外界类的耦合,也就是不符合Java编程原则中的迪米特法则。 
好了,那我们来改良一下。 
将MapperFactory设计成枚举策略模式: 

/** 
 * Mapper Creator 
 * @author boyce 
 * @version 2014-3-28 
 */  
public enum MapperFactory {  
      
    HD {  
        private SqlSessionFactory sqlSessionFactory;  
          
        @Override  
        public <T> T createMapper(Class<? extends Mapper> clazz) {  
            return createMapper(clazz, this);  
        }  
          
        @Override  
        protected void createSqlSessionFactory() {  
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, this.name());  
        }  
          
        @Override  
        public SqlSessionFactory getSqlSessionFactory() {  
            return sqlSessionFactory;  
        }  
          
    },  
    HO {  
        private SqlSessionFactory sqlSessionFactory;  
        @Override  
        public <T> T createMapper(Class<? extends Mapper> clazz) {  
            return createMapper(clazz, this);  
        }  
          
        @Override  
        protected void createSqlSessionFactory() {  
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, this.name());  
        }  
          
        @Override  
        public SqlSessionFactory getSqlSessionFactory() {  
            return sqlSessionFactory;  
        }  
    };  
      
    /** 
     * Create a mapper of environment by Mapper class 
     * @param clazz Mapper class  
     * @param environment A datasource environment 
     * @return a Mapper instance 
     */  
    public abstract <T> T createMapper(Class<? extends Mapper> clazz);  
      
    /** 
     * Create SqlSessionFactory of environment 
     */  
    protected abstract void createSqlSessionFactory();  
      
    /** 
     * get SqlSessionFactory 
     */  
    public abstract SqlSessionFactory getSqlSessionFactory();  
      
    private static InputStream inputStream = null;  
    static {  
        try {  
            inputStream = Resources.getResourceAsStream("mybatis/mybatis.xml");  
            HO.createSqlSessionFactory();  
            HD.createSqlSessionFactory();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            IOUtils.closeQuietly(inputStream);  
        }  
    }  
      
    @SuppressWarnings("unchecked")  
    private static <T> T createMapper(Class<? extends Mapper> clazz, MapperFactory MapperFactory) {  
        SqlSession sqlSession = MapperFactory.getSqlSessionFactory().openSession();  
        Mapper mapper = sqlSession.getMapper(clazz);  
        return (T)MapperProxy.bind(mapper, sqlSession);  
    }  
      
    /** 
     * Mapper Proxy  
     * executing mapper method and close sqlsession 
     * @author boyce 
     * @version 2014-4-9 
     */  
    private static class MapperProxy implements InvocationHandler {  
        private Mapper mapper;  
        private SqlSession sqlSession;  
          
        private MapperProxy(Mapper mapper, SqlSession sqlSession) {  
            this.mapper = mapper;  
            this.sqlSession = sqlSession;  
        }  
          
        private static Mapper bind(Mapper mapper, SqlSession sqlSession) {  
            return (Mapper) Proxy.newProxyInstance(mapper.getClass().getClassLoader(),  
                    mapper.getClass().getInterfaces(), new MapperProxy(mapper, sqlSession));  
        }  
          
        /** 
         * execute mapper method and finally close sqlSession 
         */  
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{  
            Object object = null;  
            try {  
                object = method.invoke(mapper, args);  
            } catch(Exception e) {  
                e.printStackTrace();  
            } finally {  
                sqlSession.close();  
            }  
            return object;  
        }  
    }  
}  

客户端使用场景: 

UserMapper mapper = MapperFactory.HO.createMapper(UserMapper.class);  
User user = mapper.getUserById(162L);  
System.out.println(user);  

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 可以在Java应用程序中使用MyBatis框架来简化数据库访问。MyBatis使用XML配置文件来映射Java对象到数据库表中的记录,这些XML文件描述了如何执行SQL查询和更新操作。MyBatisXML文件通常包括mapper接口和对应的SQL语句。这些SQL语句可以使用参数和结果映射来执行数据库操作,并将结果映射回Java对象。 ### 回答2: MyBatis 是一种开源的持久层框架,它可以与 Java 应用程序集成,用于简化数据库操作。在 MyBatis 中,我们可以使用 XML 文件来配置 SQL 语句,这种方式被广泛应用。 首先,使用 MyBatisXML 文件可以将 SQL 语句与 Java 代码进行分离,使得代码更加清晰和易于维护。通过将 SQL 语句写在 XML 文件中,开发人员可以将精力集中在 Java 代码的编写上,而不用关注 SQL 语句的书写和优化。这样可以提高开发效率,并且降低了出错的概率。 其次,使用 XML 文件配置 SQL 语句还可以实现动态 SQL。在 MyBatis 中,我们可以通过使用 XML 文件中的标签(如 if、choose、foreach 等)来实现根据不同条件生成不同的 SQL 语句。这样可以根据具体的业务需求来动态生成 SQL 语句,而不需要写大量的重复代码。 此外,MyBatis 中的 XML 文件还可以用于配置数据库连接信息、结果映射、数据源、事务管理等。通过配置 XML 文件,开发人员可以方便地进行数据库连接和事务的管理,而不需要手动编写繁琐的数据库连接和事务代码。 总结来说,MyBatis 使用 XML 文件的方式可以简化数据库操作,并且使代码更加易读、易维护。使用 XML 文件可以将 SQL 语句和 Java 代码分离,实现动态 SQL,并提供了方便的配置选项,使得开发更加高效。 ### 回答3: MyBatis是一种流行的Java持久化框架,它使用XML文件来配置持久化操作。在MyBatis中,我们可以通过编写XML文件来定义数据库操作的SQL语句。 XML文件是MyBatis中最重要的配置文件之一,它包含了数据源配置、SQL语句的定义以及结果映射等信息。使用XML文件可以帮助我们更好地组织和管理SQL语句,使得代码更加清晰和易读。 在XML文件中,我们首先需要配置数据源的相关信息,例如数据库的连接URL、用户名、密码等。这些信息将用于建立数据库连接。 接下来,我们可以定义SQL语句。在XML文件中,我们使用<sql>标签来定义SQL语句。通过使用<insert>、<update>、<delete>和<select>等标签,我们可以定义不同类型的SQL操作。在这些标签中,我们可以指定SQL语句的名称、类型以及具体的SQL语句内容。 另外,我们还可以在XML文件中定义结果映射。结果映射用于将查询结果映射为Java对象。我们可以通过使用<resultMap>标签来定义结果映射,通过指定查询返回的列与Java对象中属性的对应关系来实现映射。 最后,在Java代码中使用MyBatis时,我们需要通过读取XML文件来获取配置信息,并根据配置信息建立数据库连接。通过执行SQL语句,我们可以实现对数据库的增删改查操作。在执行SQL语句时,MyBatis会将XML文件中定义的SQL语句解析成具体的SQL语句,并将返回结果映射为Java对象。 总之,使用XML文件是MyBatis的一种常见配置方式,它可以帮助我们更好地组织和管理SQL语句,并将查询结果映射为Java对象。通过使用XML文件,我们可以更加灵活地配置使用MyBatis框架。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值