记录:268
场景:一个应用中完成一个业务需操作两个不同的数据库。
版本:spring-boot 2.4.5,mybatis-plus 3.5.0
数据库:fjdb,fzdb
数据表:sys_user(在fjdb库中),sys_role(在fzdb)
一、说明
1.配置说明
(1)在application.yml文件中,有fjdb,fzdb各自独立的数据源配置信息。
(2)在配置属性类DataSourceProperties,各个属性对应application.yml数据源属性。
(3)在FjdbDataSourceProperties类中,加载fjdb数据库数据源信息。
(4)在FzdbDataSourceProperties类中,加载fzdb数据库数据源信息。
(5)在FjdbMybatisConfig类中,生成Mybatis访问Fjdb数据库相关配置信息。
(6)在FzdbMybatisConfig类中,生成Mybatis访问Fzdb数据库相关配置信息。
2.扫描包和xml路径说明
(1)针对fjdb数据库,Mybatis扫描包和xml路径说明
com.hub.dao.fjdb.SysUserDao
resourcesmapperfjdbSysUserDao.xml
(1)针对fzdb数据库,Mybatis扫描包和xml路径说明
com.hub.dao.fzdb.SysRoleDao
resourcesmapperfzdbSysRoleDao.xml
3.调用说明
(1)前台发起http请求,
(2)WorkController处理post请求
(3)WorkServiceImpl处理任务,通过SysUserDao操作fjdb数据库;通过SysRoleDao操作fzdb数据库。
二、代码
1.配置类
1.1 数据配置基类-DataSourceProperties
DataSourceProperties属性值,直接从yml文件中以注解方式加载。
@Data
public class DataSourceProperties {
private String driverClassName;
private String url;
private String username;
private String password;
private int initialSize = 2;
private int maxActive = 10;
private int minIdle = -1;
private long maxWait = 60 * 1000L;
private boolean poolPreparedStatements = false;
private long maxPoolPreparedStatementPerConnectionSize = 20;
private long timeBetweenEvictionRunsMillis = 60 * 1000L;
private long minEvictableIdleTimeMillis = 1000L * 60L * 30L;
private long maxEvictableIdleTimeMillis = 1000L * 60L * 60L * 7;
private String validationQuery = "select 1";
private boolean testWhileIdle = true;
private boolean testonBorrow = false;
private boolean testonReturn = false;
private int validationQueryTimeout = -1;
private int maxOpenPreparedStatements = -1;
private boolean sharePreparedStatements = false;
private String filters = "stat,wall";
}
1.2 fjdb数据源属性,FjdbDataSourceProperties
注解说明:
@Component:生成Bean
@ConfigurationProperties:加载yml配置文件指定前缀的属性。
@PostConstruct:对已经加载的属性进行修改,比如某些属性在配置文件中是加密的,在此处可以解密。
InitializingBean接口:实现接口,即Bean初始化完成后执行afterPropertiesSet。
操作Fjdb数据源相关属性:
@Component
@ConfigurationProperties(prefix = "fjdb.datasource.druid", ignoreUnknownFields = true)
public class FjdbDataSourceProperties extends DataSourceProperties implements InitializingBean {
@PostConstruct
public void init() {
}
@Override
public void afterPropertiesSet() throws Exception {
}
}
1.3 fzdb数据源属性,FzdbDataSourceProperties
操作fzdb数据源相关属性:
@Component
@ConfigurationProperties(prefix = "fzdb.datasource.druid", ignoreUnknownFields = true)
public class FzdbDataSourceProperties extends DataSourceProperties implements InitializingBean {
@PostConstruct
public void init() {
}
@Override
public void afterPropertiesSet() throws Exception {
}
}
1.4 fjdb数据源对应Mybatis配置,FjdbMybatisConfig
注解说明
@Configuration:定义配置类
@MapperScan:属性basePackages定义Mybatis扫描的包;属性sqlSessionFactoryRef定义Mybatis要引用的会话工厂SqlSessionFactory的实例。
@Bean(name="fjdbDataSource"):定义数据源。
@Bean(name = "fjdbTransactionManager"):定义事务管理器。
@Bean(name = "fjdbSqlSessionFactory"):定义会话工厂。在会话工厂中配合Mybatis的各种属性,设置到会话工厂中。GlobalConfig相关的配置,通过GlobalConfigUtils的setGlobalConfig方法,关联MybatisConfiguration,GlobalConfig进行设置。
@Qualifier("fjdbDataSource"):指定使用命名的Bean实例。
操作fjdb数据源相关属性:
@Configuration
@MapperScan(basePackages = FjdbMybatisConfig.PACKAGE,
sqlSessionFactoryRef = "fjdbSqlSessionFactory")
public class FjdbMybatisConfig {
public static final String PACKAGE = "com.hub.dao.fjdb";
public static final String MAPPER_LOCATION = "classpath:mapper/fjdb
@Mapper
public interface SysUserDao {
SysUserModel queryByUserName(String username);
}
2.2 扫描操作fzdb数据源的接口,SysRoleDao
@Mapper:注解标识为Mybatis映射的接口。
import com.hub.model.SysRoleModel;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SysRoleDao {
SysRoleModel queryByCreateId(String createUserId);
}
3.Mybatis扫描的xml配置
3.1 扫描操作fjdb数据源的配置,SysUserDao.xml
配置文件如下:
3.2 扫描操作fzdb数据源的配置,SysRoleDao.xml
配置文件如下:
4.实体类
4.1 入参FormModel类
@Data
public class FormModel implements Serializable {
private String username;
private String password;
}
4.2 表对应实体类SysUserModel
@Data
@TableName("sys_user")
public class SysUserModel implements Serializable {
@TableId
private Long userId;
private String username;
private String password;
private Long createUserId;
private Date createTime;
}
4.3 表对应实体类SysRoleModel
@Data
@TableName("sys_role")
public class SysRoleModel implements Serializable {
@TableId
private Long roleId;
private String roleName;
private Long createUserId;
private Date createTime;
}
5.service类
5.1 接口IWorkService
public interface IWorkService {
Map wokr(FormModel form);
}
5.2 实现WorkServiceImpl
@Service
public class WorkServiceImpl implements IWorkService {
@Autowired
private SysUserDao user;
@Autowired
private SysRoleDao role;
@Override
public Map wokr(FormModel form) {
SysUserModel userModel = user.queryByUserName(form.getUsername());
SysRoleModel roleModel = role.queryByCreateId(String.valueOf(userModel.getCreateUserId()));
Map map = new HashMap<>();
map.put("userName",form.getUsername());
map.put("roleName",roleModel.getRoleName());
return map;
}
}
6.Controller类
如下:
@RestController
@RequestMapping("/sys")
public class WorkController {
private static final Logger logger = LoggerFactory.getLogger(WorkController.class);
@Autowired
private IWorkService workService;
@PostMapping("/work")
public Map work(@RequestBody FormModel formModel){
Map map = workService.wokr(formModel);
logger.info("返回数据: " + map.toString());
return map ;
}
}
7.启动类
如下:
@SpringBootApplication
public class ExamplesApplication {
public static void main(String[] args) {
SpringApplication.run(ExamplesApplication.class);
}
}
8.本例pom.xml文件
org.springframework.boot spring-bootorg.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-actuatororg.springframework.boot spring-boot-devtoolsruntime true org.projectlombok lomboktrue mysql mysql-connector-javacom.alibaba druid-spring-boot-startercom.baomidou mybatis-plus-boot-starterorg.springframework.boot spring-boot-configuration-processortrue
9.建表语句
9.1 sys_user
CREATE TABLE sys_user (
user_id BIGINT(16) NOT NULL AUTO_INCREMENT,
username VARCHAr(64) COLLATE utf8_bin NOT NULL COMMENT '用户名',
PASSWORD VARCHAr(64) COLLATE utf8_bin DEFAULT NULL COMMENT '密码',
create_user_id BIGINT(16) DEFAULT NULL COMMENT '创建者ID',
create_time DATETIME DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (user_id),
UNIQUE KEY username (username)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='用户';
INSERT INTO sys_user(user_id,username,PASSWORD,create_user_id,create_time)
VALUE(20220101,'admin','123456789',2022010156,'2022-3-23 23:58:59');
9.2 sys_role
CREATE TABLE sys_role (
role_id BIGINT(16) NOT NULL AUTO_INCREMENT,
role_name VARCHAr(64) DEFAULT NULL COMMENT '角色名称',
create_user_id BIGINT(16) DEFAULT NULL COMMENT '创建者ID',
create_time DATETIME DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (role_id)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='角色';
INSERT INTO sys_role(role_id,role_name,create_user_id,create_time)
VALUE(10000001,'首席执行官',2022010156,'2022-3-23 22:58:59');
10.测试
使用Postman测试如下:
11.常见问题
11.1 使用MyBatis出现数据查询数据部分字段为null
解决:
(1)实体类(本例SysUserModel)的字段和数据库表字段不对应。
(2)实体类属性和数据库表字段命名规则统一
比如:通过设置map-underscore-to-camel-case属性为true来开启驼峰功能,对应情况如数据库表列:user_name
实体类属性:userName
11.2 本例使用版本在SqlSessionFactoryBean中没有setGlobalConfig方法
解决:GlobalConfig相关配置,使用GlobalConfigUtils进行设置和获取。
11.3 @PostConstruct和afterPropertiesSet()执行顺序
执行顺序依次:@PostConstruct,afterPropertiesSet()。
以上,感谢。
2022年3月24日



