文章目录
- Mybatis官方中文文档
- 一、Mybatis简介
- 二、简单入门使用
- 2.1、在pom.xml中添加依赖
- 2.2、使用xml配置文件
- 2.3、创建接口
- 2.4、创建映射文件
- 2.6、获取sqlsession实例并执行方法
- 三、Mybatis的Xml配置文件
- 3.1、properties属性
- 3.2、settings设置
- 3.3、typeAliases类型别名
- 3.4、environments环境配置
- 3.4.1、environment环境变量
- 3.4.2、transactionManager事务管理器
- 3.4.3、dataSource数据源
- 3.4.4、mappers映射器
- 四、XML映射器
- 4.1、命名空间
- 4.2、select
- 4.3、insert,update和delete
- 4.4、sql
- 4.5、参数
- 4.6、resultMap结果映射
- 在resultMap中使用顺序:
- 在resultMap中常用元素:
- ResultMap常用属性
- id和result的常用属性
- association一对一关联常用属性
- collection一对多集合关联常用属性
- 结果映射例子:
- 五、动态SQL
- 5.1、if
- 5.2、choose、when、otherwise
- 5.3、where、set
- 5.4、foreach
Mybatis官方中文文档
此处是根据官方文档与自己的一些实践所写,若想继续详细了解请查看(官方中文文档)
一、Mybatis简介
- Mybatis是一款优秀的持久层矿建,它支持自定义SQL、存储过程以及高级映射。
- Mybatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。
- Mybatis可以通过简单的XML或注解来配置和映射原始类型、接口和Java POJO为数据库中的记录。
二、简单入门使用
2.1、在pom.xml中添加依赖
<!-- mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<!-- 测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.11</version>
</dependency>
2.2、使用xml配置文件
xml配置文件中包含了对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>
<!-- 数据源配置文件 -->
<properties resource="database.properties"></properties>
<typeAliases>
<!-- 实体类所在包 -->
<package name="org.example.demo.pojo"/>
</typeAliases>
<!-- mysql数据源 -->
<environments default="mysqlDev">
<environment id="mysqlDev">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${mysqlDriver}"/>
<property name="url" value="${mysqlUrl}"/>
<property name="username" value="${mysqlUser}"/>
<property name="password" value="${mysqlPwd}"/>
</dataSource>
</environment>
</environments>
<!-- 持久层所在的包 -->
<mappers>
<package name="org.example.demo.dao"/>
</mappers>
</configuration>
2.3、创建接口
package org.example.demo.dao;
import org.example.demo.pojo.Dog;
import java.util.List;
/**
* @program: mybatisXsqone
* @interfaceName DogDao
* @description:
* @author: 太白
* @create: 2023-01-11 15:24
**/
public interface DogDao {
List<Dog> selectList();
}
2.4、创建映射文件
对应Dao包创建目录。注意:创建目录需使用 / 是层级目录,使用.是一个目录
创建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="org.example.demo.dao.DogDao">
<select id="selectList" resultType="org.example.demo.pojo.Dog">
select * from dog
</select>
</mapper>
2.6、获取sqlsession实例并执行方法
package org.example.demo.dao;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.example.demo.pojo.Dog;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
/**
* @program: mybatisXsqone
* @interfaceName DogDaoTest
* @description:
* @author: 太白
* @create: 2023-01-11 15:29
**/
public class DogDaoTest {
public SqlSession init(){
System.out.println("Start");
// 加载配置文件
InputStream inputStream = DogDaoTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
// 获取builder工厂
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 通过建造工厂来建造sqlsessionfactory
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
// 创建sqlsession实例
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
public void down(SqlSession sqlSession){
sqlSession.commit();
sqlSession.close();
System.out.println("over");
}
@Test
public void testSelectList() {
SqlSession sqlSession = this.init();
DogDao mapper = sqlSession.getMapper(DogDao.class);
List<Dog> dogs = mapper.selectList();
for (Dog dog : dogs) {
System.out.println(dog);
}
this.down(sqlSession);
}
}
三、Mybatis的Xml配置文件
配置文件的结构如下:
- configuration (配置)
- properties (属性)
- settings (设置)
- typeAliases (类型别名)
- objectFactory (对象工厂)
- plugins (插件)
- environments (环境配置)
- environment (环境变量)
- transactionManager (事务管理器)
- dataSource (数据源)
- databaseIdProvider (数据库厂商标识)
- mappers(映射器)
配置文件头 :
<?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">
3.1、properties属性
<!-- 数据源属性(配置到外部资源文件) -->
<properties resource="database.properties"></properties>
<!-- 数据源属性(配置到mybatis的配置文件中) -->
<properties>
<property name="mysqlDriver" value="com.mysql.cj.jdbc.Driver"/>
<property name="mysqlUrl" value="jdbc:mysql://192.168.136.204:3306/jdbcdb?allowMultiQueries=true"/>
<property name="mysqlUser" value="root"/>
<property name="mysqlPwd" value="root"/>
</properties>
3.2、settings设置
驼峰命名较为常用,其他设置一般默认即可 (详情设置请查看官方文档)
<!-- 设置驼峰命名-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
3.3、typeAliases类型别名
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写
<typeAliases>
<!-- 指定包名(在此包下搜索需要的JavaBean) -->
<package name="org.example.demo.pojo"/>
<!-- 指定类名 -->
<!-- <typeAlias type="org.example.pojo.Dog" alias="Dog"/>-->
</typeAliases>
3.4、environments环境配置
3.4.1、environment环境变量
MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中使用相同的 SQL 映射。
注意:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。
若想连接两个数据库,就创建两个SqlSessionFactory实例,每个数据库对应一个。
例如:配置文件如下:
<!-- 创建sqlSessionFactory默认使用mysqlDev的数据源 -->
<environments default="mysqlDev">
<environment id="mysqlDev">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${mysqlDriver}"/>
<property name="url" value="${mysqlUrl}"/>
<property name="username" value="${mysqlUser}"/>
<property name="password" value="${mysqlPwd}"/>
</dataSource>
</environment>
<environment id="oracleDev">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${oracleDriver}"/>
<property name="url" value="${oracleUrl}"/>
<property name="username" value="${oracleUser}"/>
<property name="password" value="${oraclePwd}"/>
</dataSource>
</environment>
</environments>
创建SqlSessionFactory实例代码:
// 加载配置文件
InputStream inputStream = DogDaoTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
// 获取builder工厂
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 通过建造工厂来建造sqlsessionfactory
SqlSessionFactory mysqlFactory = sqlSessionFactoryBuilder.build(inputStream,"mysqlDev");
SqlSessionFactory oracleFactory = sqlSessionFactoryBuilder.build(inputStream,"oracleDev");
3.4.2、transactionManager事务管理器
在mybatis中有两个类型的事物管理器 (JDBC | MANAGED)
- JDBC
- 这个配置直接使用了JDBC的提交和回滚功能,它依赖从数据源获得的连接来管理事务作用域。
- 默认情况下,为了与某些驱动程序兼容,它在关闭连接时启动自动提交。
- 对于某些驱动程序来说启动自动提交不仅是不必要的,而且是代价高昂的操作。在3.5.10版本开始可以通过将“skipSetAutoCommitOnClose”属性设置为true来跳过这个步骤
<transactionManager type="JDBC">
<property name="skipSetAutoCommitOnClose" value="true"/>
</transactionManager>
- MANAGED
- 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。
- 默认情况下会关闭连接。
- 在一些容器不希望连接被关闭,隐藏可以将“closeConnection”属性设置为false来阻止默认关闭的行为
<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/>
</transactionManager>
3.4.3、dataSource数据源
在mybatis中有三种内检的数据源类型(UNPOOLED | POOLED | JNDI)
- UNPOOLED
- 每次请求都会打开和关闭链接
- POOLED (类似于c3p0有诸多连接池的配置,但都拥有默认值)
- 利用“池”的改建将JDBC连接对象组织起来,避免了创建新的链接实例是所必需的初始化和认证时间。
- JNDI(很少用)
常用属性配置:
属性 | 描述 | 数据源类型 |
---|---|---|
driver | JDBC驱动 | UNPOOLED | POOLED |
url | 数据库的JDBC URL 地址 | UNPOOLED | POOLED |
username | 数据库用户名 | UNPOOLED | POOLED |
password | 数据库密码 | UNPOOLED | POOLED |
poolMaximumActiveConnections | 在任意时间可存在的活动连接数量(默认为 10) | POOLED |
poolMaximumIdleConnections | 在任意时间可勋在的空闲连接数量 | POOLED |
poolMaximumCheckoutTime | 强制返回之前,池中连接被检出时间(默认为20秒(20000ms)) | POOLED |
3.4.4、mappers映射器
用来定义SQL映射语句。告诉Mybatis去哪里找映射文件。
<mappers>
<!--使用相对于类路径的资源引用-->
<!-- <mapper resource="org/example/dao/DogDao.xml"/>-->
<!--使用完全限定资源定位符(URL)-->
<!-- <mapper url="file:///E:/lovejava/student/mybatis/src/main/resources/org/example/dao/DogDao.xml"/>-->
<!-- 使用映射器接口实现类的完全限定类名 -->
<!-- <mapper class="org.example.dao.DogDao"/>-->
<!-- 将包内的映射器接口全部注册为映射器 -->
<package name="org.example.demo.dao"/>
</mappers>
四、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="">
</mapper>
元素(在mapper中):
元素名称 | 描述 |
---|---|
cache | 该命名空间的缓存配置 |
cache-ref | 引用其他命名空间的缓存配置 |
resultMap | 描述如何从数据库结果集中加载对象 |
sql | 可被其他语句引用的可重复语句块 |
insert | 映射插入语句 |
update | 映射更新语句 |
delete | 映射删除语句 |
select | 映射查询语句 |
4.1、命名空间
命名空间为:通用格式中的namespace
作用:
- 利用更长的全限定名将不同的语句隔离开来
- 实现了接口绑定
- 全限定名:(比如:com.example.dao.Dogdao.select),被直接用于查找及使用
- 短名称:(比如:select),如果是全局唯一可以作为一个单独引用,若不唯一或有两个或两个以上的相同名称,那么使用时就会产生 短名不唯一 的错误,这种情况下就需要使用全限定名。
4.2、select
常用属性:
属性 | 描述 |
---|---|
id | 在命名空间中唯一的标识符,可以被用来引用这条语句 |
parameterType | 将会传入这条语句的参数的类全限定名或别名。(可选) |
resultType | 期望从这条语句中返回结果的类全限定名或别名。(resultType和resultMap只可用一个) |
resultMap | 对外部resultMap的命名引用 |
4.3、insert,update和delete
常用属性:
属性 | 描述 |
---|---|
id | 在命名空间中唯一的标识符,可以被用来引用这条语句 |
parameterType | 将会传入这条语句的参数的类全限定名或别名。(可选) |
4.4、sql
这个元素可以用来定义可重复使用的SQL代码片段,以便在其他语句中使用。
使用 <include refid=" "/> 来调用
例如:
<sql id="dogField">
id,name,health,love,strain,lytm
</sql>
<select id="selectList" resultType="org.example.demo.pojo.Dog">
select <include refid="dogField"></include> from dog
</select>
4.5、参数
-
只传一个参数:
原始类型或简单数据类型因为没有其他属性,会直接用它的值来作为参数。(这个参数可以随意命名)
例如:
java接口int delete(int id);
xml文件:
<delete id="delete"> delete from dog where id = #{id} </delete>
-
传一个对象:
如果传一个对象到了语句中,会查找它的属性,将它们的值传入与处理语句的参数中。
例如:
java接口int save(Dog dog);
xml文件:
<insert id="save"> insert into dog(name,health,love,strain,lytm) values (#{name},#{health},#{love},#{strain},now()); </insert>
-
传多个参数
@Param用于dao层,是mybatis中的注解
使得mapper.xml中的参数与后台的参数对应上,也增强了可读性
例如:
java接口List<Dog> selectLoveHealth(@Param("love") Integer love, @Param("health") Integer health);
xml文件:
<select id="selectLoveHealth" resultType="org.example.pojo.Dog"> select * from dog where love=#{love} and health=#{health}; </select>
4.6、resultMap结果映射
- resultMap 元素是 MyBatis 中最重要最强大的元素。
- 它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。
- 实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的数千行代码。
- ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
在resultMap中使用顺序:
constructor? , id* , result* , association* , collection* , discriminator?
在resultMap中常用元素:
- id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
- result – 注入到字段或 JavaBean 属性的普通结果
- association – 一个复杂类型的关联;许多结果将包装成这种类型
- 嵌套结果映射 – 关联可以是 resultMap 元素,或是对其它结果映射的引用
- collection – 一个复杂类型的集合
- 嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用
ResultMap常用属性
属性 | 描述 |
---|---|
id | 当前命名空间中的一个唯一标识,用于标识一个结果映射。 |
type | 类的完全限定名,或者一个类别名称 |
id和result的常用属性
属性 | 描述 |
---|---|
property | 映射到列的字段或属性 |
column | 数据库中的列名,或者是列的别名 |
javaType | 一个Java类的全限定名,或一个类型别名 |
association一对一关联常用属性
属性 | 描述 |
---|---|
property | 映射到列的字段或属性 |
javaType | 一个Java类的全限定名,或一个类型别名 |
column | 数据库中的列名,或者是列的别名 |
select | 用于加载复杂类型属性的映射语句ID,会从column属性指定的列中检索数据,作为参数传递给目标select语句 |
collection一对多集合关联常用属性
在collection和accociation类似但会有一个新的“ofType”属性:
属性 | 描述 |
---|---|
ofType | 将 JavaBean(或字段)属性的类型和集合存储的类型区分开来 |
<collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPostsForBlog"/>
可看出posts存储Post的ArrayList集合
在一般情况下,Mybatis可以推断javaType属性为ArrayList,因此不需要填写,可以简写为:
<collection property="posts" column="id" ofType="Post" select="selectPostsForBlog"/>
结果映射例子:
一对多,一对一是可以嵌套的。
<resultMap id="dogMap1" type="dog">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="health" property="health"></result>
<result column="love" property="love"></result>
<result column="strain" property="strain"></result>
<result column="lytm" property="lytm"></result>
<association property="strainInfo" javaType="StrainInfo">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
<result column="describe" property="describe"/>
</association>
<collection property="masters" ofType="Master">
<id column="pid" property="pid"></id>
<result column="uname" property="name"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>
<result column="yearnum" property="yearnum"></result>
<!-- <result column="did" property="dog.id"></result>-->
</collection>
</resultMap>
五、动态SQL
5.1、if
<update id="update">
update dog
<set>
<if test="name!=null and name != '' ">
name = #{name},
</if>
<if test="health!=null ">
health = #{health},
</if>
<if test="love!=null">
love = #{love},
</if>
<if test="strain!=null and strain != '' ">
strain = #{strain},
</if>
</set>
where id = #{id}
</update>
5.2、choose、when、otherwise
有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
<select id="getDog" resultType="org.example.pojo.Dog">
select id,name,health,love,strain,lytm from dog
<choose>
<when test="sort == 1">
order by lytm asc
</when>
<when test="sort == 2">
order by lytm desc
</when>
<otherwise>
order by id desc
</otherwise>
</choose>
</select>
5.3、where、set
前几个例子已经解决了一些动态SQL问题,若如下:
<select id="getDog" resultType="org.example.pojo.Dog">
select id,name,health,love,strain,lytm from dog
WHERE
<if test="name!= null and name != null">
AND name like #{name}
</if>
<if test="strain!= null">
AND strain like #{strain}
</if>
</select>
若没有匹配的条件,最终SQL会变成:
select id,name,health,love,strain,lytm from dog
WHERE
这会导致查询失败,若只匹配第二个条件,最终SQL会变成:
select id,name,health,love,strain,lytm from dog
WHERE AND strain like #{strain}
这个也会导致查询失败,这个问题不能简单的用条件元素来解决。在mybatis中也考虑到了这种场景可以如下写:
<select id="getDog" resultType="org.example.pojo.Dog">
select id,name,health,love,strain,lytm from dog
<where>
<if test="name!= null and name != null">
AND name like #{name}
</if>
<if test="strain!= null">
AND strain like #{strain}
</if>
</where>
</select>
where 元素只会在子元素返回任何情况下才插入“WHERE”语句,而且,若字句开头为“and”或“or”开头,where元素也会将它们去除
用于动态更新语句的类似解决方案为set元素,set元素可以用于动态包含需要更新的列,忽略其他不更新的列(会删除掉额外的逗号)
例如:
<update id="update">
update dog
<set>
<if test="name!=null and name != '' ">
name = #{name},
</if>
<if test="health!=null ">
health = #{health},
</if>
<if test="love!=null">
love = #{love},
</if>
<if test="strain!=null and strain != '' ">
strain = #{strain},
</if>
</set>
where id = #{id}
</update>
5.4、foreach
动态SQL的另一个常见使用场景是对集合进行遍历,如:
批量添加
<insert id="batchSave">
insert into dog
values
<foreach collection="list" item="dog" separator=",">
(null,#{dog.name},#{dog.health},#{dog.love},#{dog.strain},now())
</foreach>
</insert>
属性 | 描述 |
---|---|
collection | 表示如何来得到这个集合,如果传入的直接为一个List,那么collection值就为list,如果直接传入的为一个array不可变数组,那么collection值就为array |
item | 集合中每一个元素进行迭代时的别名 |
separator | 在每次进行迭代之间以什么符号作为分隔符 |
open | 该语句以什么开始 |
close | 以什么结束 |