简介:本案例是使用使用mybatis来增删改查的一个实例, 它的数据源是多个的,可以随意切换,这在数据量比较大的项目中还是经常要用到的哦。 简单的说有点意思,哈哈。最后测试由于刚好有httpclients的代码就之间拿过来用了。
操作的实体类:
public class User { private int id; private String username; private String password; private String salt; ////////////get/set方法省略///////////// }
数据属性配置文件mybatis-config-datasource.properties
使用mysql数据库,其中%DBNAME%会根据实际情况替换实际连接的数据库。
driver=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/%DBNAME% username=root password=123456
数据库连接配置文件:mybatis-config.xml
使用了C3P0连接池
红色字体部分(最后三行)配置了实体操作配置文件路径
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-config.dtd"> <configuration> <settings> <!-- 全局映射器启用缓存 --> <setting name="cacheEnabled" value="false" /> <!-- 查询时,关闭关联对象即时加载以提高性能 --> <setting name="lazyLoadingEnabled" value="true" /> <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指定),不会加载关联表的所有字段,以提高性能 --> <setting name="aggressiveLazyLoading" value="false" /> <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 --> <setting name="multipleResultSetsEnabled" value="true" /> <!-- 允许使用列标签代替列名 --> <setting name="useColumnLabel" value="true" /> <!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 --> <setting name="useGeneratedKeys" value="true" /> <!-- 给予被嵌套的resultMap以字段-属性的映射支持 --> <setting name="autoMappingBehavior" value="FULL" /> <!-- 对于批量更新操作缓存SQL以提高性能 --> <!-- <setting name="defaultExecutorType" value="BATCH" /> --> <!-- FORSQLSERVER --> <setting name="defaultExecutorType" value="SIMPLE" /> <!-- 数据库超过25000秒仍未响应则超时 --> <setting name="defaultStatementTimeout" value="25000" /> </settings> <typeAliases> <typeAlias type="com.qing.datasource.C3P0DataSourceFactory" alias="C3P0" /> </typeAliases> <environments default="DAG"> <environment id="DAG"> <transactionManager type="JDBC"></transactionManager> <dataSource type="C3P0"> <property name="driverClass" value="${driver}" /> <property name="jdbcUrl" value="${url}" /> <property name="user" value="${username}" /> <property name="password" value="${password}" /> <property name="preferredTestQuery" value="SELECT 1" /> <property name="acquireIncrement" value="3" /> <property name="minPoolSize" value="10" /> <property name="maxPoolSize" value="100" /> <property name="maxIdleTime" value="60" /> </dataSource> </environment> </environments> <mappers> <mapper resource="sqlmapper/UserMapper.xml"/> </mappers> </configuration>
数据库切换的初始化
public class DBNameUtil { private Map<String,String> map = new HashMap<String,String>(); private static DBNameUtil dbName = new DBNameUtil(); private DBNameUtil(){ map.clear(); map.put("dag1", "test"); map.put("dag2", "shiro"); map.put("dag3", "shiroweb"); } public String getDBName(String dagId){ return map.get(dagId); } public static DBNameUtil getInstance(){ return dbName; } }
现在我们应该把这两个配置文件里的数据组合起来
创建Mybatis SqlSessionFactory实例
import java.io.IOException; import java.io.InputStream; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.springframework.util.StringUtils; import com.qing.utils.DBNameUtil; /** * 构造指定DAG ID的Mybatis SqlSessionFactory实例,并进行全局缓存. */ public final class DataSourceSqlSessionFactoryBuilder { private DataSourceSqlSessionFactoryBuilder() {}; /** * Mybatis配置文件名. */ private static final String MYBATIS_CONFIG = "mybatis-config.xml"; /** * Mybatis数据源属性配置文件. */ private static final String MYBATIS_CONFIG_PROPERTIES = "mybatis-config-datasource.properties"; /** * 缓存每个DAG对应的Mybatis数据源. */ private static final Map<String, SqlSessionFactory> DATASOURCE = new ConcurrentHashMap<String, SqlSessionFactory>(); public static SqlSessionFactory buildSqlSessionFactory(String dagID) throws IOException { if (StringUtils.isEmpty(dagID)) { throw new IOException("The DAG id is Empty!"); } if (DATASOURCE.get(dagID) != null) { System.out.println("DDR: get dataSource from cache width dagid[{" + dagID + "}]."); return DATASOURCE.get(dagID); } String dbName = DBNameUtil.getInstance().getDBName(dagID); if (dbName == null) { throw new IOException("The DAG id is not found! " + dagID); } Properties properties = null; SqlSessionFactory sqlSessionFactory = null; InputStream inputStream = Resources.getResourceAsStream(MYBATIS_CONFIG); properties = Resources.getResourceAsProperties(MYBATIS_CONFIG_PROPERTIES); String url = properties.getProperty("url").toString().replace("%DBNAME%", dbName); properties.setProperty("url", url); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,properties); DATASOURCE.put(dagID, sqlSessionFactory); System.out.println("DDR: build dataSource with dagId[{" + dagID + "}] and domain[{" + dbName + "}]."); return DATASOURCE.get(dagID); } }
有了SqlSessionFactory,现在就要创建SqlSession了,但是为方便管理,并且考虑到线程安全以及事物,我们建立一个SessionManager类。
import java.sql.SQLException; import org.apache.ibatis.session.SqlSession; /** * 管理线程上下文持有的 Mybatis SqlSession实例. */ public final class SessionManager { private SessionManager(){}; //当前线程上下文,持有Mybatis SqlSession对象. private static ThreadLocal<SqlSession> sqlSessionHolder = new ThreadLocal<SqlSession>(); //获取当前线程持有的SqlSession对象实例. public static SqlSession getSqlSession() { return sqlSessionHolder.get(); } //设置当前线程持有的SqlSession实例. public static void setSqlSession(SqlSession sqlSession) { sqlSessionHolder.set(sqlSession); } /** * 使用当前线程的SqlSession实例构造指定Mapper实例的代理对象. * @param clazz Mapper接口类型. * @return */ public static <T> T get(Class<T> clazz) { SqlSession session = sqlSessionHolder.get(); try { System.out.println("==> dataSource: {}"+session.getConnection().getMetaData().getURL()); } catch (SQLException e) { e.printStackTrace(); } return sqlSessionHolder.get().getMapper(clazz); } //关闭当前线程持有的SqlSession实例并从其ThreadLocal上下文实例中移除. public static void close() { if (sqlSessionHolder.get() != null) { sqlSessionHolder.get().close(); } sqlSessionHolder.remove(); } /** * 进行数据库事务提交. * @param deltegate 回调接口. * @throws Exception */ public static void transactional(TransactionDelegate deltegate) throws Exception{ SqlSession session = sqlSessionHolder.get(); try { System.out.println("==> dataSource: {}"+session.getConnection().getMetaData().getURL()); } catch (SQLException e) { e.printStackTrace(); } try{ session.commit(false); deltegate.execute(session); session.commit(); }catch(Exception ex){ session.rollback(); throw ex; }finally{ session.commit(true); } } //事务代理接口 public interface TransactionDelegate{ public void execute(SqlSession session) throws Exception; } }
最后就是创建操作实体的接口,以及实体相关配置了
UserMapper.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.qing.mapper.UserMapper"> <resultMap id="BaseResultMap" type="com.qing.entity.User"> <result column="id" jdbcType="TINYINT" property="id" /> <result column="username" jdbcType="VARCHAR" property="username" /> <result column="password" jdbcType="VARCHAR" property="password" /> <result column="salt" jdbcType="VARCHAR" property="salt" /> </resultMap> <sql id="Base_Column_List"> id,username,password,salt </sql> <select id="findByUserName" parameterType="java.lang.String" resultMap="BaseResultMap"> SELECT <include refid="Base_Column_List" /> FROM sys_user_test WHERE username = #{username} </select> <insert id="save" parameterType="com.qing.entity.User" useGeneratedKeys="false"> INSERT INTO sys_user_test (id ,username ,password ,salt ) VALUES ( #{id} ,#{username} ,#{password} ,#{salt} ) </insert> <update id="updateUser" parameterType="com.qing.entity.User"> UPDATE sys_user_test <set > <if test="id != null" > id = #{id}, </if> <if test="username != null"> username = #{username}, </if> <if test="password != null"> password = #{password}, </if> <if test="salt != null"> salt = #{salt}, </if> </set> WHERE id = #{id} </update> </mapper>
操作数据库接口
public interface UserMapper { List<User> findByUserName(String username); void save(User user); int updateUser(User user); }
测试:
新建一个测试的servlet
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("====================MyServlet 我来啦 =================="); String dagId = request.getParameter("dagId"); System.out.println("dagId================>"+dagId); System.out.println("dbName================>"+DBNameUtil.getInstance().getDBName(dagId)); SqlSessionFactory sqlSessionFactory = DataSourceSqlSessionFactoryBuilder.buildSqlSessionFactory(dagId); SessionManager.setSqlSession(sqlSessionFactory.openSession(true)); User user = new User(); user.setId(5); user.setUsername("wang"); user.setPassword("2345134"); user.setSalt(DBNameUtil.getInstance().getDBName(dagId)+user.getId()); SessionManager.get(UserMapper.class).save(user); }
把项目放到tomcat下面启动。
使用的是HttpClients进行测试
public class Test1 { /** * 发送 post请求访问本地应用并根据传递参数不同返回不同结果 */ public void post() { // 创建默认的httpClient实例. CloseableHttpClient httpclient = HttpClients.createDefault(); // 创建httppost HttpPost httppost = new HttpPost("http://localhost:8080/mybatis/MyServlet"); // 创建参数队列 List<NameValuePair> formparams = new ArrayList<NameValuePair>(); formparams.add(new BasicNameValuePair("dagId", "dag2")); UrlEncodedFormEntity uefEntity; try { uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8"); httppost.setEntity(uefEntity); System.out.println("executing request " + httppost.getURI()); CloseableHttpResponse response = httpclient.execute(httppost); try { HttpEntity entity = response.getEntity(); if (entity != null) { System.out.println("--------------------------------------"); System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8")); System.out.println("--------------------------------------"); } } finally { response.close(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 关闭连接,释放资源 try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args) { Test1 t = new Test1(); t.post(); } }
相关推荐
Spring Boot 和 MyBatis 的组合提供了这样的灵活性,可以方便地进行多数据源配置。本项目实例将详细讲解如何在 Spring Boot 中集成 MyBatis 并配置多数据源。 首先,我们需要了解 Spring Boot 中的数据源配置。...
总结,Spring Boot结合MyBatis的多数据源配置为企业级应用提供了强大的数据库管理能力。通过灵活的配置和智能的路由策略,开发者可以轻松地处理复杂的数据源切换需求,提升系统的健壮性和可扩展性。实践这个示例,将...
本项目是基于Spring Boot和MyBatis实现的多数据源配置示例,适合在Spring Tool Suite (STS) 开发环境中运行。 首先,我们需要理解Spring Boot的自动配置特性。Spring Boot通过`@EnableAutoConfiguration`注解简化了...
在提供的"spring整合mybatis多数据源"的demo实例中,你可能能看到上述各个步骤的具体实现,包括配置文件、路由类、以及相关的业务代码。这个实例可以帮助你快速理解并应用到自己的项目中。 总的来说,Spring整合...
myBatis 多数据源配置就是为了解决这样的问题。myBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。与 Spring Boot 结合使用时,可以方便地管理和切换不同的数据源。 首先,我们要理解什么...
总结来说,"Spring+SpringMVC+Mybatis多数据源"的整合涉及了Spring的数据源管理、SpringMVC的请求路由、Mybatis的数据源配置以及事务管理。具体实现时,可以根据项目需求选择合适的方式进行数据源切换,以达到优化...
### Spring 下 MyBatis 多数据源配置详解 在企业级应用开发中,经常会遇到需要同时操作多个数据库的情况。为了实现这一目标,开发者通常会采用多数据源配置的方法。本篇文章将详细介绍如何在Spring框架中配置...
MyBatis的多数据源配置可以通过配置多个MapperFactoryBean和DataSource来实现,每个数据源对应一个特定的配置文件和数据连接。 在Spring Boot 2中,实现多数据源的基本步骤包括: 1. **配置DataSource**:创建两个...
- **application.properties/yml配置**:在SpringBoot的配置文件中,我们需要为每个数据源定义一个数据源配置。例如,我们可以设置两个数据源`primary`和`secondary`,分别对应不同的数据库连接信息,包括URL、...
总结,MyBatis-Plus的多数据源和动态数据源配置能够帮助开发者灵活地处理复杂的数据库环境,提高系统的可扩展性和可维护性。在实际项目中,正确配置和使用这些特性是提升系统性能和稳定性的重要一环。通过深入理解...
4. **MyBatis配置**:在MyBatis的配置文件中,针对每个数据源配置一个`SqlSessionFactory`,并通过`@Resource`或`@Autowired`注入到对应的DAO中。 5. **注解驱动**:在Java配置类中,使用`@...
在多数据源场景下,Mybatis可以通过SqlSessionFactoryBuilder创建多个SqlSessionFactory实例,每个实例对应一个数据源,从而实现数据源的隔离。 实现多数据源通常有以下步骤: 1. **配置数据源**:首先,你需要...
在 Spring 中,我们可以使用 `DataSource` 抽象来表示一个数据源,通过配置多个 `DataSource` 实例,可以轻松地管理和切换这些数据源。 接着,我们来看看如何在 Spring 配置文件中定义多数据源。通常我们会创建两个...
标题 "mybatis spring 多数据源" 涉及到的...总的来说,"mybatis spring 多数据源"的主题涵盖了如何在Java应用中利用MyBatis和Spring进行多数据库管理,包括数据源配置、动态数据源路由、事务管理以及相关工具的使用。
首先,"MyBatis基于源码的多数据源"这个标题暗示了我们将不依赖于第三方库(如Apache的DBCP或C3P0)来处理多数据源,而是直接在MyBatis的源码级别上进行配置和扩展。这种做法的好处是可以更好地控制数据源的选择,...
在多数据源配置中,`SpringBoot` 提供了 `@ConfigurationProperties` 和 `DataSource` 配置类来管理不同的数据源。开发者可以创建多个 `DataSource` 实例,并通过 `@Primary` 或 `@Qualifier` 注解来指定主要数据源...
2. **数据源配置**:接着,你需要创建一个配置类,使用`@Configuration`和`@Bean`注解来实例化多个DataSource对象。Spring Boot提供了`AbstractRoutingDataSource`,可以动态切换数据源。 ```java @Configuration...
7. **实战应用**:在`spring-boot-mybatis-mysql-write-read-master`这个项目中,你将找到实现上述功能的代码示例,包括数据源配置、MyBatis的Mapper配置、Service层的读写操作逻辑等。通过学习和理解这些代码,你...
本DEMO演示了如何在SpringMVC和Mybatis框架中配置多个数据源,并结合Maven进行项目管理,提供了一个实际操作的参考。 首先,我们需要了解SpringMVC和Mybatis的基础。SpringMVC是Spring框架的一部分,主要用于处理...
关于MyBatis的Mapper接口,虽然官方文档建议在多数据源配置时避免自动扫描和装配,但在实际应用中,我们可以根据数据源创建不同的Mapper扫描配置,例如: ```xml <!-- 配置扫描第一个数据源的Mapper接口 --> ...