springboot 整合mybatis
1、SpringBoot+MyBatis
一、简单回顾一下MyBatis
核心对象包括以下三个:
-
SqlSessionFactoryBulider
-
SqlSessionFactory
-
SqlSession
-
SqlSessionFactoryBuilder --> SqlSessionFactory --> SqlSession
- 关于MyBatis的事务管理机制(两种)
<transactionManager type="JDBC"/> JDBC表示事务管理器 <transactionManager type="MANAGED"/> MANAGED表示事务事务管理器
JDBC事务管理器: MyBatis框架自己管理事务,自己采用原生的JDBC代码去管理事务:
// 关闭自动提交 开启事务 connection.setAutoCommit(false); ....业务处理 // 手动提交 使用JDBC事务管理器的话,底层创建的事务管理器对象:JdbcTransaction对象。 connection.commit(); // 如果编写的代码是下面的代码 // 表示没有开启事务。因为这种方式压根不会执行:conn.setAutoCommit(false)。 SqlSession sqlSession = sqlSessionFactory.openSession(true);
在JDBC事务中,没有执行conn.setAutoCommit(false);那么autoCommit就是true。 如果autoCommit是true,就表示没有开启事务。只要执行任意一条DML语句就提交一次。代码如下MANAGED事务管理器中有展示。
MANAGED事务管理器:
MyBatis不再负责事务的管理了。
事务管理交给其它容器来负责。对于我们当前的单纯的只有MyBatis的情况下,如果配置为:MANAGED 那么事务这块是没人管的。
没有人管理事务表示事务压根没有开启。没有人管理事务就是没有事务。
JDBC中的事务: 如果你没有在JDBC代码中执行下面这条语句,那么默认的autoCommit是true。
// 开启事务 connection.setAutoCommit(false); // 手动提交事务 connection.commit();
-
只要你的autoCommit(自动提交)是true,就表示没有开启事务。
在SpringBoot+MyBatis项目中就不用写事务相关的东西了,但是用到业务层Service就需要了
二、快速入门
第一步:引入依赖
<!-- MyBatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.5.3</version> </dependency> <!-- junit测试依赖 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <!-- lombok依赖 为了简化实体类的编写代码量 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
第二步:编写yml配置文件(此处我将properties后缀改成了yml)
其中包含连接数据库以及MyBatis的核心配置信息(但在SpringBoot框架中无需用MyBatis原核心配置文件)
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/powernode
username: root
password: root
mybatis:
mapper-locations: classpath:mapper/*.xml
#目的是为了省略resultType里的代码量
type-aliases-package: com.chf.pojo
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
第三步:构建实体类(在pojo包下),与表中字段一一对应
第四步:创建接口 mapper,用来写方法
第五步:每一个实体类对应一个mapper映射文件,在resources的mapper包下写映射文件(SQL语句)
其实这里的Sql语句是有问题的,查询到控制台的有问题,这里做个伏笔后面会知道为什么。
第六步:先测试自己是否成功连接到了数据库,不然你不管怎么测试方法都不知道你为什么爆红
测试成功,开心开心(这里控制台输出的null是我埋下的伏笔,下面会讲)
三、简易插入删除更改,mapper
@Mapper public interface CarMapper { /** * 插入汽车 * @return * @param car */ int insert(Car car); /** * 按id删除车辆信息 * @param id * @return */ int delete(Long id); /** * 更新车辆信息 * @param car * @return */ int update(Car car); }
xml
<!--namespace和里面标签的id两者都是为了动态代理而需要的--> <mapper namespace="com.chf.mapper.CarMapper"> <!-- #{}对应的是pojo层实体类的属性名"abcDe"对应的"getAbcDe"的"abcDe"(驼峰命名规范) 想简单点,对应属性名就行,复杂可能会乱ovo --> <insert id="insert"> insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType}) </insert> <!--如果占位符只有一个,其实可以随便写里面的内容但不能不写,但最好见名知意,这次只是测试--> <delete id="delete"> delete from t_car where id = #{dasdad} </delete> <update id="update"> update t_car set car_num=#{carNum}, brand=#{brand}, guide_price=#{guidePrice}, produce_time=#{produceTime}, car_type=#{carType} where id=#{id} </update> </mapper>
测试
@SpringBootTest public class Mybatis001IntroduceApplicationTests { @Autowired private CarMapper carMapper; @Test void testInsert(){ Car car = new Car(null,"111","奔驰",30.00,"2022-10-2","新能源"); int count = carMapper.insert(car); System.out.println((count == 1 ? "插入成功" : "插入失败")); } @Test void testDelete(){ int count = carMapper.delete(4L); System.out.println((count == 1 ? "删除成功" : "删除失败")); } @Test void testUpdate(){ Car car = new Car(6L,"1111","奔驰",30.00,"2022-10-2","新能源"); int count = carMapper.update(car); System.out.println((count == 1 ? "更新成功" : "更新失败")); } }
四、查询
通过控制台你会仔细的发现:除了id和brand其他皆为null。
原因就在于:属性名与表名不一致造成的,所以我们应该编写Sql语句就可以完成查询
②、按所有字段进行查询
这也是我在快速入门那里留下的伏笔,其实那个select也要进行修改
五、详解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> <!--default表示默认使用的环境--> <environments default="development"> <!-- 其中的一个环境 连接的数据库是powernode 一般一个数据库会对应一个SqlSessionFactory对象 一个环境environment会对应一个SqlSessionFactory对象 --> <environment id="development"> <!-- MyBatis事务管理器接口Transaction有两个实现类 如果type="JDBC"那么底层会实例化JdbcTransaction对象 如果type="MANAGED"那么底层会实例化ManagedTransaction对象 --> <transactionManager type="JDBC" /> <!-- datasource配置: 1、dataSource被称为数据源 2、dataSource为程序提供Connection对象 3、数据源实际上是一套规范,JDK中有这套规范:javax.sql.DataSource 4、type有三种值可选其一: POOLED:使用MyBatis自己实现的数据库连接池 UNPOOLED:不适用MyBatis的数据库连接池,每一次请求过来创建新的Connection对象 JNDI:集成其它第三方的数据库连接池,这是一套规范,大部分Web容器都实现了此规范 --> <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> <!--MyBatis另外一个环境,也就是连接的数据库是另一个数据库MyBatis--> <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> </environments> <!--通过此标签找到映射文件,实际在SpringBoot中的yml配置文件中变成:mybatis:mapper-locations--> <mappers> <package name="com.chf.mapper" /> </mappers> </configuration>
@SpringBootTest public class ConfigurationTest{ @Test void testEnvironment() throws Exception{ //获取SqlSessionFactory对象(采用默认方式获取) SqlSessionFactoryBuilder ssf = new SqlSessionFactoryBuilder(); //采用这种方式获取的就是默认的环境 SqlSessionFactory sqlSessionFactory = ssf.build(Resources.getResourceAsStream("MyBatisConfig.xml")); //这种方式通过id获取的是指定的环境 SqlSessionFactory sqlSessionFactory = ssf.build(Resources.getResourceAsStream("MyBatisConfig.xml"),"mybatisDB"); } }