spring boot mybatis整合 druid多数据源
2023-03-18 21:45 youxin 阅读(421) 评论(0) 编辑 收藏 举报地址:https://github.com/CodingDocs/springboot-guide/tree/master
在线阅读:spring boot guide指南
引入依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--数据库依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
- spring-boot-starter-web: 可以为Web开发提供支持,为我们提供了嵌入的
Servlet
容器以及Spring MVC
的依赖,并为Spring MVC
提供了大量自动配置。 - mysql-connector-java:数据库驱动包。
- mybatis-spring-boot-starter:连接
Spring Boot
和MyBatis
,构建基于Spring Boot
的MyBatis
应用程序。 - lombok:简化Java代码的工具包。
添加了“余额money”字段是为了给大家简单的演示一下事务管理的方式。
建表语句:
CREATE TABLE `user` (
`id` int(13) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(33) DEFAULT NULL COMMENT '姓名',
`age` int(3) DEFAULT NULL COMMENT '年龄',
`money` double DEFAULT NULL COMMENT '账户余额',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
1.5 配置 application.properties
由于我使用的是比较新的Mysql连接驱动,所以配置文件可能和之前有一点不同。
server.port=8333
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/erp?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
注意:我们使用的 mysql-connector-java 8+ ,JDBC 连接到mysql-connector-java 6+以上的需要指定时区 serverTimezone=GMT%2B8
。另外我们之前使用配置 Mysql数据连接是一般是这样指定driver-class-name=com.mysql.jdbc.Driver
,但是现在不可以必须为 否则控制台下面的异常:
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
上面异常的意思是:com.mysql.jdbc.Driver
被弃用了。新的驱动类是 com.mysql.cj.jdbc.Driver
。驱动程序通过SPI自动注册,手动加载类通常是不必要。
如果你非要写把com.mysql.jdbc.Driver
改为com.mysql.cj.jdbc.Driver
即可。
1.6 创建用户类 Bean
User.java
public class User {
private int id;
private String name;
private int age;
private double money;
...
此处省略getter、setter以及 toString方法
}
二 全注解的方式
先来看一下 全注解的方式,这种方式和后面提到的 xml 的方式的区别仅仅在于 一个将 sql 语句写在 java 代码中,一个写在 xml 配置文件中。全注方式解转换成 xml 方式仅需做一点点改变即可,我在后面会提到。
2.1 Dao 层开发
UserDao.java
@Mapper public interface UserDao { /** * 通过名字查询用户信息 */ @Select("SELECT * FROM user WHERE name = #{name}") User findUserByName(@Param("name") String name); /** * 查询所有用户信息 */ @Select("SELECT * FROM user") List<User> findAllUser(); /** * 插入用户信息 */ @Insert("INSERT INTO user(name, age,money) VALUES(#{name}, #{age}, #{money})") void insertUser(@Param("name") String name, @Param("age") Integer age, @Param("money") Double money); /** * 根据 id 更新用户信息 */ @Update("UPDATE user SET name = #{name},age = #{age},money= #{money} WHERE id = #{id}") void updateUser(@Param("name") String name, @Param("age") Integer age, @Param("money") Double money, @Param("id") int id); /** * 根据 id 删除用户信息 */ @Delete("DELETE from user WHERE id = #{id}") void deleteUser(@Param("id") int id); }
2.2 service 层
@Service public class UserService { @Autowired private UserDao userDao; /** * 根据名字查找用户 */ public User selectUserByName(String name) { return userDao.findUserByName(name); } /** * 查找所有用户 */ public List<User> selectAllUser() { return userDao.findAllUser(); } /** * 插入两个用户 */ public void insertService() { userDao.insertUser("SnailClimb", 22, 3000.0); userDao.insertUser("Daisy", 19, 3000.0); } /** * 根据id 删除用户 */ public void deleteService(int id) { userDao.deleteUser(id); } /** * 模拟事务。由于加上了 @Transactional注解,如果转账中途出了意外 SnailClimb 和 Daisy 的钱都不会改变。 */ @Transactional public void changemoney() { userDao.updateUser("SnailClimb", 22, 2000.0, 3); // 模拟转账过程中可能遇到的意外状况 int temp = 1 / 0; userDao.updateUser("Daisy", 19, 4000.0, 4); } }
2.3 Controller 层
@RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @RequestMapping("/query") public User testQuery() { return userService.selectUserByName("Daisy"); } @RequestMapping("/insert") public List<User> testInsert() { userService.insertService(); return userService.selectAllUser(); } @RequestMapping("/changemoney") public List<User> testchangemoney() { userService.changemoney(); return userService.selectAllUser(); } @RequestMapping("/delete") public String testDelete() { userService.deleteService(3); return "OK"; } }
2.4 启动类
//此注解表示SpringBoot启动类 @SpringBootApplication // 此注解表示动态扫描DAO接口所在包,实际上不加下面这条语句也可以找到 @MapperScan("top.snailclimb.dao") public class MainApplication { public static void main(String[] args) { SpringApplication.run(MainApplication.class, args); } }
报错问题:
Caused by: java.lang.UnsupportedClassVersionError: org/mybatis/spring/boot/autoconfigure/MybatisDependsOnDatabaseInitializationDetector has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 52.0
降级版本: 我降级到2.3就可以了
去https://mvnrepository.com/ 搜索版本:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.0</version>
</dependency>
https://blog.csdn.net/wstever/article/details/128492151
三 xml 的方式
3.1 Dao 层的改动
我这里只演示一个根据姓名找人的方法。
UserDao.java
@Mapper
public interface UserDao {
/**
* 通过名字查询用户信息
*/
User findUserByName(String name);
}
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="top.snailclimb.dao.UserDao">
<select id="findUserByName" parameterType="String" resultType="top.snailclimb.bean.User">
SELECT * FROM user WHERE name = #{name}
</select>
</mapper>
3.2 配置文件的改动
配置文件中加入下面这句话:
mybatis.mapper-locations=classpath:mapper/*.xml
代码地址:https://github.com/Snailclimb/springboot-guide/tree/master/source-code/basis/springboot-mybatis
出现:
Invalid bound statement (not found)出现原因和解决方法
其实出现这个问题实质就是mapper接口和mapper.xml文件没有映射起来。
常见的错误如下:
1.mapper.xml中的namespace和实际的mapper文件不一致
这个问题其实很好解决,瞪大眼睛,仔仔细细看看,到底对不对应不就好了嘛
2.mapper接口中的方法名和mapper.xml中的id标签不一致
这个问题和上个问题解决方法一样,仔细对对嘛,这个再对不出来,面壁思过吧。
3.上两步的问题都没有,但是还是不行,可能原因就是,没有构建进去,打开target看看对应的mapper.xml文件在不在
原文链接:https://blog.csdn.net/weixin_44695793/article/details/107752054
- 编写在resources文件中创建 mapper/UserMapper.xml文件
注意:
1.namespace中需要与使用@Mapper的接口对应
2.UserMapper.xml文件名称必须与使用@Mapper的接口一致
3.标签中的id必须与@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="com.zhg.demo.mybatis.mapper.UserMapper">
<select id="findAll" resultType="User">
SELECT * FROM tb_user
</select>
</mapper>
配置文件
注意:
1.mybatis中的mapper-locations是mapper的xml文件位置
2.mybatis中的type-aliases-package是为了配置xml文件中resultType返回值的包位置,如果未配置请使用全包名如下:
<select id="findAll" resultType="com.zhg.demo.mybatis.entity.User">
SELECT * FROM tb_user
</select>
server: port: 8081 spring: #数据库连接配置 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://47.107.105.158:3306/test?characterEncoding=utf-8&useSSL=false username: root password: 123456 #mybatis的相关配置 mybatis: #mapper配置文件 mapper-locations: classpath:mapper/*.xml type-aliases-package: com.zhg.demo.mybatis.entity #开启驼峰命名 configuration: map-underscore-to-camel-case: true
https://juejin.cn/post/7182832936545157175
Druid数据库多数据源
Spring的多数据源支持—AbstractRoutingDataSource,AbstractRoutingDataSource定义了抽象的determineCurrentLookupKey方法,子类实现此方法,来确定要使用的数据源
Druid 实现多数据源支持,核心是Overwrite AbstractRoutingDataSource 的 determineCurrentLookupKey 方法
public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean { protected DataSource determineTargetDataSource() { Assert.notNull(this.resolvedDataSources, "DataSource router not initialized"); Object lookupKey = determineCurrentLookupKey(); DataSource dataSource = this.resolvedDataSources.get(lookupKey); if (dataSource == null && (this.lenientFallback || lookupKey == null)) { dataSource = this.resolvedDefaultDataSource; } if (dataSource == null) { throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]"); } return dataSource; } // 确定当前要使用的数据源 protected abstract Object determineCurrentLookupKey(); }
定义aop切面实现
https://blog.csdn.net/Mr_ming_a_probie/article/details/127920120
基于
- @MapperScan(basePackages = "com.eastmoney.labelmanager.db.mapper.second", sqlSessionTemplateRef = "secondarySqlSessionTemplate")
https://pro.leanote.com/p/5b62d22ba8dc8f244d1324f5
启动类配置
关键点:去除 exclude = {DataSourceAutoConfiguration.class} 及扫描 com.demo.mapper目录
@MapperScan("com.demo.mapper")
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication .class, args);
}
原文链接:https://blog.csdn.net/xrq1995/article/details/126231539
SpringBoot 配置 Druid多数据源 通过 注解 + AOP 实现线程多数据源切换 AbstractRoutingDataSource多数据源实现 多类型数据库配置
https://blog.csdn.net/m0_52074262/article/details/122136558
问题原因
日志提示我们没有配置数据源的url属性,我们使用的是druid数据源,而在上面的图示中,url我们是配置的,因此只有一个原因:druid没有识别配置文件中的jdbcUrl。
解决
druid在数据源配置时(包含多个数据源配置),数据库链接地址必须使用“url”,其他的url写法无法加载
总计一下:
数据源 | 单数据源配置url写法 | 多数据源配置url写法 |
---|---|---|
druid | url | url |
hikaricp(springboot默认使用的数据源) | jdbcUrl | jdbc-url |
SpringBoot + Mybatis + Druid 配置多数据源
————————————————
import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; @Configuration @MapperScan(basePackages = "com.mulits.datasource.mapper.tel.**", sqlSessionTemplateRef = "telSqlSessionTemplate") public class TelDataConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource.tel") public DataSource telDataSource() { return DataSourceBuilder.create().build(); } @Bean public SqlSessionFactory telSqlSessionFactory(@Qualifier("telDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); return bean.getObject(); } @Bean public DataSourceTransactionManager telTransactionManager(@Qualifier("telDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean public SqlSessionTemplate telSqlSessionTemplate(@Qualifier("telSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
原文链接:https://blog.csdn.net/weixin_42902577/article/details/106038904
java使用mysql java.lang.ClassNotFoundException: “com.mysql.cj.jdbc.Driver“
https://stackoverflow.com/questions/30651830/use-jdbc-mysql-connector-in-intellij-idea
It’s easy to configure. First just open the IntelliJ IDE and follow this simple step:
File->Project Structure->Libraries
Then click on the plus(+) sign and select 对应的jar文件即可
jdbc执行原生sql
配置DataSourceConfig
import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; /** * @Author goujunqiang * @Date 2019/10/15 **/ @Configuration public class DataSourceConfig { @Bean(name = "baseDataSource") @ConfigurationProperties(prefix = "spring.datasource") // application.properteis中对应属性的前缀 @Primary public DataSource dataSourceBase() { return new DruidDataSource(); } @Bean(name = "resourceJdbcTemplate") public JdbcTemplate inditeJdbcTemplate(@Qualifier("baseDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } @Bean(name = "scannerCodeDataSource") @ConfigurationProperties(prefix = "spring.datasource-white-bucket") public DataSource scannerDataSource() { return new DruidDataSource(); } @Bean(name = "scannerJdbcTemplate") public JdbcTemplate scannerCodeJdbcTemplate(@Qualifier("scannerCodeDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } }
package cn.example.restfulapi.sys.task; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.Map; /** * @author Mr.Hao * @date 2020-04-29 */ @Component public class JdbcTest { @Resource(name = "resourceJdbcTemplate") JdbcTemplate JdbcTemplate; @PostConstruct public void start(){ String sql = "SELECT * FROM `snapshot_info` limit 1;"; Map<String, Object> stringObjectMap = JdbcTemplate.queryForMap(sql); System.out.println("=============查询返回一个map=================="); System.out.println(stringObjectMap); /* System.out.println("=============插入数据=================="); String insertSql = "INSERT INTO snapshot_info VALUES (NULL, ?, ?);"; int x = JdbcTemplate.update(insertSql, 7);*/ System.out.println("===============删除数据================"); String DeleteSql = "DELETE FROM snapshot_info WHERE id=?;"; int i = JdbcTemplate.update(DeleteSql, 9944); System.out.println("影响的行数: " + i); System.out.println("===============更新数据================"); String updateSql = "UPDATE snapshot_info SET task_id=? WHERE id=?;"; int z = JdbcTemplate.update(updateSql, 11, 9943); System.out.println("影响的行数: " + z); } }
public Map<String, Object> queryForMap(String sql)
执行查询语句,将一条记录放到一个Map中。
JdbcTemplate查询-queryForList返回一个List集合
public List<Map<String, Object>> queryForList(String sql)
执行查询语句,返回一个List集合,List中存放的是Map类型的数据。
https://zhuanlan.zhihu.com/p/363407178
https://zhuanlan.zhihu.com/p/363407178
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2022-03-18 Robot Framework 自动化测试框架
2014-03-18 Linux 统计文件夹下文件个数
2013-03-18 jquery选择器返回数组处理
2013-03-18 LR分析
2013-03-18 eclipse打开当前文件所在文件夹的两种方法
2013-03-18 编译原理---递归下降分析法
2012-03-18 c++ string::size详解