MyBatis学习

1.原生JDBC

依赖

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
 
<dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
</dependency>
1.加载 JDBC 驱动程序 2.创建数据库的连接 3.创建 preparedStatement 4.执⾏ SQL 语句 5.处理结果集 6.关闭 JDBC 对象资源
 Class.forName("com.mysql.cj.jdbc.Driver");
 //连接
 String url = "jdbc:mysql://127.0.0.1:3306/test?
useUnicode=true&characterEncoding=utf-8&useSSL=false";
 String username = "test";
 String password = "test";
//获取连接对象,并连接数据库
 Connection connection = DriverManager.getConnection(url,username,password);
 //获取语句对象
 Statement statement = connection.createStatement();
 ResultSet resultSet = statement.executeQuery("select * from
t_test1");
 while (resultSet.next()){
 System.out.println(resultSet.toString());
 }
 statement.close();
每次要加载驱动,连接信息是硬编码 sql 和 java 代码耦合⼀起,改动不易 参数设置缺少灵活性 处理结果集麻烦,不能⾃动映射到实体类 连接资源不能复⽤,资源浪费

ORM对象关系映射框架

对数据库的表和POJO(Plain Ordinary Java Object,普通Java对象 )Java对象的做映射的框架

hibernate (ssh)

笨重, sql 调优麻烦

JPA - Spring Data JPA

Java Persistence API, 轻量级,部分中⼩项⽬适合

mybatis

半⾃动化 ( 半 ORM 框架 ) ,便于写 sql ,轻量级,⼤⼚⼴泛使⽤

2.MyBatis

mybatis – MyBatis 3 | Introduction

依赖

<dependencies>
 <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
 <dependency>
 <groupId>org.mybatis</groupId>
 <artifactId>mybatis</artifactId>
 <version>3.5.9</version>
 </dependency>
 <!-- 使⽤JDBC链接mysql的驱动-->
 <dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
 <version>8.0.19</version>
 </dependency>
</dependencies>
        每个基于 MyBatis 的应⽤都是以⼀个 SqlSessionFactory 的实例为核⼼         SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得         SqlSessionFactoryBuilder 可以从 XML 配置⽂件或⼀个预先配置的 Confifiguration 实例来构 建出 SqlSessionFactory 实例 ⼯⼚设计模式⾥⾯ 需要获取 SqlSession ,⾥⾯提供了在数据库执⾏ SQL 命令所需的所有⽅法 配置 mybatis-confifig.xml.xml
<?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://127.0.0.1:3306/test2?
useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false"/>
 <property name="username" value="test"/>
 <property name="password" value="test"/>
 </dataSource>
 </environment>
 </environments>
 <mappers>
 <mapper resource="mapper/TestMaper.xml"/>
 </mappers>
</configuration>

TestMapper.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="com.test.dao.TestMapper">
 <select id="selectById"
resultType="com.test.domain.Test">
 select * from t_test_2 where id = #{test_id}
 </select>
</mapper>
取 java 对象的某个值,属性名⼤⼩写要⼀致                  #{value} : 推荐 , 是 java 的名称         ${value} : 不推荐,存在 sql 注⼊⻛险

代码方式 补⻬对象字段Main.java

 public static void main(String [] args) throws IOException {
 String resouce = "config/mybatis-config.xml";
 //读取配置⽂件
 InputStream inputStream = Resources.getResourceAsStream(resouce);
 //构建Session⼯⼚
 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 //获取Session
 try(SqlSession sqlSession = sqlSessionFactory.openSession()){
 TestMapper testMapper =
sqlSession.getMapper(TestMapper.class);
 Test test= testMapper.selectById(1);

 List<Test > testList = testMapper.selectList();
 System.out.println(testList .toString());
 }
 }

注解

 /**
 * 查询列表
 * @return
 */
 @Select("select * from t_test2")
 List<Test> selectList();

Mybatis使⽤流程

创建 mybatis-config.xml 全局的配置⽂件 创建 XXXMapper.xml 配置⽂件 创建 SqlSessionFactory ⽤ SqlSessionFactory 创建 SqlSession 对象 ⽤ SqlSession 执⾏增删改查 CRUD

使⽤log4j配置打印sql

<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-log4j12</artifactId>
</dependency>

在应⽤的classpath中创建名称为 log4j.properties 的⽂件

log4j.rootLogger=ERROR, stdout
log4j.logger.com.test=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

mysql⾃带函数使⽤(where  ... and like ..)

<select id="selectByPointAndTitleLike"
resultType="com.test.domain.Test">
select * from t_test2 where point=#{point} and title like concat('%', #
{title},'%')
</select>

Mybatis 配置驼峰字段映射java对象和数据库字段

Mybatis ⾃带配置 ( 加在⽂件顶部 )
 <!--下划线⾃动映射驼峰字段-->
 <settings>
 <setting name="mapUnderscoreToCamelCase" value="true"/>
 </settings>

Mybatis⼊参parameterType和取值类型

parameterType 参数类型                 可以是基本类型                 可以是 Java 集合 List 或者 Map                 可以是 Java ⾃定义对象 取参数值,具体某个字段的类型,从 java类型映射到数据库类型.例⼦ #{title, jdbcType=VARCHAR} 注意: 多数情况不加是正常使⽤,但是如果出现报错:⽆效的列类型,则是缺少 jdbcType; 只有当字段可为 NULL 时才需要 jdbcType 属性 常⻅的数据库类型和 java 列席对⽐
JDBC Type         Java Type
CHAR                 String
VARCHAR              String
LONGVARCHAR          String
NUMERIC           java.math.BigDecimal
DECIMAL           java.math.BigDecimal
BIT                 boolean
BOOLEAN             boolean
TINYINT             byte
SMALLINT             short
INTEGER             INTEGER
INTEGER             int
BIGINT             long
REAL                 float
FLOAT                 double
DOUBLE                 double
BINARY                 byte[]
VARBINARY                byte[]
LONGVARBINARY         byte[]
DATE             java.sql.Date
TIME             java.sql.Time
TIMESTAMP        java.sql.Timestamp
CLOB                 Clob
BLOB                 Blob
ARRAY                 Array
DISTINCT         mapping of underlying type
STRUCT             Struct
REF                 Ref
DATALINK             java.net.URL

新增数据

 <insert id="add" parameterType="com.test.domain.Test">
 INSERT INTO `t_test2` ( `title`, `summary`, `cover_img`, `price`,
`create_time`, `point`)
 VALUES
 (#{title,jdbcType=VARCHAR},#{summary,jdbcType=VARCHAR},#
{coverImg,jdbcType=VARCHAR},#{price,jdbcType=INTEGER},
 #{createTime,jdbcType=TIMESTAMP},#{point,jdbcType=DOUBLE});
</insert>

获得插⼊的⾃增主键

<insert id="add" parameterType="com.test.domain.Test"
useGeneratedKeys="true" keyProperty="id" keyColumn="id" >
 INSERT INTO `t_test2` ( `title`, `summary`, `cover_img`, `price`,
`create_time`, `point`)
 VALUES
 (#{title,jdbcType=VARCHAR},#{summary,jdbcType=VARCHAR},#
{coverImg,jdbcType=VARCHAR},#{price,jdbcType=INTEGER},
 #{createTime,jdbcType=TIMESTAMP},#{point,jdbcType=DOUBLE});
</insert>

//新增⼀条记录
 Test test= new Test();
 test.setTitle("testtesttest");
 test.setCoverImg("xdclass.net/aaa.png");
 test.setPoint(9.4);
 test.setCreateTime(new Date());
 test.setPrice(9900);
 test.setSummary("test for test");
 int rows = testMapper.add(test);
 System.out.println(rows);
 System.out.println(test.toString());

Mybatis实战foreach批量插⼊语法

foreach: ⽤于循环拼接的内置标签,常⽤于 批量新增、 in 查询等常⻅
包含以下属性:
 collection:必填,值为要迭代循环的集合类型,情况有多种
 ⼊参是List类型的时候,collection属性值为list
 ⼊参是Map类型的时候,collection 属性值为map的key值
 
 item:每⼀个元素进⾏迭代时的别名
 index:索引的属性名,在集合数组情况下值为当前索引值,当迭代对象是map时,这个值是
map的key
 open:整个循环内容的开头字符串
 close:整个循环内容的结尾字符串
 separator: 每次循环的分隔符

<!--批量插⼊-->
<insert id="addBatch"
parameterType="com.test.domain.Test"
useGeneratedKeys="true" keyProperty="id" keyColumn="id" >
INSERT INTO `t_test2` ( `title`, `summary`, `cover_img`, `price`,
`create_time`, `point`)
VALUES
<foreach collection="list" item="test" separator=",">
 
(#{test.title,jdbcType=VARCHAR},#{test.summary,jdbcType=VARCHAR},#
{test.coverImg,jdbcType=VARCHAR},
#{test.price,jdbcType=INTEGER},
#{test.createTime,jdbcType=TIMESTAMP},#{test.point,jdbcType=DOUBLE})
<foreach/>

MyBatis3.X更新

<update id="updateTest"
 parameterType="com.test.domain.Test">
 UPDATE t_test2
 set
 title = #{title,jdbcType=VARCHAR},
 summary = #{summary,jdbcType=VARCHAR},
 cover_img = #{coverImg,jdbcType=VARCHAR},
 price = #{price,jdbcType=INTEGER},
 c_id = #{cId,jdbcType=INTEGER},
 point = #{point,jdbcType=INTEGER},
 update_time = now()
 WHERE
 id = #{id}
</update>
存在其他不想被更新的字段却置为 null 或者默认值了

Mybatis 动态字段更新 if test 标签

//当前字段符合条件才更新这个字段的值
<if test='title != null and id == 1'> title = #{title}, </if>
<if test="title!=null"> title = #{title}, </if>

<update id="updateTestSelective"
parameterType="com.test.domain.Test">
 update t_test2
 <trim prefix="set" suffixOverrides=",">
 <if test="title != null "> title = #{title,jdbcType=VARCHAR},
</if>
 <if test="summary != null "> summary = #
{summary,jdbcType=VARCHAR},</if>
 <if test="coverImg != null "> cover_img = #
{coverImg,jdbcType=VARCHAR},</if>
 <if test="price != 0 "> price = #{price,jdbcType=INTEGER},
</if>
<if test="createTime !=null "> create_time = #
{createTime,jdbcType=TIMESTAMP},</if>
 <!-- 特别注意: ⼀定要看pojo类⾥⾯的是基本数据类型,还是包装数据类型-->
 <if test="point != null "> point = #{point,jdbcType=DOUBLE},
</if>
 </trim>
 where
 id = #{id}
 </update>

Mybatis删除语法操作

<delete id="deleteByCreateTimeAndPrice" parameterType="java.util.Map">
 delete from test where create_time <![CDATA[ > ]]> #{createTime}
and price <![CDATA[ >= ]]> #{price}
</delete>
⼤于等于 <![CDATA[ >= ]]> ⼩于等于 <![CDATA[ <= ]]>

3.mybatis-confifig.xml常⻅属性

核⼼配置⽂件(dom节点顺序要求,不然报错)

configuration (配置) properties (属性) settings (设置) typeAliases (类型别名) typeHandlers (类型处理器) objectFactory (对象⼯⼚) plugins (插件,少⽤) environments (环境配置,不配多环境,基本在 Spring ⾥⾯配置) environment (环境变量) transactionManager (事务管理器) dataSource (数据源) databaseIdProvider (数据库⼚商标识) mappers (映射器) mybatis – MyBatis 3 | 配置

MyBatis3.X 查询typeAlias别名

typeAlias 类型别名,给类取个别名,可以不⽤输⼊类的全限定名
 <typeAlias type="com.test.domain.Test"
alias="Test"/>

<!--<select id="selectById" parameterType="java.lang.Integer"
resultType="com.test.domain.Test">-->
 <select id="selectById" parameterType="java.lang.Integer"
resultType="Test">
 select * from t_test2 where id = #{test_id,jdbcType=INTEGER}
 </select>


<typeAliases>
 <!--<typeAlias type="com.test.domain.Test"
alias="Test"/>-->
 <package name="com.test.domain"/>
</typeAliases>

Mybatissql⽚段

<sql id="base_test_field">
 id,title,summary,cover_img
 </sql>
 
 <select id="selectById" parameterType="java.lang.Integer"
resultType="Test">
 select <include refid="base_test_field"/> from t_test2 where
id = # {test_id,jdbcType=INTEGER}
 </select>
 <select id="selectListByXML" resultType="Test">
 select <include refid="base_test_field"/> from t_test2
 </select>

4.复杂Sql查询

MybatisresultMap

resultType         查询出的字段在相应的pojo 中必须有和它相同的字段对应,或者基本数据类型         适合简单查询 resultMap         需要⾃定义字段,或者多表查询,⼀对多等关系,⽐resultType 更强⼤         适合复杂查询
<resultMap id="TestResultMap" type="Test">
 <!--
 id 指定查询列的唯⼀标示
 column 数据库字段的名称
 property pojo类的名称
 -->
 <id column="id" property="id" jdbcType="INTEGER" />
 <result column="test_tile" property="title" jdbcType="VARCHAR" />
 <result column="summary" property="summary" jdbcType="VARCHAR" />
 <result column="cover_img" property="coverImg" jdbcType="VARCHAR" />
</resultMap>
<select id="selectBaseFieldByIdWithResultMap" resultMap="TestResultMap">
select id , title as test_tile, summary, cover_img from t_test2 where id = #
{test_id}
</select>

复杂对象映射配置ResultMapassociation

 <resultMap id="orderResultMap" type="Order">
     <id column="id" property="id"/>
     <result column="user_id" property="userId"/>
     <result column="out_trade_no" property="outTradeNo"/>
     <result column="create_time" property="createTime"/>
     <result column="state" property="state"/>
     <result column="total_fee" property="totalFee"/>
     <result column="test_id" property="testId"/>
     <result column="test_title" property="testTitle"/>
     <result column="test_img" property="testImg"/>
     <!-- association 配置属性⼀对⼀
          property 对应videoOrder⾥⾯的user属性名
         javaType 这个属性的类型
     -->
 <association property="user" javaType="User">
     <id property="id" column="user_id"/>
     <result property="name" column="name"/>
     <result property="headImg" column="head_img"/>
     <result property="createTime" column="create_time"/>
     <result property="phone" column="phone"/>
 </association>
 </resultMap>
 <!--⼀对⼀管理查询订单, 订单内部包含⽤户属性-->
 <select id="queryVideoOrderList" resultMap="OrderResultMap">
 select
 o.id id,
 o.user_id ,
 o.out_trade_no,
 o.create_time,
 o.state,
 o.total_fee,
 o.test_id,
 o.test_title,
 o.test_img,
 u.name,
 u.head_img,
 u.create_time,
 u.phone
 from order o left join user u on o.user_id = u.id
 </select>

// resultmap association关联查询
OrderMapper orderMapper =
sqlSession.getMapper(OrderMapper.class);
List<Order> orderList = orderMapper.queryVideoOrderList();
System.out.println(orderList.toString());

⼀对多映射配置ResultMapcollection

<resultMap id="UserOrderResultMap" type="User">
 <id property="id" column="id"/>
 <result property="name" column="name"/>
 <result property="headImg" column="head_img"/>
 <result property="createTime" column="create_time"/>
 <result property="phone" column="phone"/>
 <!--
 property 填写pojo类中集合类属性的名称
 ofType 集合⾥⾯的pojo对象
 -->
 <collection property="orderList" ofType="Order">
 <!--配置主键,管理order的唯⼀标识-->
 <id column="order_id" property="id"/>
 <result column="user_id" property="userId"/>
 <result column="out_trade_no" property="outTradeNo"/>
 <result column="create_time" property="createTime"/>
 <result column="state" property="state"/>
 <result column="total_fee" property="totalFee"/>
 <result column="video_id" property="videoId"/>
 <result column="video_title" property="videoTitle"/>
 <result column="video_img" property="videoImg"/>
 </collection>
 </resultMap>
 <select id="queryUserOrder" resultMap="UserOrderResultMap">
 select
 u.id,
 u.name,
 u.head_img,
 u.create_time,
 u.phone,
 o.id order_id,
 o.out_trade_no,
 o.user_id,
 o.create_time,
 o.state,
 o.total_fee,
 o.test_id,
 o.test_title,
 o.test_img
 from user u left join order o on u.id = o.user_id
 </select>
 // resultmap association关联查询
 OrderMapper orderMapper =
sqlSession.getMapper(OrderMapper.class);
//resultmap collection测试
List<User> userList = orderMapper.queryUserOrder();
System.out.println(userList.toString());
association 映射的是⼀个 pojo 类,处理⼀对⼀的关联关系。 collection 映射的⼀个集合列表,处理的是⼀对多的关联关系。

模板

<!-- column不做限制,可以为任意表的字段,⽽property须为type 定义的pojo属性-->
<resultMap id="唯⼀的标识" type="映射的pojo对象">
 <id column="表的主键字段,或查询语句中的别名字段" jdbcType="字段类型" property="映射
pojo对象的主键属性" />
 <result column="表的⼀个字段" jdbcType="字段类型" property="映射到pojo对象的⼀个属
性"/>
 <association property="pojo的⼀个对象属性" javaType="pojo关联的pojo对象">
 <id column="关联pojo对象对应表的主键字段" jdbcType="字段类型" property="关联pojo
对象的属性"/>
 <result column="表的字段" jdbcType="字段类型" property="关联pojo对象的属性"/>
 </association>
 <!-- 集合中的property 需要为oftype定义的pojo对象的属性-->
 <collection property="pojo的集合属性名称" ofType="集合中单个的pojo对象类型">
 <id column="集合中pojo对象对应在表的主键字段" jdbcType="字段类型" property="集合
中pojo对象的主键属性" />
 <result column="任意表的字段" jdbcType="字段类型" property="集合中的pojo对象的属
性" /> 
 </collection>
</resultMap>

5.多级缓存与懒加载

Mybatis⼀级缓存

⼀级缓存的作⽤域是 SQLSession ,同⼀个 SqlSession 中执⾏相同的 SQL 查询 (相同的SQL 和参数 ),第⼀次会去查询数据库并写在缓存中,第⼆次会直接从缓存中取; 基于 PerpetualCache 的 HashMap本地缓存; 默认开启⼀级缓存; 失效策略:当执⾏ SQL 时候两次查询中间发⽣了增删改的操作,即 insert 、 update 、 delete 等操作 commit 后会清空该 SQLSession 缓存 ; ⽐如 sqlsession 关闭,或者清空等;

Mybatis⼆级缓存

⼆级缓存是 namespace 级别的,多个 SqlSession 去操作同⼀个 namespace下的Mapper 的 sql 语句,多个 SqlSession 可以共⽤⼆级缓存 , 如果两个 mapper 的 namespace相同,(即使是两个 mapper ,那么这两个 mapper 中执⾏ sql查询到的数据也将存在相同的⼆级缓存区域中,但是最后是每个 Mapper 单独的名称空间); 基于 PerpetualCache 的 HashMap 本地缓存,可⾃定义存储源,如 Ehcache/Redis 等; 默认是没有开启⼆级缓存; 操作流程:第⼀次调⽤某个 namespace 下的 SQL去查询信息,查询到的信息会存放该 mapper 对应的⼆级缓存区域。 第⼆次调⽤同个 namespace 下的 mapper映射⽂件中,相同的 sql 去查询信息,会去对应的⼆级缓存内取结果; 失效策略:执⾏同个 namespace 下的 mapepr 映射⽂件中增删改 sql ,并执⾏了 commit 操作 ,会清空该⼆级缓存 注意:实现⼆级缓存的时候, MyBatis 建议返回的 POJO是可序列化的, 也就是建议实现 Serializable 接⼝ 缓存淘汰策略:会使⽤默认的 LRU 算法来收回(最近最少使⽤的) 如何开启某个⼆级缓存 mapper.xml ⾥⾯配置
<!--开启mapper的namespace下的⼆级缓存-->
 <!--
 eviction:代表的是缓存回收策略,常⻅下⾯两种。
 (1) LRU,最近最少使⽤的,⼀处最⻓时间不⽤的对象
 (2) FIFO,先进先出,按对象进⼊缓存的顺序来移除他们
 flushInterval:刷新间隔时间,单位为毫秒,这⾥配置的是100秒刷新,如果不配置
它,当SQL被执⾏的时候才会去刷新缓存。
 size:引⽤数⽬,代表缓存最多可以存储多少个对象,设置过⼤会导致内存溢出
 readOnly:只读,缓存数据只能读取⽽不能修改,默认值是false
 -->
<cache eviction="LRU" flushInterval="100000" readOnly="true" size="1024"/>
全局配置:
<settings>
<!--这个配置使全局的映射器(⼆级缓存)启⽤或禁⽤缓存,全局总开关,这⾥关闭,mapper中开启
了也没⽤-->
 <setting name="cacheEnabled" value="true" />
</settings>
如果需要控制全局 mapper ⾥⾯某个⽅法不使⽤缓存,可以配置 useCache="false"
<select id="selectById" parameterType="java.lang.Integer"
resultType="Test" useCache="false">
select <include refid="base_test_field"/> from t_test2 where id = #
{test_id,jdbcType=INTEGER}
</select>
优先查询⼆级缓存 - 》查询⼀级缓存 - 》数据库 什么是懒加载: 按需加载,先从单表查询,需要时再从关联表去关联查询,能⼤⼤提⾼数据库性能 , 并不是所有场景下使⽤懒加载都能提⾼效率 Mybatis 懒加载: resultMap ⾥⾯的 association 、 collection 有延迟加载功能
<!--全局参数设置-->
<settings>
 <!--延迟加载总开关-->
 <setting name="lazyLoadingEnabled" value="true"/>
 <!--将aggressiveLazyLoading设置为false表示按需加载,默认为true-->
 <setting name="aggressiveLazyLoading" value="false"/>
</settings>
<resultMap id="TestOrderResultMapLazy" type="TestOrder">
 <id column="id" property="id"/>
 <result column="user_id" property="userId"/>
 <result column="out_trade_no" property="outTradeNo"/>
 <result column="create_time" property="createTime"/>
 <result column="state" property="state"/>
 <result column="total_fee" property="totalFee"/>
 <result column="test_id" property="testId"/>
 <result column="test_title" property="testTitle"/>
 <result column="test_img" property="testImg"/>
<!--
select: 指定延迟加载需要执⾏的statement id
column: 和select查询关联的字段
-->
<association property="user" javaType="User" column="user_id"
select="findUserByUserId"/>
</resultMap>
 <!--⼀对⼀管理查询订单, 订单内部包含⽤户属性 懒加载-->
<select id="queryTestOrderListLazy" resultMap="TestOrderResultMapLazy">
 select
 o.id id,
 o.user_id ,
 o.out_trade_no,
 o.create_time,
 o.state,
 o.total_fee,
 o.test_id,
 o.test_title,
 o.test_img
 from test_order o
</select>
<select id="findUserByUserId" resultType="User">
 select * from user where id=#{id}
</select>
dubug 模式测试懒加载不准确,可以直接 run

6.MyBatis3.x 的事务管理形式

使⽤JDBC的事务管理

使⽤ java.sql.Connection 对象完成对事务的提交( commit() )、回滚( rollback())、关闭( close() )

使⽤MANAGED的事务管理

MyBatis ⾃身不会去实现事务管理,⽽让程序的容器如( Spring, JBOSS)来实现对事务的管理
<environment id="development">
 <!-- mybatis使⽤jdbc事务管理⽅式 -->
 <transactionManager type="JDBC"/>
 <dataSource type="POOLED">
 <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
 <property name="url"
value="jdbc:mysql://127.0.0.1:3306/test?
useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false"/>
 <property name="username" value="test"/>
 <property name="password" value="test"/>
 </dataSource>
</environment>
事务⼯⼚ TransactionFactory 的两个实现类 JdbcTransactionFactory->JdbcTransaction ManagedTransactionFactory->ManagedTransaction 注意:如果不是 web 程序,然后使⽤的事务管理形式是 MANAGED, 那么将没有事务管理功能
上一篇:正则表达式 部分总结


下一篇:eclipse中使用anaconda引入numpy等包