【深入MyBatis】MyBatis之基础整理

一.MyBatis是什么?

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。MyBatis是一个 半自动化的ORM框架(Object Relational Mapping对象关系映射--解决面向对象和数据库发展不一致的问题)

①根据MyBatis官方的定义,MyBatis是支持定制化SQL语句,存储过程,高级映射的持久层框架.

②MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集的过程.

③MyBatis可以对配置和原生Map使用简单的XML或注解,将接口和Java的实体类映射成数据库的对应的记录.

二.MyBatis的使用流程总结

1.导入Jar包

asm-3.3.1.jar (java文件解析包,spring需要用到这个包)

cglib-2.2.2.jar(动态代理包,MyBatis通过动态代理,不需要编写Mapper接口的实现类)

commons-loggin-1.1.1.jar (日志包,spring需要用到这个包)

javassist-3.17.1-GA.jar (字节码解析助手包,处理.class文件)

log4j-1.2.17.jar、logj-api-2.0-rc1.jar、log4j-core-2.0-rc1.jar(这三个包都是log4j日志包)

mybatis-3.2.7.jar(mybatis核心包)

slf4j-api-1.7.5.jar(日志包)

slf4j-log4j12-1.7.5.jar(日志包)

2.构建实体类pojo包下的实体类构建

3.创建和配置mybatis.xml文件

①定义DTD文档约束(使用一系列合法的元素来定义文档结构)

<!--DTD是提高书写代码的速度,提供了快捷提示  -->
<?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标签(根标签)

③配置其子标签,各子标签的作用如下

<!-- 配置 -->
<configuration>
 <!-- 配置属性文件路径 -->
 <properties resource="config.properties">
 </properties>
 <!-- 开启log4j的 -->
 <settings >
 <setting name="logImpl" value="LOG4J"/>
<setting name="cacheEnabled" value="true"/>
 </settings>
 <!-- 设置实体类别名 -->
 <typeAliases>
 <!-- 别名 -->
 <!--<typeAlias type="com.bjsxt.pojo.Flower" alias="a"/> -->
 <!-- 声明包 resultType值为类名就行 (不区分大小写)-->
 <package name="com.bjsxt.pojo"></package>
 </typeAliases>
 <!-- 配置数据库 default属性表示要使用哪个数据库环境,值为environment 标签的id-->
 <environments default="mysql">
 <environment id="mysql">
 <!-- 配置数据库的事务管理 -->
 <transactionManager type="JDBC">
 <!-- type(JDBC|MANAGED) -->
 <!-- JDBC表示使用原生的事务管理器 -->
 <!-- MANAGED表示将事务管理交给容器管理,比如spring -->
 </transactionManager>
 <!-- 配置具体数据库参数 -->
 <dataSource type="POOLED">
 <!-- type为POOLED表示开启数据库连接池 -->
 <property name="url" value="${url}"/>
 <property name="username" value="${username}"/>
 <property name="password" value="${password}"/>
 <property name="driver" value="${driver}"/>
 </dataSource>
</environment>
</environments>
 <!-- 配置mapper文件 -->
<mappers>
 <!-- resource mapper文件的路径,便于同一加载解析 -->
引用url地址
<mapper url="file:///e:/..../.../mybatis.xml"  />
resource 切记:"/"的目录
<mapper resource="com/bjsxt/mapper/FlowerDMLMapper.xml"  />
 <package name="com.bjsxt.mapper"/>
 </mappers>
</configuration>

4.创建和配置mapper.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="包名.接口的名称">
<!-- id: 方法名称 resultType:返回值类型 如果返回的是一个对象,就写对象的实体即可 如果返回的是一个集合。书写集合的泛型的类型即可 parameterType:参数的类型 -->
<!--如果configuration中配置了typeAlias写别名即可,如果配置了package只写类名即可,不区分大小写-->
<select id="selectAll" resultType="com.bjsxt.pojo.Flower"> select * from flower </select>
</mapper> 

5.使用SqlSession的对象完成数据库操作

①获取读取mybatis.xml文件,获得配置文件输入流对象
InputStream is = Resources.getResourceAsStream("mybatis.xml");

②获取SqlSessionFactory工厂对象(通过实例化SqlSessionFactoryBuilder调用Builder方法,传入配置文件输入流对象,获取)
SqlSessionFactroy factory = new SqlSessionFactroyBuilder().build(is);

③获取SqlSession对象
SqlSession sqlSession = factory.openSession();

④使用sqlSession对象完成对数据库的操作
insert/update/delete
-----select的方法有很多----------------
MyBatis最初提供的API的方法有
selectOne("namespace+statementId",parameter)
selectList("namespace+statementId",parameter)
selectMap("namespace+statementId",parameter,key) 需要指定key为数据库的哪一个字段

⑤commit或者rollback,最后close关闭SqlSession

6.配置setting开启log4j的支持

MyBatis使用日志的最大的作用:
①就是为了方法的输出后台执行的sql语句和参数传递的变化过程,方便开发人员的调试
②可以把指定的日志信息按照规定的格式保存到本地文件中

log4j的五种级别
①FATAL
②ERROR
③WARN
④INFO
⑤DEBUG

在log4j.properties配置文件中配置
log4j.logger.com.xxxx.mapper=debug/trace         (log4j.logger+包名---即以该包名开头的所有的命名空间都用debug或者trace级别记录日志)

8.注意事项

①#{ }相当于展位操作
②${ }相当于拼接,无法应对sql注入攻击
③#{0}  #{param1}  获得下标为0的参数
④如果传入的参数只有一个,且类型为引入数据类型,非包装类或者String,不能使用#{0.name} #{param1.name}获取值,可以直接#{name},或者给该      参数在接口中添加注解,声明别名如:  List<Flower> select(@Param("f")Flower flower)
⑤select必须要声明返回值类型及resultMap或者resultType,DML语句不需要再标签中声明,因为返回的都是int
⑥标签中的parameterType可以省略,在底层会自动匹配参数类型,如果写了但写错了,会报错
⑦resultType如果为Map,sqlSession调用了selectMap()的方法,会自动生成一个类去存放所对应的数据库的字段值,和你声明的实体类无关,因此不能强转,否则会报错,但如果resultType为实体类如Flower,调用了selectMap()生成的value值得真实类型就是Flower了,可以强转,select底层都是调用了selectList方法


三.MyBatis的SQL动态拼接

1.if标签

<if test="param1!=null and param1!='' ">
</if>

2.where标签

自动在前面加上where,同时去除第一个and
<where>
</where>

3.choose when otherwise标签

相当于else if()只执行一个,后续都不执行
<choose>
        <when test="">

        </when>
        <otherwise>

        </otherwise>

</choose>

4.set标签
自动补充set关键字,并且把最后逗号去掉(只能用于update标签中)

<set>
    <if>
    </if>
</set>

5.trim标签

去除前缀后缀及添加前缀后缀----------功能十分强大
<trim prefix="set" suffixOverrides=",">
</trim>
prefix增加前缀  prefixOverrides去除前缀
suffix增加后缀   sufffixOverrides去除后缀

6.foreach标签

open开始  close结束  separator分割 item把每一个值赋予item
<foreach collection="list/array" open="(" close=")" separator="," item="it">
    #{it}
</foreach>

7.bind标签

用于模糊查询
<bind name="pa" value="'%'+param1+'%'"></bind>

8.sql标签

sql使用*效率非常低  可以使用sql配置替代*    ------------把相同的代码的内容提取出来
<sql id="..">
id,name,price
</sql>

9.include

INCLUDE引入SQL片段使用的标签
<include refid="sql的id"></include>

四.多表联合查询

1.resultMap的三个使用场景

①数据库的字段名和实体中的属性名

②N+1查询的时候 (注意:书写的两个表中的公共字段不可以省去)

③多表查询的sql语句的时候 (注意:即使字段名称一致也不可以省去)

2.什么时候使用 resultType 什么时候使用resultMap

①单表的查询的时候resultType

②数据库的字段和实体的属性不一致resultMap

③多表查询的sql语句的时候resultMap

3.业务代码方式和N+1方式的区别和联系

    联系:

          无论使用哪一种方式执行的sql语句都是N+1条

    不同点:

          业务代码:两个表的联系是使用java代码的方式进行关联的 

          N+1方式:mybatis标签的配置

4.示例

多对一的多表查询的sql语句
<resultMap id="rm1" type="student">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="password" property="password"></result>
<result column="clazz" property="clazz"></result>
<association property="cla" javaType="Clazz" >
<id column="cid" property="id"></id>
<result column="cname" property="name"></result>
</association>
</resultMap>

一对多的多表查询sql语句
<resultMap type="clazz" id="rm2">
 <id column="id" property="id"></id>
 <result column="name" property="name"></result>
 <collection property="stuList" ofType="student">
 <id column="sid" property="id"></id>
 <result column="sname" property="name"/>
 <result column="sage" property="age"/>
 <result column="sclazz" property="clazz"/>
 </collection>
 </resultMap>
注意:即使字段名称一致也不可以省去 

N+1方式的多表查询
如果是N+1方式跟上面两种方式差不多,但是在collection中和association中需要指定select(namespace+statementId或者自己写sql语句) ,还有要指定column,以指定的column为参数进行查询;column和你执行的sql语句要有关系;
注意:书写的两个表中的公共字段不可以省去  

五.mybatis中的注解

mubatis中的注解:

注解的出现就是为了简化XML 的操作

      @Select("select *  from student")

public  List<Student>  findAll();

@Select("select *  from  student  where  sid =#{0}")

public  Student  findOne(int  sid);

@Insert("insert into  student  values(default,#{sname},#{pwd},#{clazzno})")

public  int  insert(Student stu);

@Update("update  student  set  sname = #{sname}  where  sid=#{sid}")

public  int update(Student  stu);

@Delete("delete  from  student  where sid =#{0}")

    public  int  delete(int sid);

注解的缺点:

  [1]多表的查询支持操作不完善

  [2]使用XML的目的是实现java和SQL语句的问题

  [3]使用注解的使用必须保证  实体中的属性和数据库的字段必须一致

六.Mybatis的运行原理

1. 运行过程中涉及到的类


1.1 Resources MyBatis中IO流的工具类

1.1 加载配置文件

1.2 SqlSessionFactoryBuilder() 构建器

1.2.1 作用:创建SqlSessionFactory接口的实现类

1.3 XMLConfigBuilder  MyBatis全局配置文件内容构建器类

1.3.1 作用负责读取流内容并转换为JAVA代码.

1.4 Configuration 封装了全局配置文件所有配置信息.

1.4.1 全局配置文件内容存放在Configuration中

1.5 DefaultSqlSessionFactory 是SqlSessionFactory接口的实现类

1.6 Transaction 事务类

1.6.1 每一个SqlSession会带有一个Transaction对象.

1.7 TransactionFactory 事务工厂

1.7.1 负责生产Transaction

1.8 Executor  MyBatis执行器

1.8.1 作用:负责执行SQL命令

1.8.2 相当于JDBC中statement对象(或PreparedStatement或CallableStatement)

1.8.3 默认的执行器SimpleExcutor

1.8.4 批量操作BatchExcutor

1.8.5 通过openSession(参数控制)

1.9 DefaultSqlSession 是SqlSession接口的实现类

1.10 ExceptionFactory MyBatis中异常工厂

2.流程解释

在MyBatis运行开始时需要先通过Resources加载全局配置文件.下面需要实例化SqlSessionFactoryBuilder构建器.帮助SqlSessionFactory接口实现类DefaultSqlSessionFactory.

在实例化DefaultSqlSessionFactory之前需要先创建XmlConfigBuilder解析全局配置文件流,并把解析结果存放在Configuration中.之后把Configuratin传递给DefaultSqlSessionFactory.到此SqlSessionFactory工厂创建成功.

由SqlSessionFactory工厂创建SqlSession.

每次创建SqlSession时,都需要由TransactionFactory创建Transaction对象,同时还需要创建SqlSession的执行器Excutor,最后实例化DefaultSqlSession,传递给SqlSession接口.

根据项目需求使用SqlSession接口中的API完成具体的事务操作.

如果事务执行失败,需要进行rollback回滚事务.

如果事务执行成功提交给数据库.关闭SqlSession

-------------------------------------------------------------------------------------------
ps:下一节会对mybatis的缓存机制进行总结

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容