Mybatis的事務管理機制
在mybatis-config.xml文件中.可以進行mybatis的事務管理
<transactionManager type="JDBC"/>
type的值有兩個
- JDBC
- MANAGED
JDBC事務管理器
mybatis框架自己管理事務,自己采用原生的JDBC代碼去管理事務
底層創建的事務管理器對象是JdbcTransaction對象
conn.setAutoCommit(false);開啟事務
進行業務處理
conn.commit():手動提交事務
SqlSession sqlSession = sqlSessionFactory.openSession();//如果使用事務管理器是JDBC的話,實際上會執行:conn.setAutoCommit(false)
sqlSession.commit();//如果使用的事務管理器是JDBC的話,實際上會執行:conn.commit()
不建議傳入參數true
SqlSession sqlSession = sqlSessionFactory.openSession(true);
如果傳入了參數true,那么底層就不會執行conn.setAutoCommit(false),那么autoCommit就是true
如果autoCommit是true,就表示沒有開啟事務,只要執行一條sql語句就提交一次
MANAGED事務管理器
mybatis不再負責事務的管理,事務管理交給其他容器來負責
當以后ssm框架進行集成的時候可以用MANAGED
但只有mybatis的框架時,如果配置managed那么這塊事務是沒人管的,表示事務沒開啟
Junit單元測試
先引入單元測試的依賴
然后在test包下創建類,起名規范就是要測試的類加Test
測試方法要加注解@Test,說明這個方法是測試方法
單元測試中有兩個重要的概念
- 實際值:被測試的業務方法的真正的執行結果
- 期望值:執行了這個業務之后,你期望的執行結果是多少
最后加斷言進行測試
Assert.assertEquals(expected,actual)
Mybatis的日志信息
Mybatis配置日志信息需要在核心配置文件中進行配置
Mybatis已經對STDOUT_LOGGING進行了實現,只需要開啟即可
但STDOUT_LOGGING的日志信息不夠豐富,如果想用豐富的要引入第三方組件
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
集成logback日志框架
- 引入logback的依賴
- 引入logback所必須的xml配置文件
- 這個配置文件的名字必須叫做logback.xml或者logback-text.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"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern></encoder></appender><logger name="com.apache.ibaits" level="TRACE"></logger><logger name="java.sql.Connection" level="DEBUG"></logger><logger name="java.sql.Statement" level="DEBUG"></logger><logger name="java.sql.PreparedStatement" level="DEBUG"></logger><root level="DEBUG"><append-ref ref="STDOUT"></append-ref><append-ref ref="FILE"></append-ref></root></configuration>
如果使用的是標準的日志需要配置settings,如果使用的第三方組件就不用配置了
Mybatis封裝工具類
//一個sqlSessionFactory對應一個environment,一般一個environment對應一個數據庫
//所以調用openSession的時候不用每次都創建sqlSessionFactory對象
//寫在類加載器中即可public class MybatisUtil {private static SqlSessionFactory sqlSessionFactory;static {try {sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));} catch (IOException e) {throw new RuntimeException(e);}}private MybatisUtil() {}public static SqlSession openSession() {return sqlSessionFactory.openSession();}
}
Mybatis的CRUD
- C:Create(增)
- R:Retrieve(查)
- U:update(改)
- D:delete(刪)
在mybatis當中的占位符是#{}
Map集合傳值
#{}傳入的值是map的鍵
Map<String,Object> map = new HashMap<>();map.put("k1","1111");map.put("k2","比亞迪漢");map.put("k3",10.0);map.put("k4","2020-12-11");map.put("k5","電車");//第一個參數是sql語句的id//第二個參數是封裝數據的對象sqlSession.insert("insertCar",map);insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values (null,#{k1},#{k2},#{k3},#{k4},#{k5})
POJO類傳值
#{}傳入的值是POJO類的屬性值
SqlSession sqlSession = SqlSessionUtils.openSession();Car car = new Car(null, "1112", "凱的拉克CT6", 55.0, "2023-12-10", "電車");sqlSession.insert("insertCar",car);sqlSession.commit();sqlSession.close();insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values (null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
嚴格意義上來說:如果使用POJO類傳值的話,#{}中實際上是mybatis調用get方法去掉get再把剩下的單詞首字母小寫
#{name}->#{getName}
mybatis的刪除
<delete id="deleteCar">delete from t_car where id=#{id}</delete>sqlSession.delete("deleteCar",15);
Mybatis的更新
public void testUpdateCarById(){SqlSession sqlSession = SqlSessionUtils.openSession();Car car = new Car(5L,"9999","凱美瑞",30.0,"2023-12-10","燃油車");sqlSession.update("updateCar",car);sqlSession.commit();sqlSession.close();}<update id="updateCar">update t_car setcar_num=#{carNum},brand=#{brand},guide_price=#{guidePrice},produce_time=#{produceTime},car_type=#{carType}whereid=#{id}</update>
Mybatis的查詢
mybatis中查詢的時候mybatis底層執行了select語句之后,就一定會返回一個結果集ResultSet
需要在select標簽中指定resultType來確定ResultSet封裝成什么類型的Java對象
@Testpublic void testSelectCarById(){SqlSession sqlSession = SqlSessionUtils.openSession();Object o = sqlSession.selectOne("selectCar", 1);System.out.println(o);sqlSession.close();}
}<select id="selectCar" resultType="POJO.Car">select *from t_carwhere id=#{id}</select>
查詢時如果結果中的列名和封裝對象中的屬性名不對應那么就賦不上值
<select id="selectCar" resultType="POJO.Car">
select id,brand,car_num as carNum,guide_price as guidePrice,produce_time as produceTime,car_type as carType
from t_car
where id=#{id}
</select>
Mybatis查詢所有
//resultType是封裝的結果集類型,不是指定List的類型,是指定List集合中的元素類型
<select id="selectAll" resultType="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>@Testpublic void testSelectAll(){SqlSession sqlSession = SqlSessionUtils.openSession();List<Object> Cars = sqlSession.selectList("selectAll");Cars.forEach(car-> System.out.println(car));sqlSession.close();}
Mybatis中的namespace
在sqlMapper.xml文件當中,有namespace這個屬性是用來指定命名空間的,用來防止id重復
本質上mybatis的sql語句的寫法是namespace.id為了防止id重復
Mybatis的核心配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//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/mybatistest"/><property name="username" value="root"/><property name="password" value="abc123"/></dataSource></environment></environments><mappers><mapper resource="CarMapping.xml"/></mappers>
</configuration>
environments是指mybatis的環境,mybatis中可以有多個環境,一個環境對應一個數據庫
一個數據庫對應一個SqlSessionFactory對象
default指的是默認使用的環境,指定environment的id
當創建SqlSessionFactory的時候沒有指定使用哪個環境就是用默認的環境
Mybatis的事務管理器
transactionManager是事務管理器,指定mybatis具體用什么方式去管理事務
- 第一個:JDBC:使用原生的jdbc代碼來管理事務
- 第二個:MANAGED:mybatis不再負責事務管理,將事務管理交給其他的容器來管理
在Mybatis中提供了事務管理器接口:Transaction
接口下有兩個實現類:JdbcTransaction,ManagedTransaction
如果type="JdbcTransaction" 那么底層會實例化JdbcTransaction對象
如果type="ManagedTransaction" 那么底層會實例化ManagedTransaction對象
Mybatis的數據源
dataSource被稱為數據源
dataSource為程序提供Connection對象,但凡是給程序員提供Connection對象的都叫數據源
數據源實際上是一套規范,JDK中有這套規范,javax.sql.DataSource(這個數據源的規范,這套接口實際上是JDK規范的)
我們自己也可以編寫數據源組件,只要實現javax.sql.DataSource接口就行了,實現接口中的所有方法,這樣就有了自己的數據源
數據庫連接池是提供連接對象的,所以數據庫連接池就是一個數據源組件
type屬性是用來指定數據源的類型,就是指定具體使用什么方法來獲取Connection對象
type的屬性值有三個:
- UNPOOLED:不使用數據庫連接池技術,每一次請求過來之后,都是創建新的Connection對象
- POOLED:使用mybatis自己實現的數據庫連接池
- JNDI:集成其他第三方的數據庫連接池
JNDI是一套規范,大部分web容器都實現了JNDI規范
Mybatis的properties標簽
java.util.Properties類,是一個Map集合,key和value都是String類
properties是為了讓核心文件的配置更靈活
<propety name="屬性名" value="屬性值" />
<properties resource="配置文件名" />