一、什么是Mybatis
Mybatis 是一个持久层的框架(dao),他是一个半自动ORM(对象关系映射)框架,它是对jdbc操作的一次封装
ORM: Object Relational Mapping,简称ORM
O:对象
R:关系(对象和表关系)
M:映射(就是把表中的字段的值 映射到 对象的属性中)
半自动:就是需要自己书写sql语句
如何使用
1、导入Mybatis的架包
2、配置Mybatis中的核心配置文件(有两种):1:核心配置文件(mybatis-config.xml):配置数据源(数据库),配置缓存、日志、别名 2:映射文件(xxxxMapper.xml):配置对象与表之间的关系。然后通过sql语句来映射字段和对象属性的值
主配置文件
<?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="config/db.properties"></properties>
<settings>
<!--打开缓存-->
<setting name="cacheEnabled" value="true"/>
<!--使用懒加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--配置使用的日志框架 1 导包 2 使用log4j.properties文件-->
<!--该log4j.properties文件 必须(**)放置到src目录下-->
<setting name="logImpl" value="LOG4J"/>
</settings>
<!--配置类的别名-->
<typeAliases>
<!--用了别名以后 就不需要写包名-->
<package name="Bean"></package>
</typeAliases>
<!--插件配置-->
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
<!--helperDialect: 数据库的方式 : 连接的数据库的种类-->
<!--mysql: 使用mysql的数据库-->
<property name="helperDialect" value="mysql"/>
</plugin>
</plugins>
<!--配置应用的环境 默认开发环境-->
<environments default="development">
<environment id="development">
<!--使用jdbc的事务管理器-->
<transactionManager type="JDBC"/>
<!--配置数据源(使用的那个数据库)-->
<!--type="POOLED" 数据库连接池-->
<dataSource type="POOLED">
<property name="driver" value="${mysqlDriver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${user}"/>
<property name="password" value="${pass}"/>
</dataSource>
</environment>
</environments>
<!--映射器(mappers)-->
<mappers>
<!--映射配置文件-->
<mapper resource="config/mapper/studentMapper.xml"></mapper>
</mappers>
</configuration>
Mapper XML 文件 解读
MyBatis 的真正强大在于它的映射语句,也是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。
SQL映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):
cache – 给定命名空间的缓存配置。
cache-ref – 其他命名空间缓存配置的引用。
resultType:是用来处理简单对象的一种方式
resultMap:是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
sql – 可被其他语句引用的可重用语句块。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句
resultMap
constructor - 用于在实例化类时,注入结果到构造方法中
idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能
arg - 将被注入到构造方法的一个普通结果
id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
result – 注入到字段或 JavaBean 属性的普通结果
association – 一个复杂类型的关联;许多结果将包装成这种类型
嵌套结果映射 – 关联可以指定为一个 resultMap 元素,或者引用一个
collection – 一个复杂类型的集合嵌套结果映射 – 集合可以指定为一个 resultMap 元素,或者引用一个
discriminator – 使用结果值来决定使用哪个 resultMap.
简单写一下resultMap,详细解释看代码里面的注释
<?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="Dao.IClassDao">
<!--定义可重复使用的sql语句 主要是需要重写的列名-->
<sql id="studentcolumn">
s.sid as sid,
s.snamm as sname,
s.sex as sex,
c.id as cid,
c.cname as cname,
t.id as tid,
t.teacther as tea
</sql>
<resultMap id="classmap" type="ClassBean">
<id property="id" column="cid"></id>
<result property="name" column="cname"></result>
<!--一对一-->
<association property="teacther" javaType="Teacther">
<id property="id" column="tid"></id>
<result property="name" column="tea"></result>
</association>
<!--一对多-->
<collection property="stuList" ofType="StudentBean">
<id property="id" column="sid"></id>
<result property="name" column="sname"></result>
<result property="sex" column="sex"></result>
</collection>
</resultMap>
<!--接口方法的要求: 映射文件下的方法名 必须 和 接口中的方法名一样-->
<select id="getclasslist" resultMap="classmap">
SELECT <include refid="studentcolumn"></include>
from student s
LEFT JOIN class c on s.classid=c.id
LEFT JOIN teacther t on c.fk_teacther=t.id
</select>
<select id="getclassbean" resultMap="classmap" parameterType="int">
SELECT <include refid="studentcolumn"></include>
from student s
LEFT JOIN class c on s.classid=c.id
LEFT JOIN teacther t on c.fk_teacther=t.id
where c.id=#{arg}
</select>
</mapper>
缓存
Mybatis中有一级缓存和二级缓存,默认情况下一级缓存是开启的,而且是不能关闭的。一级缓存是指SqlSession级别的缓存,当在同一个SqlSession中进行相同的SQL语句查询时,第二次以后的查询不会从数据库查询,而是直接从缓存中获取,一级缓存最多缓存1024条SQL。二级缓存是指可以跨SqlSession的缓存。
Mybatis中进行SQL查询是通过org.apache.ibatis.executor.Executor接口进行的,总体来讲,它一共有两类实现,一类是BaseExecutor,一类是CachingExecutor。前者是非启用二级缓存时使用的,而后者是采用的装饰器模式,在启用了二级缓存时使用,当二级缓存没有命中时,底层还是通过BaseExecutor来实现的。
一级缓存
一级缓存是默认启用的,在BaseExecutor的query()方法中实现,底层默认使用的是PerpetualCache实现,PerpetualCache采用HashMap存储数据。一级缓存会在进行增、删、改操作时进行清除。
二级缓存
二级缓存是默认关闭的,如想开启,则可以通过Mybatis配置文件中的元素下的子元素来指定cacheEnabled为true。
<settings>
<setting name="cacheEnabled" value="true" />
</settings>
我们要想使用二级缓存,是需要在对应的Mapper.xml文件中定义其中的查询语句需要使用哪个cache来缓存数据的。这有两种方式可以定义,一种是通过cache元素定义,一种是通过cache-ref元素来定义。但是需要注意的是对于同一个Mapper来讲,它只能使用一个Cache,当同时使用了和时使用定义的优先级更高。Mapper使用的Cache是与我们的Mapper对应的namespace绑定的,一个namespace最多只会有一个Cache与其绑定。
动态 SQL
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似.MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。
if标签 条件控制
<if test="title != null">
AND title like #{title}
</if>
choose (when, otherwise) 条件控制
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
trim (where, set)
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
<if test="bio != null">bio=#{bio}</if>
</set>
foreach
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>