Mybaits入门
一、Mybaits框架特点
- 支持定制化SQL、存储过程、基本路线以及高级映射
- 避免了几乎所有JDBC代码中手动设置参数以及获取结果集
- 支持注解式开发、XML开发
- ·····
二、开发我第一个MYbatis程序
-
①打包方式jar
-
②引入依赖
- mybatis依赖
- mysql驱动
前面两步的pom.xml文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.powernode</groupId> <artifactId>Mybatis-001</artifactId> <version>1.0-SNAPSHOT</version> <!--打包方式--> <packaging>jar</packaging> <dependencies> <!--`mybatis依赖 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.10</version> </dependency> <!--mysql驱动依赖 --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.0.33</version> </dependency> </dependencies> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> </project>
-
③编写mybatis核心配置文件:mybatis-config.xml
- 注意:
- 这个文件不是必须叫做mybatis-config.xml,可以随意取,只是这个常用
- 这个文件存放的位置也不是固定的,但是一般情况下,会放到类的根目录下
- mybatis-config.xml文件中的配置信息不懂不用管,先修改链接数据库的信息
- 注意:
-
④编写·····Mapper.xml文件
- 在这个文件中编写sql语句,这个文件名也不是固定的,放的位置也不是固定的,我们在这里取名,叫做CarMapper.xml,暂时方放到根的类路径下
-
⑤在mybatis-config.xml文件中指定····Mapper.xml文件的路径
- 如:
<mapper resource="CarMapper.xml"/>
- 注意:resource属性会自动从类的根路径下开始查找资源
- 如:
-
⑥编写mybatis程序(使用mybatis的类库,编写mybatis程序,连接数据库,做增删改查)
- 在mybatis中,负责执行SQL语句的那个对象叫做什么?
- 叫做SqlSession,其代表用来专门执行sql语句的是一个java程序和数据库之间的一次会话
- 要想SqlSession对象,先获取SqlSessionFactory对象,通过SqlSessionFactory工厂来生产SqlSession对象
- 怎么获取SqlSessionFactory对象?
- 先获取SqlSessionFactoryBuilder对象
- 通过SqlSessionFactoryBuilder对象的build方法,来获取一个SqlSessionFactory
- 所以综上:SqlSessionFactoryBuilder—>SqlSessionFactory—>SqlSession
- 在mybatis中,负责执行SQL语句的那个对象叫做什么?
1、从 XML 中构建 SqlSessionFactory
通过标题我们可以知道:
- 在mybatis中SqlSessionFactory是一个很重要的对象
- SqlSessionFactory对象的创建需要xml
xml是一个配置文件
2、mybatis中有两个重要的配置文件
其中一个就是mybatis-config.xml,这个是核心配置文件,主要配置链接数据库的信息等(一般是一个)
另一个是·····Mapper.xml,这个文件是专门用来编写SQL语句的配置文件(一般情况是一个表一个)
- user表,就有UserMapper.xml
- student表,就有StudentMapper.xml
3、关于第一个mybatis程序的细节
-
mybatis中sql语句的结尾;可以省略
-
Resources.getResourceAsStream("mybatis-config.xml");
- 以后凡是遇到resource这个单词,大部分情况,这种加载资源是从类的根路径下开始查找
- 优点:项目的移植性强,可以跨越操作系统
-
inputStream is = new FileInputStream("d:\\mybatis-confiog.xml");
- 假设这个xml文件在d盘,可以采用建流的方式,但是有缺点:可移植性太差,如果遇到跨操作系统的问题,就会无效
-
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");
- ClassLoader.getSystemClassLoader()获取系统的类加载器,系统类加载器有一个方法getResourceAsStream,就是从类路径当中加载资源的
- 通过源代码分析 :
Resources.getResourceAsStream("mybatis-config.xml");
底层源代码就是ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");
4、关于Mybatis的事物管理机制
-
在mybatis-config.xml文件中,可以通过以下的配置进行mybatis的事务管理
<transactionManager type="JDBC"/>
- type的值有两个:JDBC和MANAGED(大小写无所谓)
-
在mybatis中提供了两种事物管理机制
-
①JDBC事务管理器
- mybatis框架自己管理事物,采用原生的JDBC的代码去管理
- conn.setAutoCommit(false);//开启事务、
- ·····业务处理·····
- conn.commit();//手动提交事务
-
使用JDBC事务管理器的话,底层创建的事务管理器对象:JDBCTranscation对象
-
如果你编写的代码是下面的代码:
-
//再获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(true);
-
表示没有开启事务,因为底层不会执行:conn.setAutoCommit(false);
-
在JDBC事务中,没有执行conn.setAutoCommit(false);那么autoCommit就是true
-
如果autoCommit是true,就表示没有开启事务,只要执行任意一条DML语句,就提交一次
-
-
②MANAGED事物管理器
- mybatis不再负者事务的管理,事务交给其他容器来负责。例如:spring
-
-
注意:
- 只要autoCommit就是true就表示没有开启事务
- 只要autoCommit就是false就表示开启事务
5、一个比较完整的Mybatis程序
package com.powernode.mybatis.test;
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 MybatisCompleteTest {
public static void main(String[] args) {
SqlSession sqlSession = null;
try {
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
//开启会话
sqlSession = sqlSessionFactory.openSession();
//执行sql语句,处理相关事务
int count = sqlSession.insert("insertCar");
System.out.println(count);
//执行到这里,没有发生任何异常,提交事务,终止事务
sqlSession.commit();
} catch (Exception e) {
//最好回滚事务
if(sqlSession!=null){
sqlSession.rollback();
}
e.printStackTrace();
}finally {
//关闭会话(就是释放资源)
if(sqlSession!=null) {
sqlSession.close();
}
}
}
}
三、Junit测试
注意MathServiceTest是对MathService类的junit测试,测试里面业务方法是否符合预期
//MathService
package com.powernode.junit.service;
/*
* 数学服务类
* */
public class MathService {
/**
* 求和业务方法
* @param a
* @param b
* @return
*/
public int sum(int a,int b){
return a+b;
}
/**
*求差的业务方法
* @param a
* @param b
* @return
*/
public int sub(int a,int b){
return a-b;
}
}
//MathServiceTest
package com.powernode.junit.service;
import org.junit.Assert;
import org.junit.Test;
/**
* 单元测试类
*
*/
public class MathServiceTest {//命名规范:你要测试的类+Test
/**
*单元测试方法写多少个
* 一般是一个业务方法对应一个测试方法
* 测试方法的规范:public void testXxxx(){}
* 测试方法的方法名:以test开始,假设的方法是sum,这个测试的方法名就是testsum
* @Test很重要,被这个注解标记的方法就是一个单元测试方法
*/
@Test
public void testSum(){
/*
* 单元测试中两个重要的概念:
* 一:实际值:(被测试的业务方法的真正执行结果)
* 二:期望值:(执行完这个业务方法之后,你期望的执行结果是多少)
* */
MathService mathService = new MathService();
//实际值
int actual = mathService.sum(1, 2);
//期望值
int expected = 3;
//加断言进行测试
Assert.assertEquals(expected,actual);
}
@Test
public void testSub(){
MathService mathService = new MathService();
//实际值
int actual = mathService.sub(10, 2);
//期望值
int expected = 8;
//加断言进行测试
Assert.assertEquals(expected,actual);
}
}
四、关于Mybatis集成日志组件
1、Mybatis常见的日志集成组件有哪些?
-
SLF4J (沙拉风)
- SLF4J是一个日志标准,其中有一个框架叫做logback,它实现了SLF4J
-
LOG4J
-
LOG4J2
-
JDK_LOGGING
-
COMMONS_LOGGING
-
STDOUT_LOGGING
- 这种可以看到连接对象是什么时候创建的,使命时候关闭的,sql语句内容等,但是没有详细的日期,线程名字等
-
NO_LOGGING
其中的STDOUT_LOGGING是标准日志,mybatis框架本身已经实现了这种标准,只要开启即可
开启方法:在mybatis-config.xml文件中使用settings标签
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
//这个标签在编写的时候,要注意顺序,在environments标签之前
2、集成logback日志框架
logback日志框架实现了slf4j标准
-
①引入logback的依赖
-
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.11</version> <scope>test</scope> </dependency>
-
-
②引入logback所必须的配置文件
- 这个配置文件的名字必须叫做:logback.xml或者logback-test.xml,不可以是其他的
- 这个配置文件的位置,必须放在类的根路径下
五、使用mybatis完成CRUD
- C:Create 增
- R:Retrieve 查
- U:Update 改
- D:Delete 删
1、先实现insert
-
在JDBC中占位符使用的是?,而在mybatis中使用的#{},和JDBC中的?等效
-
java程序中使用Map可以给SQL语句的占位符传值
-
用map集合传参
-
这是class类中的代码
-
Map<String,Object> map = new HashMap<>(); map.put("carNum","1111"); map.put("brand","比亚迪唐"); map.put("guidePrice",10.0); map.put("produceTime","2020-11-04"); map.put("carType","电车");
-
-
这是CarMapper.xml配置文件的写法
-
<!--insert语句 ,id是这个sql语句的唯一标识,这个id就表示这条sql语句--> <insert id="insertCar"> /*#{}中的{}写的是map中的key*/ insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType}); </insert>
-
-
-
使用pojo传参
-
class类中的代码
-
@Test public void testInsertCarByPojo(){ SqlSession sqlSession = SqlSessionUtil.openSession(); Car car = new Car(null,"2023","大众",9.0,"2020-01-23","油车"); int count = sqlSession.insert("insertCar", car); System.out.println(count); sqlSession.commit(); sqlSession.close(); }
-
-
这是CarMapper.xml配置文件的写法
-
<insert id="insertCar"> <!--#{}中的{}中存放的是pojo中的属性名--> <!--严格意义上来说,{}中应该是get方法中的方法名去掉get,首字母小写的单词,--> insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType}); </insert>
-
-
2、删除数据delete
根据id删除数据
-
class中的代码
-
@Test public void testDeleteById(){ SqlSession sqlSession = SqlSessionUtil.openSession(); int count = sqlSession.delete("deleteById",13); System.out.println(count); sqlSession.commit(); sqlSession.close(); }
-
xml文件中高度代码
-
<delete id="deleteById"> delete from t_car where id = #{id}; </delete>
-
-
3、改update
根据id修改某条记录
-
class中的代码
-
@Test public void testUpdateById(){ SqlSession sqlSession = SqlSessionUtil.openSession(); Car car = new Car(5L,"8888","劳斯莱斯",1000.0,"1956-08-09","油车"); sqlSession.update("updateById",car); sqlSession.commit(); sqlSession.close(); }
-
-
xml中的代码
-
<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>
-
4、select查询一个结果
-
class中的代码
-
@Test public void testSelectById(){ SqlSession sqlSession = SqlSessionUtil.openSession(); //mybatis底层执行了select一定会返回一个结果集对象:ResultSet //然后mybatis从结果集中取数据,封装java对象 Object car = sqlSession.selectOne("selectById", 1); System.out.println(car); sqlSession.close(); }
-
-
xml文件里面的代码
-
<select id="selectById" 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 where id = #{id} </select> <!--需要注意的是:在查询的时候,要指定,返回结果集的类型,使用resultType属性,-->
-
-
但是需要注意的是,会有几个属性的值没有被赋值成功,是因为我们在pojo类中的属性名和数据库中的列名不一样导致的
- 所以就可以使用起别名的方式去纠正
5、select查询所有的结果集
-
class中的代码
-
@Test public void testSelectAll(){ SqlSession sqlSession = SqlSessionUtil.openSession(); List<Object> cars = sqlSession.selectList("selectAll"); cars.forEach(car-> System.out.println(car)); sqlSession.close(); }
-
-
xml文件里面的代码
-
<select id="selectAll" 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>
-
6、关于SqlMapper中映射文件中的namespace
在SqlMapper.xml文件中有一个namespace,这个属性是用来指定命名空间的,用来防止id重复
- 情景:比如有两个SqlMapper.xml文件,一个a.xmL,一个b.xml,但是里面都有selectAll这个查询,但是我想执行a.xml文件中的那个selectAll,就在写java代码的时候:
List<Car> cars = sqlSession.selectList("a.selectAll");
- 即:namespace+id
六、Mybatis中的核心配置文件
1、environment标签
<?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>
<!--其中的一个环境,链接的数据库是powernode-->
<!--一般一个数据库会对应一个SqlSessionFactory对象-->
<!--一个环境会对应一个SqlSessionFactory对象-->
<environments default="powernodeDB"><!--default表示默认使用的环境
,这里就是说:当创建SqlSessionFactory对象时,没有指定环境,默认会使用powernodeDB-->
<environment id="powernodeDB">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_powernode?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<environment id="qfDB">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/qf?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="CarMapper.xml"/>
</mappers>
</configuration>
class代码
//直接上代码,自己看
@Test
public void testEnvironment() throws IOException {
//获取SqlSessionFactory对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//这个默认使用的环境就是environment中默认的
//SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
//这个就是指定了环境:就是qfDB
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"),"qfDB");
}
2、对数据源的解析(dataSource)
<dataSource type="POOLED">
<!--
dataSource:数据源
作用:为程序提供Connection对象,(但凡是给程序提供Connection对象的,都叫数据源)
常见的数据源组件(常见的数据库连接池有什么):
- druid(阿里巴巴德鲁伊连接池)
- c3p0
- dbcp
···
type属性用来指定数据源的类型:就是指定有什么方式来获取Connection对象
三个值:
- UNPOOLED:不使用数据库连接池技术,每一次请求之后,都创建新的Connection对象
- POOLED:使用mybatis自己实现的数据库连接池
- JNDI:集成第三方的数据库连接池
-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_powernode?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
数据库连接池参数:
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/qf?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<!--具体连接池中的参数应该如何配置:
poolMaximumActiveConnections:连接池中最多正在使用的连接对象的数量上限, 在任意时间可存在的活动(正在使用)连接数量,默认为10-->
<property name="poolMaximumActiveConnections" value="10"/>
<!--每隔2秒打印日志,并且尝试获取连接对象-->
<property name="poolTimeToWait" value="2000"/>
<!--强行让某个连接空闲,超时时间的设置-->
<property name="poolMaximumCheckoutTime" value="10000"/>
<!--最多的空闲数量-->
<property name="poolMaximumIdleConnection" value="5"/>
</dataSource>
3、对于mybatis-config.xml文件的mapper标签
mapper标签的属性一共三个:
-
resources
- 从类的根路径下开始查找资源,采用这种方式,你的配置文件需要放到类路径当中
-
url
- 这种方式是使用绝对路径的方法,这种方法不要求配置文件放到类路径当中
-
class
- 全限定接口名,必须带有带有包名
<mapper class="com.powernode.mybatis.mapper.CarMapper"/>
这种就是mybatis框架就会自动取com/powernode/mybatis/mapper下找CarMapper.xml文件- 也就是说:采用这种方式,就是CarMapper.xml文件和CarMapper接口必须在同一个目录下
- 全限定接口名,必须带有带有包名
-
但是这种事最常用的
<mappers> <!--使用这种方式要注意,CarMapper和CarMapper.xml文件都要在一个包下,这里看似不在一个,但是在同一个包当中--> <package name="com.powernode.mybatis.mapper"/> </mappers>
七、在WEB中使用Mybatis(MVC)
实现的小功能就是实现银行的转账功能,在前端页面输入金额,从而改变数据库中的金额
Demo:
mysql 版本 :8.0
jdk版本:17
idea版本:2023专业版
tomocat版本:9.0
maven、mybatis等驱动可以直接去maven远程仓库获取!!!注意版本问题
可以去我的百度网盘直接获取:
https://pan.baidu.com/s/1LSokTxuam9tqy_z4s8_rQA?pwd=81eb
提取码:81eb