Mybatis的含义
什么是Mybatis?
mybatis是一款优秀的数据持久层框架,是对jdbc进行了轻量级封装.
Mybatis能干什么?
- mybatis中的sqlsession是与数据库进行交互的对象.用作管理事物,管理缓存,当后面讲到一级缓存和二级缓存的时候缓存的创建就与sqlsession有关
- mybatis可以将数据库连接配置提取到xml文件中
- mybatis还可以将sql提取到xml文件中
- mybatis可以将数据库中的记录一一映射到java对象中,称此为orm映射.
- mybaits支持动态sql和缓存
Mybatis框架如何搭建
配置java项目中的pom.xml文件
- 首先需要配置java项目的根目录中的pom.xml,将mybatis的依赖先导入进去.之后再将mysql的依赖(也可以是你使用的数据库的依赖)导入进去.
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <version>8.0.16</version>
</dependency>
配置mybatis.xml文件
- 在resources文件夹下创建一个mybatis.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>
<!-- mybatis的核心配置文件 -->
<!-- 导入属性文件-->
<properties resource="config.properties"></properties>
<!-- 对mybatis全局的一个设置-->
<settings>
<!-- 指定日志组件,打印输出日志信息-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- 是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- <setting name="autoMappingBehavior" value="FULL"/> 需要慎用-->
<!-- 开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 定义类型的别名-->
<typeAliases>
<!-- <typeAlias type="com.ffyc.mybatispro.model.Admin" alias="Admin"></typeAlias>-->
<package name="com.ffyc.mybatispro.model"/>
</typeAliases>
<!-- 配置数据库连接信息-->
<environments default="development">
<environment id="development">
<!-- 配置事务管理器-->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${uname}" />
<property name="password" value="${upassword}"/>
</dataSource>
</environment>
</environments>
<!-- 配置注册sql映射文件-->
<mappers>
<mapper resource="mappers/AdminMapper.xml"></mapper>
<mapper resource="mappers/StudentMapper.xml"></mapper>
<mapper resource="mappers/MajorMapper.xml"></mapper>
</mappers>
</configuration>
-
在上述所配置的所有文件中,我都对他们的作用进行了注释并且在下文中都有解释,大家如果有不明白的,可以给我发私信.
Mybatis的使用
在我们使用Mybatis的过程中,我们需要了解Mybatis是通过将sql语句封装到框架中去来使用,从而大大减少了项目中Dao类的负担和代码冗余.所以我们对于mybatis的使用应该是显现在Dao类中的.
在Dao类中使用Mybatis
- 对于Mybatis的使用,我们是通过接口实现的,我们可以在项目的resources文件夹中创建一个Mapper文件夹,专门用来存放sql映射的xml文件.最后记得将这些xml文件写入到mybatis的核心配置中去
- 注:因为xml中不具备报错的功能,如果不小心写错会让开发者十分头痛,所以我们可以下一个插件来提醒我们是否出错.
sql映射文件中的使用方法
- 在sql映射文件中,我们需要搭建sql映射的核心配置
-
<?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"> <!--namesplace="接口的地址" 将xml文件与接口进行绑定--> <mapper namespace="com.ffyc.mybatispro.dao.MajorDao"> </mapper>
搭建完了之后就可以通过在接口中定义方法来在sql映射文件中实现.
动态sql的用法
- if的使用:if可以对传入的条件进行判断,例:
-
<trim prefix="where" prefixOverrides="and|or"> <if test="name!=null"> name=#{name} </if> <if test="gender!=null"> and gender=#{gender} </if> <if test="phone!=null"> and phone=#{phone} </if> </trim>
- trim的使用:他的参数由prefixOverrides和prefix等组成,他们的含义是当trim中前缀prefix出现后接着有prefixOverrides出现,就用prefixOverrides覆盖掉prefix.
- choose的使用:一般用于选择多项中的一项
-
<select id="findStudents" resultType="Student" parameterType="Student"> select * from student <trim prefix="where" prefixOverrides="and|or"> <choose> <when test="name!=null"> name=#{name} </when> <when test="phone!=null"> and phone=#{phone} </when> <otherwise> gender = '男' </otherwise> </choose> </trim> </select>
- Set的使用方法:在更新数据库操作的sql语句中,有时候会通过if来判断是否修改,但也要遵循sql语句的结构,例如下面这个代码
-
<update id="updateStudent" parameterType="Student"> update student <set> <if test="name!=null"> name=#{name}, </if> <if test="gender!=null"> gender=#{gender}, </if> <if test="phone!=null"> phone=#{phone} </if> </set> where id=#{id} </update>
- 此时是默认phone元素不存在的情况下,所以在phone=#{phone}后没有加逗号,但是如果phone==null的情况下,那么就不走这个if语句,那么上面gender=#{gender}就多了一个逗号,会导致sql语句的结构出现问题,此时就会用到set的功能
- set的功能就是会动态的去掉最后一条修改元素后的逗号.
- Foreach的使用方法:foreach的参数有item,index,collection,open,separator,close几个,其中item指的是在集合中每一个元素迭代的名字,index指的是一个下标,用于表示在迭代过程中迭代到的元素处于集合中的哪个位置,collection指迭代的是哪一个集合,open指的是语句从哪里开始,separator指的是迭代每一个元素以上面为分隔符,close表示以什么结束.
- sql映射中的一些特殊字符:
- < ----> <
- > ----> &rt;
- " ----> "
- ' ----> '
- & ----> &
Dao类中实现接口的返回值和传入参数如何在sql映射文件中显示
- 在sql映射文件中可以通过parameterType="数据类型"来进行传入参数的使用,还可以通过parameterMap="传入类型"来进行传入参数的使用.那么返回值应该如何返回呢?
- 如果我们实现的是单表的查询,我们只需要使用resultType="数据类型"进行返回,但是如果我们使用的是多表的嵌套查询,我们应该使用resultMap="数据类型"进行返回,在resultMap中我们又可以通过association和collection来进行多表的查询.
- 如果在我们相关联的表中,你需要查询的数据是单个元素,那么我们可以直接使用association来进行嵌套表元素的查询,他用到的参数分别是property(orm映射)和javaType(确认对象类型)
- 但是如果在我们相关联的表中,你需要查询的数据是不是单个的元素,那么你就需要使用collection来进行查询,他用到的参数是在上面的基础上加入了一个ofType,这个是为了确定集合中的数据类型(可以嵌套).
如何在使用类中使用Mybatis
- 在使用类中使用Mybatis的话,需要先创建一个SqlSessionFactory对象,之后创建一个流来读取mybatis核心配置文件,也就是resources中的mybatis.xml文件,最后通过SqlSessionFactory创建SqlSession对象,但是需要注意的是,由于SqlSessionFacory的开销较大,不能够一直创建,只需要一个框架创建一次就可以,所以我们将他封装到Util类中去.
-
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; import java.io.InputStream; public class MybatisUtil { static SqlSessionFactory sqlSessionFactory =null; static { //读取mybatis核心配置文件 InputStream inputStream = null; try { inputStream = Resources.getResourceAsStream("mybatis.xml"); } catch (IOException e) { e.printStackTrace(); } //创建SqlSessionFactory,用来创建SqlSession,在一个项目中,我们只创建一个sqSessionFactory,因为他的创建开销 较大 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } public static SqlSession getSqlSession(){ return sqlSessionFactory.openSession(); } }
- 注意:在sqlSession对象创建使用完后记得使用close方法将其关闭,而且在涉及到修改数据库记录的情况下,需要使用commit方法来更新数据库.
Mybatis中的一级缓存和二级缓存
为什么使用缓存
将一次mysql查询的内容放在一个java对象中,不销毁,当下次使用的时候,直接从java中获取,不从数据库中查询获得,减轻了数据库的压力
Mybatis中的一级缓存
- 一级缓存是sqlSession级别,同一个sqlSession中,查询相同数据第二次直接可以从缓存中获取.
- 一级缓存中的数据在sqlsession销毁后会自动消失,或者通过clearcache()方法来清除一级缓存中的数据,
- 执行insert,delete,update操作会清除一级缓存中的数据
Mybatis中的二级缓存
- 二级缓存是sqlsessionfactory级别,可以被多个sqlsession共享
- 默认不开启二级缓存,需要手动添加<setting name="cacheEnabled" value="true"/>来开启