本文源碼:GitHub·點這裡 || GitEE·點這裡
一、項目案例簡介
1、多資料簡介
實際的項目中,經常會用到不同的資料庫以滿足項目的實際需求。随着業務的并發量的不斷增加,一個項目使用多個資料庫:主從複制、讀寫分離、分布式資料庫等方式,越來越常見。
2、MybatisPlus簡介
MyBatis-Plus(簡稱 MP)是一個MyBatis的增強工具,在MyBatis的基礎上隻做增強不做改變,為簡化開發、提高效率而生。
插件特點
無代碼侵入:隻做增強不做改變,引入它不會對現有工程産生影響。
強大的 CRUD 操作:通過少量配置即可實作單表大部分 CRUD 操作滿足各類使用需求。
支援 Lambda 形式調用:通過 Lambda 表達式,友善的編寫各類查詢條件。
支援主鍵自動生成:可自由配置,解決主鍵問題。
内置代碼生成器:采用代碼或者 Maven 插件可快速生成各層代碼。
内置分頁插件:基于 MyBatis 實體分頁,開發者無需關心具體操作。
内置性能分析插件:可輸出 Sql 語句以及其執行時間。
二、多資料源案例
1、項目結構

注意:mapper層和mapper.xml層分别放在不同目錄下,以便mybatis掃描加載。
2、多資料源配置
spring:
# 資料源配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource
admin-data:
driverClassName: com.mysql.jdbc.Driver
dbUrl: jdbc:mysql://127.0.0.1:3306/cloud-admin-data?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&useSSL=false
username: root
password: 123
initialSize: 20
maxActive: 100
minIdle: 20
maxWait: 60000
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 30
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 30000
maxEvictableIdleTimeMillis: 60000
validationQuery: SELECT 1 FROM DUAL
testOnBorrow: false
testOnReturn: false
testWhileIdle: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
filters: stat,wall
user-data:
driverClassName: com.mysql.jdbc.Driver
dbUrl: jdbc:mysql://127.0.0.1:3306/cloud-user-data?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&useSSL=false
username: root
password: 123
initialSize: 20
maxActive: 100
minIdle: 20
maxWait: 60000
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 30
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 30000
maxEvictableIdleTimeMillis: 60000
validationQuery: SELECT 1 FROM DUAL
testOnBorrow: false
testOnReturn: false
testWhileIdle: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
filters: stat,wall
這裡參數的形式是多樣的,隻需要配置參數掃描即可。
3、參數掃描類
@Component
@ConfigurationProperties(prefix = "spring.datasource.admin-data")
public class DruidOneParam {
private String dbUrl;
private String username;
private String password;
private String driverClassName;
private int initialSize;
private int maxActive;
private int minIdle;
private int maxWait;
private boolean poolPreparedStatements;
private int maxPoolPreparedStatementPerConnectionSize;
private int timeBetweenEvictionRunsMillis;
private int minEvictableIdleTimeMillis;
private int maxEvictableIdleTimeMillis;
private String validationQuery;
private boolean testWhileIdle;
private boolean testOnBorrow;
private boolean testOnReturn;
private String filters;
private String connectionProperties;
// 省略 GET 和 SET
}
4、配置Druid連接配接池
@Configuration
@MapperScan(basePackages = {"com.data.source.mapper.one"},sqlSessionTemplateRef = "sqlSessionTemplateOne")
public class DruidOneConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(DruidOneConfig.class) ;
@Resource
private DruidOneParam druidOneParam ;
@Bean("dataSourceOne")
public DataSource dataSourceOne () {
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(druidOneParam.getDbUrl());
datasource.setUsername(druidOneParam.getUsername());
datasource.setPassword(druidOneParam.getPassword());
datasource.setDriverClassName(druidOneParam.getDriverClassName());
datasource.setInitialSize(druidOneParam.getInitialSize());
datasource.setMinIdle(druidOneParam.getMinIdle());
datasource.setMaxActive(druidOneParam.getMaxActive());
datasource.setMaxWait(druidOneParam.getMaxWait());
datasource.setTimeBetweenEvictionRunsMillis(druidOneParam.getTimeBetweenEvictionRunsMillis());
datasource.setMinEvictableIdleTimeMillis(druidOneParam.getMinEvictableIdleTimeMillis());
datasource.setMaxEvictableIdleTimeMillis(druidOneParam.getMaxEvictableIdleTimeMillis());
datasource.setValidationQuery(druidOneParam.getValidationQuery());
datasource.setTestWhileIdle(druidOneParam.isTestWhileIdle());
datasource.setTestOnBorrow(druidOneParam.isTestOnBorrow());
datasource.setTestOnReturn(druidOneParam.isTestOnReturn());
datasource.setPoolPreparedStatements(druidOneParam.isPoolPreparedStatements());
datasource.setMaxPoolPreparedStatementPerConnectionSize(druidOneParam.getMaxPoolPreparedStatementPerConnectionSize());
try {
datasource.setFilters(druidOneParam.getFilters());
} catch (Exception e) {
LOGGER.error("druid configuration initialization filter", e);
}
datasource.setConnectionProperties(druidOneParam.getConnectionProperties());
return datasource;
}
@Bean
public SqlSessionFactory sqlSessionFactoryOne() throws Exception{
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
factory.setDataSource(dataSourceOne());
factory.setMapperLocations(resolver.getResources("classpath*:/dataOneMapper/*.xml"));
return factory.getObject();
}
@Bean(name="transactionManagerOne")
public DataSourceTransactionManager transactionManagerOne(){
return new DataSourceTransactionManager(dataSourceOne());
}
@Bean(name = "sqlSessionTemplateOne")
public SqlSessionTemplate sqlSessionTemplateOne() throws Exception {
return new SqlSessionTemplate(sqlSessionFactoryOne());
}
}
注意事項
- MapperScan 在指定資料源上配置;
- SqlSessionFactory 配置掃描的Mapper.xml位址 ;
- DataSourceTransactionManager 配置該資料源的事務;
- 兩個資料源的配置手法相同,不贅述 ;
5、操作案例
- 資料源一:簡單查詢
@Service
public class AdminUserServiceImpl implements AdminUserService {
@Resource
private AdminUserMapper adminUserMapper ;
@Override
public AdminUser selectByPrimaryKey (Integer id) {
return adminUserMapper.selectByPrimaryKey(id) ;
}
}
- 資料源二:事務操作
@Service
public class UserBaseServiceImpl implements UserBaseService {
@Resource
private UserBaseMapper userBaseMapper ;
@Override
public UserBase selectByPrimaryKey(Integer id) {
return userBaseMapper.selectByPrimaryKey(id);
}
// 使用指定資料源的事務
@Transactional(value = "transactionManagerTwo")
@Override
public void insert(UserBase record) {
// 這裡資料寫入失敗
userBaseMapper.insert(record) ;
// int i = 1/0 ;
}
}
注意:這裡的需要指定該資料源配置的事務管理器。
三、MybatisPlus案例
1、核心依賴
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.7.1</version>
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.0.7.1</version>
</dependency>
2、配置檔案
mybatis-plus:
mapper-locations: classpath*:/mapper/*.xml
typeAliasesPackage: com.digital.market.*.entity
global-config:
db-config:
id-type: AUTO
field-strategy: NOT_NULL
logic-delete-value: -1
logic-not-delete-value: 0
banner: false
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
cache-enabled: false
call-setters-on-nulls: true
jdbc-type-for-null: 'null'
3、分層配置
mapper層
UserBaseMapper extends BaseMapper<UserBase>
實作層
UserBaseServiceImpl extends ServiceImpl<UserBaseMapper,UserBase> implements UserBaseService
接口層
UserBaseService extends IService<UserBase>
4、mapper.xml檔案
<mapper namespace="com.plus.batis.mapper.UserBaseMapper" >
<resultMap id="BaseResultMap" type="com.plus.batis.entity.UserBase" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="user_name" property="userName" jdbcType="VARCHAR" />
<result column="pass_word" property="passWord" jdbcType="VARCHAR" />
<result column="phone" property="phone" jdbcType="VARCHAR" />
<result column="email" property="email" jdbcType="VARCHAR" />
<result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
<result column="state" property="state" jdbcType="INTEGER" />
</resultMap>
<sql id="Base_Column_List" >
id, user_name, pass_word, phone, email, create_time, update_time, state
</sql>
<select id="selectByParam" parameterType="com.plus.batis.entity.QueryParam" resultMap="BaseResultMap">
select * from hc_user_base
</select>
</mapper>
BaseMapper中的方法都已預設實作;這裡也可以自定義實作一些自己的方法。
5、示範接口
@RestController
@RequestMapping("/user")
public class UserBaseController {
private static final Logger LOGGER = LoggerFactory.getLogger(UserBaseController.class) ;
@Resource
private UserBaseService userBaseService ;
@RequestMapping("/info")
public UserBase getUserBase (){
return userBaseService.getById(1) ;
}
@RequestMapping("/queryInfo")
public String queryInfo (){
UserBase userBase1 = userBaseService.getOne(new QueryWrapper<UserBase>().orderByDesc("create_time")) ;
LOGGER.info("倒叙取值:{}",userBase1.getUserName());
Integer count = userBaseService.count() ;
LOGGER.info("查詢總數:{}",count);
UserBase userBase2 = new UserBase() ;
userBase2.setId(1);
userBase2.setUserName("spring");
boolean resFlag = userBaseService.saveOrUpdate(userBase2) ;
LOGGER.info("儲存更新:{}",resFlag);
Map<String, Object> listByMap = new HashMap<>() ;
listByMap.put("state","0") ;
Collection<UserBase> listMap = userBaseService.listByMap(listByMap) ;
LOGGER.info("ListByMap查詢:{}",listMap);
boolean removeFlag = userBaseService.removeById(3) ;
LOGGER.info("删除資料:{}",removeFlag);
return "success" ;
}
@RequestMapping("/queryPage")
public IPage<UserBase> queryPage (){
QueryParam param = new QueryParam() ;
param.setPage(1);
param.setPageSize(10);
param.setUserName("cicada");
param.setState(0);
return userBaseService.queryPage(param) ;
}
@RequestMapping("/pageHelper")
public PageInfo<UserBase> pageHelper (){
return userBaseService.pageHelper(new QueryParam()) ;
}
}
這裡pageHelper方法是使用PageHelper插件自定義的方法。
四、源代碼位址
GitHub·位址
https://github.com/cicadasmile/middle-ware-parent
GitEE·位址
https://gitee.com/cicadasmile/middle-ware-parent
推薦閱讀:程式設計體系分類整理
序号 | 項目名稱 | GitHub位址 | GitEE位址 | 推薦指數 |
---|---|---|---|---|
01 | Java描述設計模式,算法,資料結構 | GitHub·點這裡 | GitEE·點這裡 | ☆☆☆☆☆ |
02 | Java基礎、并發、面向對象、Web開發 | ☆☆☆☆ | ||
03 | SpringCloud微服務基礎元件案例詳解 | ☆☆☆ | ||
04 | SpringCloud微服務架構實戰綜合案例 | |||
05 | SpringBoot架構基礎應用入門到進階 | |||
06 | SpringBoot架構整合開發常用中間件 | |||
07 | 資料管理、分布式、架構設計基礎案例 | |||
08 | 大資料系列、存儲、元件、計算等架構 |