多数据源、动态数据源 这两篇文章分别详细介绍了springboot、mybatis、druid如何进行静态的多数据源配置,以及动态切换多数据源。本文对二者进行一个整合,即:在一个项目中有多个数据源,每一个数据源分别都是读写分离的进行动态切换。
1、pom.xml:
同之前两篇文章
2、项目结构:
3、application.properties和数据源配置:
1)application.properties
#---------------------使用durid连接池 #---w ds1.w.datasource.url=jdbc:mysql://jy.ttengine.w.abc.db:1883/ttengine?useUnicode=true&characterEncoding=utf8 ds1.w.datasource.username=ttengine ds1.w.datasource.password=TTengine123 ds1.w.datasource.driverClassName=com.mysql.jdbc.Driver #---r ds1.r.datasource.url=jdbc:mysql://jy.ttengine.r.abc.db:1883/ttengine?useUnicode=true&characterEncoding=utf8 ds1.r.datasource.username=ttengine ds1.r.datasource.password=TTengine123 ds1.r.datasource.driverClassName=com.mysql.jdbc.Driver #---pool ds1.datasource.initialSize=20 ds1.datasource.minIdle=20 ds1.datasource.maxActive=200 ds1.datasource.maxWait=60000 ds1.datasource.timeBetweenEvictionRunsMillis=60000 ds1.datasource.minEvictableIdleTimeMillis=300000 ds1.datasource.testWhileIdle=true ds1.datasource.testOnBorrow=false ds1.datasource.testOnReturn=false ds1.datasource.poolPreparedStatements=true ds1.datasource.maxPoolPreparedStatementPerConnectionSize=20 #---------------------使用durid连接池 #---w ds2.w.datasource.url=jdbc:mysql://jy.toutiao.w.abc.db:8907/toutiao?useUnicode=true&characterEncoding=utf8 ds2.w.datasource.username=toutiao ds2.w.datasource.password=^MR7xu5o ds2.w.datasource.driverClassName=com.mysql.jdbc.Driver #---r ds2.r.datasource.url=jdbc:mysql://jy.toutiao.r.abc.db:8907/toutiao?useUnicode=true&characterEncoding=utf8 ds2.r.datasource.username=toutiao ds2.r.datasource.password=^MR7xu5o ds2.r.datasource.driverClassName=com.mysql.jdbc.Driver #---pool ds2.datasource.initialSize=20 ds2.datasource.minIdle=20 ds2.datasource.maxActive=200 ds2.datasource.maxWait=60000 ds2.datasource.timeBetweenEvictionRunsMillis=60000 ds2.datasource.minEvictableIdleTimeMillis=300000 ds2.datasource.testWhileIdle=true ds2.datasource.testOnBorrow=false ds2.datasource.testOnReturn=false ds2.datasource.poolPreparedStatements=true ds2.datasource.maxPoolPreparedStatementPerConnectionSize=20 # 页面默认前缀目录 spring.mvc.view.prefix=/WEB-INF/page/ spring.mvc.view.suffix=.jsp
2)ds1数据源相关代码:
A、自定义数据源切换类:
package cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds1.config; public class DatabaseContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static void setDBKey(String dataSourceKey) { contextHolder.set(dataSourceKey); } public static String getDBKey() { return contextHolder.get(); } public static void clearDBKey() { contextHolder.remove(); } }
B、自定义DynamicDataSource:
package cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds1.config; import java.util.HashMap; import java.util.Map; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; /** * 动态数据源 * @author kevinliu * */ public class DynamicDataSource extends AbstractRoutingDataSource { private static DynamicDataSource instance; private static byte[] lock=new byte[0]; private static Map<Object,Object> dataSourceMap=new HashMap<Object, Object>(); @Override public void setTargetDataSources(Map<Object, Object> targetDataSources) { super.setTargetDataSources(targetDataSources); dataSourceMap.putAll(targetDataSources); super.afterPropertiesSet();// 必须添加该句,否则新添加数据源无法识别到 } public Map<Object, Object> getDataSourceMap() { return dataSourceMap; } @Override protected Object determineCurrentLookupKey() { String dbKey = DatabaseContextHolder.getDBKey(); /*if (StringUtils.isBlank(dbKey)) { dbKey = "read"; }*/ return dbKey; } private DynamicDataSource() {} public static synchronized DynamicDataSource getInstance(){ if(instance==null){ synchronized (lock){ if(instance==null){ instance=new DynamicDataSource(); } } } return instance; } }
C、定制DataSourceConfig::
package cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds1.config; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; @Configuration //扫描 Mapper 接口并容器管理 @MapperScan(basePackages = DatasourceConfig.PACKAGE, sqlSessionFactoryRef = "sqlSessionFactory") public class DatasourceConfig { // 精确到 master 目录,以便跟其他数据源隔离 static final String PACKAGE = "cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds1"; static final String MAPPER_LOCATION = "classpath:mapper/ds1/*.xml"; @Value("${ds1.w.datasource.url}") private String wurl; @Value("${ds1.w.datasource.username}") private String wuser; @Value("${ds1.w.datasource.password}") private String wpassword; @Value("${ds1.w.datasource.driverClassName}") private String wdriverClass; @Value("${ds1.r.datasource.url}") private String rurl; @Value("${ds1.r.datasource.username}") private String ruser; @Value("${ds1.r.datasource.password}") private String rpassword; @Value("${ds1.r.datasource.driverClassName}") private String rdriverClass; @Value("${ds1.datasource.maxActive}") private Integer maxActive; @Value("${ds1.datasource.minIdle}") private Integer minIdle; @Value("${ds1.datasource.initialSize}") private Integer initialSize; @Value("${ds1.datasource.maxWait}") private Long maxWait; @Value("${ds1.datasource.timeBetweenEvictionRunsMillis}") private Long timeBetweenEvictionRunsMillis; @Value("${ds1.datasource.minEvictableIdleTimeMillis}") private Long minEvictableIdleTimeMillis; @Value("${ds1.datasource.testWhileIdle}") private Boolean testWhileIdle; @Value("${ds1.datasource.testWhileIdle}") private Boolean testOnBorrow; @Value("${ds1.datasource.testOnBorrow}") private Boolean testOnReturn; @Bean(name = "dynamicDataSource") @Primary public DynamicDataSource dynamicDataSource() { DynamicDataSource dynamicDataSource = DynamicDataSource.getInstance(); //jdbc配置 DruidDataSource wdataSource = new DruidDataSource(); wdataSource.setDriverClassName(wdriverClass); wdataSource.setUrl(wurl); wdataSource.setUsername(wuser); wdataSource.setPassword(wpassword); //连接池配置 wdataSource.setMaxActive(maxActive); wdataSource.setMinIdle(minIdle); wdataSource.setInitialSize(initialSize); wdataSource.setMaxWait(maxWait); wdataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); wdataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); wdataSource.setTestWhileIdle(testWhileIdle); wdataSource.setTestOnBorrow(testOnBorrow); wdataSource.setTestOnReturn(testOnReturn); wdataSource.setValidationQuery("SELECT 'x'"); wdataSource.setPoolPreparedStatements(true); wdataSource.setMaxPoolPreparedStatementPerConnectionSize(20); try { wdataSource.setFilters("stat"); } catch (SQLException e) { e.printStackTrace(); } //jdbc配置 DruidDataSource rdataSource = new DruidDataSource(); rdataSource.setDriverClassName(rdriverClass); rdataSource.setUrl(rurl); rdataSource.setUsername(ruser); rdataSource.setPassword(rpassword); //连接池配置 rdataSource.setMaxActive(maxActive); rdataSource.setMinIdle(minIdle); rdataSource.setInitialSize(initialSize); rdataSource.setMaxWait(maxWait); rdataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); rdataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); rdataSource.setTestWhileIdle(testWhileIdle); rdataSource.setTestOnBorrow(testOnBorrow); rdataSource.setTestOnReturn(testOnReturn); rdataSource.setValidationQuery("SELECT 'x'"); rdataSource.setPoolPreparedStatements(true); rdataSource.setMaxPoolPreparedStatementPerConnectionSize(20); try { rdataSource.setFilters("stat"); } catch (SQLException e) { e.printStackTrace(); } Map<Object,Object> map = new HashMap<>(); map.put("ds1_w", wdataSource); map.put("ds1_r", rdataSource); dynamicDataSource.setTargetDataSources(map); dynamicDataSource.setDefaultTargetDataSource(rdataSource); return dynamicDataSource; } @Bean(name = "transactionManager") @Primary public DataSourceTransactionManager transactionManager() { return new DataSourceTransactionManager(dynamicDataSource()); } @Bean(name = "sqlSessionFactory") @Primary public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dynamicDataSource) throws Exception { final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(dynamicDataSource); sessionFactory.setTypeAliasesPackage("cn.edu.nuc.springbootmybatisdynamicmutilds.entity"); sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(DatasourceConfig.MAPPER_LOCATION)); return sessionFactory.getObject(); } @Bean public ServletRegistrationBean druidServlet() { ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(); servletRegistrationBean.setServlet(new StatViewServlet()); servletRegistrationBean.addUrlMappings("/druid/*"); Map<String, String> initParameters = new HashMap<String, String>(); initParameters.put("loginUsername", "admin");// 用户名 initParameters.put("loginPassword", "admin");// 密码 initParameters.put("resetEnable", "false");// 禁用HTML页面上的“Reset All”功能 initParameters.put("allow", ""); // IP白名单 (没有配置或者为空,则允许所有访问) //initParameters.put("deny", "192.168.20.38");// IP黑名单 (存在共同时,deny优先于allow) servletRegistrationBean.setInitParameters(initParameters); return servletRegistrationBean; } @Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(new WebStatFilter()); filterRegistrationBean.addUrlPatterns("/*"); filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); return filterRegistrationBean; } }
3)同样ds2:
A、自定义数据源切换类:
package cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds2.config; public class Ds2DatabaseContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static void setDBKey(String dataSourceKey) { contextHolder.set(dataSourceKey); } public static String getDBKey() { return contextHolder.get(); } public static void clearDBKey() { contextHolder.remove(); } }
B、DynamicDataSource:
package cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds2.config; import java.util.HashMap; import java.util.Map; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; /** * 动态数据源 * @author kevinliu * */ public class Ds2DynamicDataSource extends AbstractRoutingDataSource { private static Ds2DynamicDataSource instance; private static byte[] lock=new byte[0]; private static Map<Object,Object> dataSourceMap=new HashMap<Object, Object>(); @Override public void setTargetDataSources(Map<Object, Object> targetDataSources) { super.setTargetDataSources(targetDataSources); dataSourceMap.putAll(targetDataSources); super.afterPropertiesSet();// 必须添加该句,否则新添加数据源无法识别到 } public Map<Object, Object> getDataSourceMap() { return dataSourceMap; } @Override protected Object determineCurrentLookupKey() { String dbKey = Ds2DatabaseContextHolder.getDBKey(); /*if (StringUtils.isBlank(dbKey)) { dbKey = "read"; }*/ return dbKey; } private Ds2DynamicDataSource() {} public static synchronized Ds2DynamicDataSource getInstance(){ if(instance==null){ synchronized (lock){ if(instance==null){ instance=new Ds2DynamicDataSource(); } } } return instance; } }
C、config:
package cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds2.config; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; @Configuration //扫描 Mapper 接口并容器管理 @MapperScan(basePackages = Ds2DatasourceConfig.PACKAGE, sqlSessionFactoryRef = "ds2SqlSessionFactory") public class Ds2DatasourceConfig { // 精确到 master 目录,以便跟其他数据源隔离 static final String PACKAGE = "cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds2"; static final String MAPPER_LOCATION = "classpath:mapper/ds2/*.xml"; @Value("${ds2.w.datasource.url}") private String wurl; @Value("${ds2.w.datasource.username}") private String wuser; @Value("${ds2.w.datasource.password}") private String wpassword; @Value("${ds2.w.datasource.driverClassName}") private String wdriverClass; @Value("${ds2.r.datasource.url}") private String rurl; @Value("${ds2.r.datasource.username}") private String ruser; @Value("${ds2.r.datasource.password}") private String rpassword; @Value("${ds2.r.datasource.driverClassName}") private String rdriverClass; @Value("${ds2.datasource.maxActive}") private Integer maxActive; @Value("${ds2.datasource.minIdle}") private Integer minIdle; @Value("${ds2.datasource.initialSize}") private Integer initialSize; @Value("${ds2.datasource.maxWait}") private Long maxWait; @Value("${ds2.datasource.timeBetweenEvictionRunsMillis}") private Long timeBetweenEvictionRunsMillis; @Value("${ds2.datasource.minEvictableIdleTimeMillis}") private Long minEvictableIdleTimeMillis; @Value("${ds2.datasource.testWhileIdle}") private Boolean testWhileIdle; @Value("${ds2.datasource.testWhileIdle}") private Boolean testOnBorrow; @Value("${ds2.datasource.testOnBorrow}") private Boolean testOnReturn; @Bean(name = "ds2DynamicDataSource") public Ds2DynamicDataSource ds2DynamicDataSource() { Ds2DynamicDataSource dynamicDataSource = Ds2DynamicDataSource.getInstance(); //jdbc配置 DruidDataSource wdataSource = new DruidDataSource(); wdataSource.setDriverClassName(wdriverClass); wdataSource.setUrl(wurl); wdataSource.setUsername(wuser); wdataSource.setPassword(wpassword); //连接池配置 wdataSource.setMaxActive(maxActive); wdataSource.setMinIdle(minIdle); wdataSource.setInitialSize(initialSize); wdataSource.setMaxWait(maxWait); wdataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); wdataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); wdataSource.setTestWhileIdle(testWhileIdle); wdataSource.setTestOnBorrow(testOnBorrow); wdataSource.setTestOnReturn(testOnReturn); wdataSource.setValidationQuery("SELECT 'x'"); wdataSource.setPoolPreparedStatements(true); wdataSource.setMaxPoolPreparedStatementPerConnectionSize(20); try { wdataSource.setFilters("stat"); } catch (SQLException e) { e.printStackTrace(); } //jdbc配置 DruidDataSource rdataSource = new DruidDataSource(); rdataSource.setDriverClassName(rdriverClass); rdataSource.setUrl(rurl); rdataSource.setUsername(ruser); rdataSource.setPassword(rpassword); //连接池配置 rdataSource.setMaxActive(maxActive); rdataSource.setMinIdle(minIdle); rdataSource.setInitialSize(initialSize); rdataSource.setMaxWait(maxWait); rdataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); rdataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); rdataSource.setTestWhileIdle(testWhileIdle); rdataSource.setTestOnBorrow(testOnBorrow); rdataSource.setTestOnReturn(testOnReturn); rdataSource.setValidationQuery("SELECT 'x'"); rdataSource.setPoolPreparedStatements(true); rdataSource.setMaxPoolPreparedStatementPerConnectionSize(20); try { rdataSource.setFilters("stat"); } catch (SQLException e) { e.printStackTrace(); } Map<Object,Object> map = new HashMap<>(); map.put("ds2_w", wdataSource); map.put("ds2_r", rdataSource); dynamicDataSource.setTargetDataSources(map); dynamicDataSource.setDefaultTargetDataSource(rdataSource); return dynamicDataSource; } @Bean(name = "ds2TransactionManager") public DataSourceTransactionManager ds2TransactionManager() { return new DataSourceTransactionManager(ds2DynamicDataSource()); } @Bean(name = "ds2SqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("ds2DynamicDataSource") DataSource dynamicDataSource) throws Exception { final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(dynamicDataSource); sessionFactory.setTypeAliasesPackage("cn.edu.nuc.springbootmybatisdynamicmutilds.entity"); sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(Ds2DatasourceConfig.MAPPER_LOCATION)); return sessionFactory.getObject(); } @Bean public ServletRegistrationBean druidServlet() { ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(); servletRegistrationBean.setServlet(new StatViewServlet()); servletRegistrationBean.addUrlMappings("/druid/*"); Map<String, String> initParameters = new HashMap<String, String>(); initParameters.put("loginUsername", "admin");// 用户名 initParameters.put("loginPassword", "admin");// 密码 initParameters.put("resetEnable", "false");// 禁用HTML页面上的“Reset All”功能 initParameters.put("allow", ""); // IP白名单 (没有配置或者为空,则允许所有访问) //initParameters.put("deny", "192.168.20.38");// IP黑名单 (存在共同时,deny优先于allow) servletRegistrationBean.setInitParameters(initParameters); return servletRegistrationBean; } @Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(new WebStatFilter()); filterRegistrationBean.addUrlPatterns("/*"); filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); return filterRegistrationBean; } }
4、其他:
1)controller:
package cn.edu.nuc.springbootmybatisdynamicmutilds.controller; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import cn.edu.nuc.springbootmybatisdynamicmutilds.entity.Test; import cn.edu.nuc.springbootmybatisdynamicmutilds.service.TestService; @Controller public class TestController { private static final Logger logger = LoggerFactory.getLogger(TestController.class); @Autowired private TestService testService; @RequestMapping("/test") @ResponseBody public String test(HttpServletRequest request) { String name = request.getParameter("name"); Test test = null; try { test = testService.findByName(name); } catch (Exception e) { test = new Test(); logger.error("test error.",e); } logger.info("test....{}",name); return test.toString(); } @RequestMapping("/save") @ResponseBody public String saveTest(HttpServletRequest request) { String res = "0"; String name = request.getParameter("name"); try { testService.saveTest(name); } catch (Exception e) { res = "1"; logger.error("save test error.",e); } logger.info("save test....{}",name); return res; } }
2)service:
package cn.edu.nuc.springbootmybatisdynamicmutilds.service; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds1.TestDao; import cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds1.config.DatabaseContextHolder; import cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds2.DemoDao; import cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds2.config.Ds2DatabaseContextHolder; import cn.edu.nuc.springbootmybatisdynamicmutilds.entity.Demo; import cn.edu.nuc.springbootmybatisdynamicmutilds.entity.Test; @Service public class TestService{ private static final Logger logger = LoggerFactory.getLogger(TestService.class); @Autowired private TestDao testDao; @Autowired private DemoDao demoDao; public Test findByName(String name) throws Exception{ List<Demo> demoList = demoDao.getDemoList(); logger.info(demoList.toString()); return testDao.findByName(name); } public void saveTest(String name) throws Exception{ logger.info("saveTest..."); DatabaseContextHolder.setDBKey("ds1_w"); Test t = new Test(); t.setName(name); testDao.saveTest(t); Ds2DatabaseContextHolder.setDBKey("ds2_w"); Demo demo = new Demo(); demo.setTitle(name); demo.setDescs(name+",desc"); demo.setId(2L); demoDao.updateDeomo(demo); } }
3)entity:
package cn.edu.nuc.springbootmybatisdynamicmutilds.entity; public class Test { private Long id; private String name; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Test [id=" + id + ", name=" + name + "]"; } }
package cn.edu.nuc.springbootmybatisdynamicmutilds.entity; public class Demo { private Long id; private String title; private String descs; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescs() { return descs; } public void setDescs(String descs) { this.descs = descs; } @Override public String toString() { return "Demo [id=" + id + ", title=" + title + ", descs=" + descs + "]"; } }
4)dao:
package cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds1; import org.apache.ibatis.annotations.Param; import cn.edu.nuc.springbootmybatisdynamicmutilds.entity.Test; public interface TestDao { Test findByName(@Param("name") String n); void saveTest(Test t) throws Exception; }
package cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds2; import java.util.List; import cn.edu.nuc.springbootmybatisdynamicmutilds.entity.Demo; public interface DemoDao { List<Demo> getDemoList() throws Exception; void updateDeomo(Demo demo) throws Exception; }
5)mapper文件
<?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="cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds1.TestDao"> <resultMap id="BaseResultMap" type="cn.edu.nuc.springbootmybatisdynamicmutilds.entity.Test"> <result column="id" property="id" /> <result column="name" property="name" /> </resultMap> <parameterMap id="Test" type="cn.edu.nuc.springbootmybatisdynamicmutilds.entity.Test"/> <sql id="Base_Column_List"> id,name </sql> <select id="findByName" resultMap="BaseResultMap" parameterType="java.lang.String"> select <include refid="Base_Column_List" /> from test where name = #{name} </select> <!-- 插入 --> <insert id="saveTest" parameterType="Test"> insert into test (name) values (#{name}) </insert> </mapper>
<?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="cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql.ds2.DemoDao"> <resultMap id="BaseResultMap" type="cn.edu.nuc.springbootmybatisdynamicmutilds.entity.Demo"> <result column="id" property="id" /> <result column="title" property="title" /> <result column="descs" property="descs" /> </resultMap> <parameterMap id="Demo" type="cn.edu.nuc.springbootmybatisdynamicmutilds.entity.Demo"/> <sql id="Base_Column_List"> id,title,descs </sql> <select id="getDemoList" resultType="Demo"> select <include refid="Base_Column_List" /> from demo </select> <!-- 更新 --> <update id="updateDeomo" parameterType="Demo"> update demo set <![CDATA[ title=#{title}, descs = #{descs} ]]> where id=#{id} </update> </mapper>
6)主类:
package cn.edu.nuc.springbootmybatisdynamicmutilds; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Hello world! * 可以统一用@MapperScan指定扫描的dao,也可以在每个dao上添加@Mapper */ @SpringBootApplication //mapper 接口类扫描包配置 @MapperScan("cn.edu.nuc.springbootmybatisdynamicmutilds.dao.mysql") public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args); } }