引入 Junit
- Junit 是专⻔做单元测试的组件。
- 在实际开发中,单元测试⼀般是由我们 Java 程序员来完成的。我们要对我们⾃⼰写的每⼀个业务⽅法负责任,要保证每个业务⽅法在进⾏测试的时候都能通过。
- 测试的过程中涉及到两个概念:
- 期望值:执行了这个业务方法之后,你期望的执行结果是什么
- 实际值:被测试的业务方法的真正执行结果
- 期望值和实际值相同表示测试通过,期望值和实际值不同则单元测试执⾏时会报错。
- 这里引⼊ Junit 是为了代替 main ⽅法
第一步:引入依赖
<!--junit依赖--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency>
第二步:使用 Junit 进行测试
- 编写单元测试类,对我们的代码进行测试,测试类中的每⼀个测试⽅法上使用
@Test
注解进⾏标注 - 关于测试类的一写规范:
- 测试类的类名:
要进行测试的类 + Test
- 测试类中的测试方法:一般是一个业务方法对应一个测试方式,测试方法的命名为
test + 要测试方法的方法名
,public void testXxxx() {}
,每个测试方法需要使用@Test
注解进行标注,表示该方法是一个单元测试方法
package com.powernode.junit.service; import org.junit.Assert; import org.junit.Test; // 测试类的类名:要进行测试的类 + Test public class MathServiceTest { @Test public void testSum(){ // 单元测试中有两个重要的概念: // 一个是:实际值(被测试的业务方法的真正执行结果) // 一个是:期望值(执行了这个业务方法之后,你期望的执行结果是多少) MathService mathService = new MathService(); // 获取实际值 int actual = mathService.sum(1, 2); // 期望值 //int expected = 3; int expected = 30; // 加断言进行测试,期望值与实际值不一致会报错 Assert.assertEquals(expected, actual); } @Test public void testSub(){ MathService mathService = new MathService(); // 实际值 int actual = mathService.sub(10, 5); // 期望值 int expected = 5; // 添加断言机制,期望值与实际值一致则不会报错 Assert.assertEquals(expected, actual); } }
关于 MyBatis 集成日志组件
日志组件简述
- mybatis 常见的集成的日志组件有哪些呢?
- SLF4J(沙拉风):沙拉风是一个日志标准,其中有一个日志框架叫做logback,它实现了沙拉风规范。
- LOG4J
- LOG4J2
- STDOUT_LOGGING
- …
- log4j、log4j2、logback都是同一个作者开发的。
- STDOUT_LOGGING 是标准日志,mybatis 已经实现了这种标准日志,mybatis 框架本身已经实现了这种标准,只要开启即可。
开启 MyBatis 本身的日志功能
- 在 mybatis-config.xml 文件中使用settings标签进行配置开启。
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
- 这个标签在编写的时候要注意,它应该出现在 environments 标签之前,注意顺序。
- 当然,不需要记忆这个顺序,因为有dtd文件进行约束,我们只要参考dtd约束即可,标签的顺序不正确会报错
- MyBatis 本身自己实现的日志框架也是可以的,可以看到一些信息,比如:连接对象什么时候创建,什么时候关闭,sql语句是怎样的。但是没有详细的日期,线程名字等。
- 如果想可以看到更加丰富的日志信息,可以集成第三方的log组件。
集成 logback 日志框架。
- logback日志框架实现了slf4j标准。(沙拉风:日志门面、日志标准)
- 在MyBatis使用标准日志 STDOUT_LOGGING 之外的其他日志框架,可以不在mybatis的配置文件中指定 MyBatis 所用日志的具体实现,未指定时将会自动查找,只需要引入相应日志框架的依赖以及日志框架的配置文件即可。
- 第一步:引入logback的依赖。
<!-- 引入logback依赖,logback日志框架实现了slf4j规范 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.11</version> </dependency>
- 第二步:引入logback所必须的xml配置文件。
- 这个配置文件的名字必须叫做:logback.xml或者logback-test.xml,不能是其它的名字。
- 这个配置文件必须放到类的根路径下,不能是其他位置。
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <!-- 控制台输出 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>[%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <!--mybatis log configure--> <logger name="com.apache.ibatis" level="TRACE"/> <logger name="java.sql.Connection" level="DEBUG"/> <logger name="java.sql.Statement" level="DEBUG"/> <logger name="java.sql.PreparedStatement" level="DEBUG"/> <!-- 日志输出级别,logback日志级别包括五个:TRACE < DEBUG < INFO < WARN < ERROR --> <!-- 级别越低输出的信息越多 --> <root level="DEBUG"> <appender-ref ref="STDOUT"/> <appender-ref ref="FILE"/> </root> </configuration>
MyBatis 工具类 SqlSessionUtil 的封装
package cw.mybatis.utils; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; /** * Mybatis工具类 */ public class SqlSessionUtils { // 工具类的构造方法一般为私有,防止实例化对象 // 工具类中的方法都是静态的,可以直接采用类名进行调用,不需要new对象,方便调用 private SqlSessionUtils() {} private static SqlSessionFactory sqlSessionFactory; // 类加载时执行 // SqlSessionUtil工具类在进行第一次加载的时候,解析mybatis-config.xml文件。创建SqlSessionFactory对象。 // SqlSessionFactory对象:一个SqlSessionFactory对应一个environment,一个environment通常是一个数据库。 static { SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); try { sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml")); } catch (IOException e) { throw new RuntimeException(e); } } /** * 获取数据库会话对象 * @return 数据库会话对象 */ public static SqlSession openSession() { // SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // SqlSessionFactory对象:一个SqlSessionFactory对应一个environment,一个environment通常是一个数据库。 // SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession sqlSession = sqlSessionFactory.openSession(); return sqlSession; } }
- 测试:
package cw.mybatis.test; import cw.mybatis.utils.SqlSessionUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; public class SqlSessionUtilsTest { @Test public void testOpenSession() { SqlSession sqlSession = SqlSessionUtils.openSession(); int count = sqlSession.insert("insertCar"); System.out.println(count); sqlSession.commit(); sqlSession.close(); } }
使用 MyBatis 完成 CRUD
- CRUD
- C: Create 增
- R: Retrieve 查(检索)
- U: Update 改
- D: Delete 删
insert
MyBatis 中 SQL 的编写
<!--namespace先随便写--> <mapper namespace="car"> <!-- 在insert标签中写向数据库中插入数据的SQL --> <insert id="insertCar"> insert into t_car(car_num,brand,guide_price,produce_time,car_type) values('103', '奔驰E300L', 50.3, '2022-01-01', '燃油车') </insert> </mapper>
- 这样写的问题是:插入数据库的值写死到配置文件中的。这个在实际开发中是不存在的。一定是前端的form表单提交过来数据。然后将值传给sql语句。
- JDBC 的代码的写法
String sql = "insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,?,?,?,?,?)"; ps.setString(1, xxx); ps.setString(2, yyy); ....
- 在JDBC当中占位符采用的是?,在mybatis当中是什么呢?
- 和?等效的写法是:#{}
- 在mybatis当中不能使用?占位符,必须使用 #{} 来代替JDBC当中的 ?
- #{} 和 JDBC当中的 ? 是等效的。
<!--namespace先随便写--> <mapper namespace="car"> <insert id="insertCar"> insert into t_car(car_num,brand,guide_price,produce_time,car_type) values(#{}, #{}, #{}, #{}, #{}) </insert> </mapper>
使用Map集合传参
- java程序中使用Map可以给SQL语句的占位符传值,占位符中写map集合的key,如果key不存在,获取的是null,一般map集合的key起名的时候要见名知意。
<mapper namespace="car"> <!--insert sql:保存⼀个汽⻋信息--> <insert id="insertCar"> insert into t_car (id,car_num,brand,guide_price,produce_time,car_type) values (null, #{k1}, #{k2}, #{k3}, #{k4}, #{k5}) </insert> </mapper>
package cw.mybatis; import cw.mybatis.utils.SqlSessionUtils; import org.apache.ibatis.session.SqlSession; import java.util.HashMap; import java.util.Map; public class CarMapperTest { @Test public void testInsertCar() { // 使用map集合进行数据的封装。 Map<String, Object> map = new HashMap<>(); map.put("k1", "1111"); map.put("k2", "比亚迪汉"); map.put("k3", 10.0); map.put("k4", "2020-11-11"); map.put("k5", "电车"); // 获取与数据库的会话对象 SqlSession sqlSession = SqlSessionUtils.openSession(); // 执行SQL语句 // insert SQL 使用 insert方法 // insert方法的参数: // 第一个参数:sqlId,从CarMapper.xml文件中复制。 // 第二个参数:封装数据的对象。 sqlSession.insert("insertCar", map); sqlSession.commit(); sqlSession.close(); } }
使用POJO(简单普通的java对象)传参
- 第一步:定义一个pojo类Car,提供相关属性
package cw.mybatis.pojo; /** * 封装汽车相关信息的pojo类。普通的java类。 */ public class Car { // 数据库表当中的字段应该和pojo类的属性一一对应。 // 建议使用包装类,这样可以防止null的问题。 private Long id; private String carNum; private String brand; private Double guidePrice; private String produceTime; private String carType; public Car() { } public Car(Long id, String carNum, String brand, Double guidePrice, String produceTime, String carType) { this.id = id; this.carNum = carNum; this.brand = brand; this.guidePrice = guidePrice; this.produceTime = produceTime; this.carType = carType; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getCarNum() { return carNum; } public void setCarNum(String carNum) { this.carNum = carNum; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public Double getGuidePrice() { return guidePrice; } public void setGuidePrice(Double guidePrice) { this.guidePrice = guidePrice; } public String getProduceTime() { return produceTime; } public void setProduceTime(String produceTime) { this.produceTime = produceTime; } public String getCarType() { return carType; } public void setCarType(String carType) { this.carType = carType; } @Override public String toString() { return "Car{" + "id=" + id + ", carNum='" + carNum + '\'' + ", brand='" + brand + '\'' + ", guidePrice=" + guidePrice + ", produceTime='" + produceTime + '\'' + ", carType='" + carType + '\'' + '}'; } }
- 第二步:Java程序
@Test public void testInsertCarPOJO() { // 封装数据 Car car = new Car(null, "3333", "比亚迪", 30.0, "2020-11-11", "新能源"); SqlSession sqlSession = SqlSessionUtils.openSession(); // 执行sql sqlSession.insert("insertCar", car); sqlSession.commit(); sqlSession.close(); }
- 第三步:SQL语句
<mapper namespace="car"> <!--insert sql:保存⼀个汽⻋信息--> <!-- 占位符 #{} 中写POJO的属性名 --> <insert id="insertCar"> insert into t_car (id,car_num,brand,guide_price,produce_time,car_type) values (null, #{carNum}, #{brand}, #{guidePrice}, #{produceTime}, #{carType}) </insert> </mapper>
MyBatis 如何获取 POJO 属性值分析
- 如果把SQL语句写成如下这个德行:
insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,#{xyz},#{brand},#{guidePrice},#{produceTime},#{carType})
- 出现了什么问题呢?
There is no getter for property named 'xyz' in 'class com.powernode.mybatis.pojo.Car'
- mybatis去找:Car类中的getXyz()方法去了。没找到。报错了。
- 怎么解决的?
- 可以在Car类中提供一个getXyz()方法。这样问题就解决了。
- 通过这个测试,得出一个结论:
- 严格意义上来说:如果使用POJO对象传递值的话,#{}这个大括号中到底写什么?
- 写的是get方法的方法名去掉get,然后将剩下的单词首字母小写,然后放进去。
- 例如:getUsername() --> #{username}
- 例如:getEmail() --> #{email}
- …
- 也就是说mybatis在底层给?传值的时候,先要获取值,怎么获取的?
- 调用了pojo对象的get方法。例如:car.getCarNum(),car.getCarType(),car.getBrand()
SQL 语句标签的 parameterType 属性
- 其实传参数的时候有一个属性parameterType,这个属性用来指定传参的数据类型,不过这个属性是可以省略的
<insert id="insertCar" parameterType="java.util.Map"> insert into t_car(car_num,brand,guide_price,produce_time,car_type) values(#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType}) </insert> <insert id="insertCarByPOJO" parameterType="com.powernode.mybatis.pojo.Car"> insert into t_car(car_num,brand,guide_price,produce_time,car_type) values(#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType}) </insert>
delete
- 需求:根据id删除数据
- SQL语句
<!-- 当sql语句中的占位符只有一个时,占位符中的内容可以任意写,但是不能不写,一般采用见名知意的命名 --> <!-- 只有一个占位符时,mybatis可以知道数据填放的位置 --> <delete id="deleteById"> delete from t_car where id = #{id} </delete>
- java程序
@Test public void testDeleteById() { SqlSession sqlSession = SqlSessionUtils.openSession(); // 第二个参数会被自动装箱成相应的类型 sqlSession.delete("deleteById", 10); sqlSession.commit(); sqlSession.close(); }
- 注意:如果占位符只有一个,那么#{}的大括号里可以随意。但是最好见名知意。
update
- 需求:根据id修改某条记录。
<update id="updateById"> update t_car set car_num = #{carNum}, brand = #{brand}, guide_price = #{guidePrice}, produce_time = #{produceTime}, car_type = #{carType} where id = #{id} </update>
@Test public void testUpdateById() { SqlSession sqlSession = SqlSessionUtils.openSession(); // 封装数据 Car car = new Car(4L, "9999", "凯美瑞", 30.3, "1999-11-10", "燃油车"); int count = sqlSession.update("updateById", car); System.out.println(count); sqlSession.commit(); sqlSession.close(); }
select
- select语句查询会有一个结果集
查一条数据
- 需求:根据id查询。
- 查询时需要告诉mybatis查询结果集封装成的java对象类型,select标签中resultType属性,这个属性用来告诉mybatis,查询结果集封装成什么类型的java对象。
- select标签中resultType通常写的是:全限定类名。
- 如果表的字段名与相应的java类的属性名不一致可以使用别名为查询语句的字段指定别名,来解决不能为java对象属性赋值的问题
<!-- sql语句中如果表的字段名与相应的java类的属性名不一致需要使用别名为查询语句的字段指定别名, 否则对应字段的查询为null --> <select id="selectById" resultType="cw.mybatis.pojo.Car"> select id,car_num as carNum,brand,guide_price as guidePrice, produce_time as produceTime, car_type as carType from t_car where id = #{id} </select>
@Test public void testSelectById() { SqlSession sqlSession = SqlSessionUtils.openSession(); // 执行DQL语句。查询。根据id查询。返回结果一定是一条。 // mybatis底层执行了select语句之后,一定会返回一个结果集对象:ResultSet // JDBC中叫做ResultSet,接下来就是mybatis应该从ResultSet中取出数据,封装java对象。 Object car = sqlSession.selectOne("selectById", 1); System.out.println(car); sqlSession.close(); }
查多条数据
<!-- resultType还是指定要封装的结果集的类型。 不是指定List类型,是指定List集合中元素的类型。 --> <select id="selectAll" resultType="cw.mybatis.pojo.Car"> select id,car_num as carNum,brand,guide_price as guidePrice, produce_time as produceTime, car_type as carType from t_car </select>
@Test public void testSelectAll() { SqlSession sqlSession = SqlSessionUtils.openSession(); // selectList方法:mybatis通过这个方法就可以得知你需要一个List集合。 // 它会自动给你返回一个List集合。 List<Car> cars = sqlSession.selectList("selectAll"); cars.forEach(System.out::println); sqlSession.close(); }
SQL Mapper 的 namespace
- 在sql mapper.xml文件当中有一个namespace,这个属性是用来指定命名空间的。用来防止id重复。
- 当不同的 SQLMapper 映射文件中,存在 sqlId 相同的两个SQL语句,若使用SQL语句时不使用命名空间,则会报错
- 命名空间的使用
namespace.sqlId
(MyBatis中sqlId的完整写法) - 实际上,本质上,mybatis中的sqlId的完整写法:namespace.id
- 创建CarMapper2.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="car2"> <select id="selectCarAll" resultType="com.powernode.mybatis.pojo.Car"> select id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType from t_car </select> </mapper>
- CarMapper.xml和CarMapper2.xml文件中都有 id=“selectCarAll”
- 将CarMapper2.xml配置到mybatis-config.xml文件中。
<mappers> <mapper resource="CarMapper.xml"/> <mapper resource="CarMapper2.xml"/> </mappers>
- Java代码
@Test public void testSelectAll() { SqlSession sqlSession = SqlSessionUtils.openSession(); List<Car> cars = sqlSession.selectList("selectAll"); cars.forEach(System.out::println); sqlSession.close(); }
org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.IllegalArgumentException: selectCarAll is ambiguous in Mapped Statements collection (try using the full name including the namespace, or rename one of the entries) 【翻译】selectCarAll在Mapped Statements集合中不明确(请尝试使用包含名称空间的全名,或重命名其中一个条目) 【大致意思是】selectCarAll重名了,你要么在selectCarAll前添加一个名称空间,要有你改个其它名字。
- Java代码修改如下:
@Test public void testSelectAll() { SqlSession sqlSession = SqlSessionUtils.openSession(); // SQL id:namespace.id List<Car> cars = sqlSession.selectList("car.selectAll"); cars.forEach(System.out::println); sqlSession.close(); }
MyBatis核心配置文件详解
老杜原版
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/powernode"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="CarMapper.xml"/> <mapper resource="CarMapper2.xml"/> </mappers> </configuration>
- configuration:根标签,表示配置信息。
- environments:环境(多个),以“s”结尾表示复数,也就是说mybatis的环境可以配置多个数据源。
- default属性:表示默认使用的是哪个环境,default后面填写的是environment的id。default的值只需要和environment的id值一致即可。
- environment:具体的环境配置(主要包括:事务管理器的配置 + 数据源的配置)
- id:给当前环境一个唯一标识,该标识用在environments的default后面,用来指定默认环境的选择。
- transactionManager:配置事务管理器
- type属性:指定事务管理器具体使用什么方式,可选值包括两个
- JDBC:使用JDBC原生的事务管理机制。底层原理:事务开启conn.setAutoCommit(false); …处理业务…事务提交conn.commit();
- MANAGED:交给其它容器来管理事务,比如WebLogic、JBOSS等。如果没有管理事务的容器,则没有事务。没有事务的含义:只要执行一条DML语句,则提交一次。
- dataSource:指定数据源
- type属性:用来指定具体使用的数据库连接池的策略,可选值包括三个
- UNPOOLED:采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的思想。
- property可以是:
- driver 这是 JDBC 驱动的 Java 类全限定名。
- url 这是数据库的 JDBC URL 地址。
- username 登录数据库的用户名。
- password 登录数据库的密码。
- defaultTransactionIsolationLevel 默认的连接事务隔离级别。
- defaultNetworkTimeout 等待数据库操作完成的默认网络超时时间(单位:毫秒)
- POOLED:采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现。
- property可以是(除了包含UNPOOLED中之外):
- poolMaximumActiveConnections 在任意时间可存在的活动(正在使用)连接数量,默认值:10
- poolMaximumIdleConnections 任意时间可能存在的空闲连接数。
- 其它…
- JNDI:采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样。如果不是web或者maven的war工程,JNDI是不能使用的。
- property可以是(最多只包含以下两个属性):
- initial_context 这个属性用来在 InitialContext 中寻找上下文(即,initialContext.lookup(initial_context))这是个可选属性,如果忽略,那么将会直接从 InitialContext 中寻找 data_source 属性。
- data_source 这是引用数据源实例位置的上下文路径。提供了 initial_context 配置时会在其返回的上下文中进行查找,没有提供时则直接在 InitialContext 中查找。
- mappers:在mappers标签中可以配置多个sql映射文件的路径。
- mapper:配置某个sql映射文件的路径
- resource属性:使用相对于类路径的资源引用方式
- url属性:使用完全限定资源定位符(URL)方式
各标签拆分解释说明版
文档类型说明
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
- 文档类型说明中的 configuration,是根标签的名称,一个文档只有一个根标签
- http://mybatis.org/dtd/mybatis-3-config.dtd 是xml文档的dtd约束,约束文档中可以出现什么标签、标签能有什么子标签、标签中可以有什么属性、标签属性可以具有的值以及标签出现的顺序
根标签
<configuration> ... </configuration>
- configuration:根标签,表示配置信息
properties
- java.util.Properties类,是一个Map集合,key和value都是String类型
- property标签中的name属性为key,value属性为value
- 在properties标签中可以配置很多属性
- 在properties下面的标签中可以使用property配置的属性值,使用
${property的name属性}
取出相应的值
<properties> <!-- <property name="属性名" value="属性值"/> --> <property name="jdbc.driver" value="com.mysql.cj.jdbc.Driver"/> <property name="jdbc.url" value="jdbc:mysql://localhost:3306/powernode"/> <property name="jdbc.username" value="root"/> <property name="jdbc.password" value="root"/> </properties>
<dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource>
从指定路径下开始查找配置文件
- properties中的property可以配置到配置文件中
<!-- resource,从类路径下开始查找资源 --> <properties resource="jdbc.properties" />
<!-- 从绝对路径当中加载资源 --> <!-- 绝对路径怎么写?file:///路径 --> <properties url="file:///d:/jdbc.properties" />
environments
<environments default="powernodeDB"> ... </environments>
- 在 environments 标签中配置数据库环境,可以配置多个数据库环境
- default 表示默认使用的数据库环境
- 当你使用mybatis创建SqlSessionFactory对象的时候,没有指定数据库环境的话,默认使用 default 属性指定的数据库环境
environment
- environments 的子标签,在 environment 标签中配置每一个数据库环境
- 一般一个数据库会对应一个SqlSessionFactory对象,一个环境environment会对应一个SqlSessionFactory对象,所以一个数据库一般对应一个环境
<!-- 第一个数据库环境 --> <environment id="powernodeDB"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="poolMaximumActiveConnections" value="10"/> <property name="poolTimeToWait" value="2000"/> <property name="poolMaximumCheckoutTime" value="10000"/> <property name="poolMaximumIdleConnections" value="5"/> </dataSource> </environment> <!-- 第二个数据库环境 --> <environment id="mybatisDB"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment>