Mybatis 框架 --(ps:小狂神视频 + 个人领悟)

Mybatis 框架

1. 学习思路:

1. 搭建环境 
2. 导入Mybatis 
3. 编写代码
4. 测试 

2. 学习途径

一、Mybatis 介绍

1. 什么是mybatis?

1. MyBatis 是一款优秀的持久层框架,它支持定制SQL、存储过程以及高级映射。

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

3. MyBatis 可以使用简单的XML或注解来配置和映射原生类型、接口和Java的POJO(Plain Old Java Objects,普通老式Java对象)为数据库中的记录。

4. MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

5. iBATIS 一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)

6. 由实体类和SQL语句之间建立映射关系

2. 为什么需要mybatis?

1. 帮助程序员将数据存入到数据库中
		将sql语句封装在配置文件中,便于统一管理与维护,降低程序的耦合性.

2. 方便程序代码的调试

3. 传统的JDBC代码太复杂了。简化。框架。自动化。

4. 不用Mybatis也可以。但mybatis更容易上手。技术没有高低之分

5. 是一个开源框架,能了解底层的封装过程

3. mybatis的优点!

1. 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。

2. 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。

3. 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。

4. 提供映射标签,支持对象与数据库的orm字段关系映射。

5. 提供对象关系映射标签,支持对象关系组建维护。

6. 提供xml标签,支持编写动态sql。

4. Mybatis 缺点

1. SQL语句编写工 作量大,对开发人员有一定要求

2. 数据库移植性差

二、Mybatis 环境搭建

1. 普通 Java Web程序

  • 新建一个javaWeb程序
    新建普通javaWeb

  • 下载mybatis.jar包并导入工程

    • 下载mybatis下载
    • 导入jar文件
      jar包导入1
      jar包导入2
    • 修改编译后文件存放地址
      修改编译后class文件的存放地址
  • 编写核心配置文件

    • 创建 resources 资源目录
      创建 resources 资源目录
    • 编写核心配置文件
<?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="jdbc.properties"/>

    <!--    配置log日志-->
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <!--environments配置的是环境 可以有多个环境
        根据 id指定  default为默认环境-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 配置Mapper(注册Mapper) -->
    <!-- 每一个Mapper.xml都需要在核心配置文件中注册!!! -->
    <mappers>
        <mapper resource="cn/kgc/tangcco/dao/UserDao.xml"/>
    </mappers>
</configuration>
    • 创建实体类-pojo
1. 根据数据库中的表(表中的字段)创建实体类属性与表中字段一一对应
    • DAO层- SQL映射文件
      编写SQL映射文件
    • 创建测试类
      • 读取全局配置文件(核心配置文件)
// 1. 找到指定的配置文件(在本工程中 核心配置文件为mybatis-config.xml)
String resource = "mybatis-config.xml";
// 2. 将配置文件通过 Resources的 getResourceAsStream()方法 读取为输入流
InputStream inputStream = Resources.getResourceAsStream(resource);
      • 创建SqlSessionFactory对象,读取配置文件
// 3. 实例化 SqlSessionFactoryBuilder 对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 4. 通过 SqlSessionFactoryBuilder对象 读取输入流  获取SqlSessionFactory对象;
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(inputStream);
      • 创建SqlSession对象
// 从SqlSessionFactory中 获取 SqlSession对象,以获得在数据库执行 SQL 命令所需的所有方法
SqlSession sqlSession = factory.openSession();
      • 注意: 前三步 可以提取为工具类
public class SqlSessionFactoryUtil {
    private static SqlSessionFactory sqlSessionFactory;
    static{
        try {
            // 使用Mybatis第-步:获取sqlSessionFactory对象
            // 读取核心配置文件
            String resource = "mybatis-config.xml" ;
            InputStream inputStream = Resources.getResourceAsStream( resource) ;
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream) ;
        } catch (IOException e) {
            e. printStackTrace();
        }
    }

    //既然有了SqlSessionFactory, 顾名思义,我们就可以从中获得SqlSession的实例了。
    // SqlSession 完全包含了面向数据库执行SQL命令所需的所有方法。
    public static SqlSession getSqlSession(){
        // SqlSession sqlSession = sqlSessionFactory.openSession();
        // return sqlSession;
        return sqlSessionFactory.openSession();
    }
}
      • 调用mapper文件进行数据操作
// selectOne
@Test
public void totalCountTest() {
	SqlSession sqlSession = SqlSessionFactoryUtil.getSqlSession();
    Integer count = sqlSession.selectOne("cn.kgc.tangcco.demo01.dao.UserMapper.totalCount");
    log.info("totalCount  count== " + count);
    if (null != sqlSession) sqlSession.close();
}

@Test
public void totalCountTest02() {
    SqlSession sqlSession = SqlSessionFactoryUtil.getSqlSession();
    Integer count = sqlSession.getMapper(UserMapper.class).totalCount();
    log.info("totalCount  count== " + count);
    if (null != sqlSession) sqlSession.close();
}

2. maven程序

  • 新建一个maven 程序

  • 删除程序中的src目录

当前项目作为父级工程可以再当前工程中建立子工程
	子项目(子工程)不需要再次导入 父工程已有的依赖
  • 导入maven依赖
1. 数据库驱动
2. mybatis
3. junit测试
<dependencies>
    <!-- mysql -->
	<dependency>
		<groupId>mysq1</groupId>
		<artifactId>mysq1-connector-java</artifactId>
		<version>8.0.29</version>
	</dependency>

	<!-- mybatis -->
	<!-- https://mvnreposi tory. com/arti fact/org. mybatis/mybatis -->
	<dependency>
		<groupId>org. mybatis</groupId>
		<artifactId>mybatis</artifactId>
		<version>3.5.2</versi on>
	</dependency>
	<!-- junit -->
	<dependency>
		<groupId> junit</groupId>
		<artifactId>junit</artifactId>
		<version>4.12</version>
	</dependency>
</dependencies>
  • 创建项目 module
  • ** 编写核心配置文件 mybatis-config.xml**
<?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>
    
  <!-- environments  可以配合多套环境 default 为默认环境-->
    
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
    
  <!-- 每一个Mapper.xml都需要在核心配置文件中注册!!! -->
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>
  • **编写 mybatis 工具类 **
//sqlSessionFactory --> sqlSession
public class MybatisUtils {
	private static SqlSessionFactory sqlSessionFactory;
	static{
		try {
			// 使用Mybatis第-步:获取sqlSessionFactory对象
            // 读取核心配置文件
			String resource = "mybatis-config.xml" ;
			InputStream inputStream = Resources.getResourceAsStream( resource) ;
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream) ;
		} catch (IOException e) {
			e. printStackTrace();
		}
	}
    
	//既然有了SqlSessionFactory, 顾名思义,我们就可以从中获得SqlSession的实例了。
	// SqlSession 完全包含了面向数据库执行SQL命令所需的所有方法。
	public static SqlSession getSqlSession(){
        // SqlSession sqlSession = sqlSessionFactory.openSession();
        // return sqlSession;
		return sqlSessionFactory.openSession();
    }
}
  • 编写代码
1. 实体类 pojo
2. 接口 dao
3. 使用 xml配置文件 -- 替换 --> 接口实现类(使用jdbc的老套路) 
	由原来的DaoImpl 转变为一个 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 命名空间 -->
<!-- namespace=绑定一个**Mapper(就是**Dao)接口 -->
<!-- namespace= "该接口的完全限定名" -->
<mapper namespace="org.mybatis.example.BlogMapper">
  <!-- 查询语句 -->
  <!-- id="接口中的某一个方法" -->
  <!-- resultType="接口id对应方法的返回值(若是集合,则resultType=泛型对象)" -->
  <select id="selectBlog" resultType="Blog">
    <!-- sql 语句 -->
    select * from Blog where id = #{id}
  </select>
  <!-- 其他语句 -->
</mapper>
  • 编写测试类
public class DaoTest {

    /**
     * log 日志
     */
    private Logger log = Logger.getLogger(DaoTest.class);

    /**
     * 使用selectOne 调用Mapper文件时 :selectOne("命名空间的值.id值")
     *
     * 使用getMapper 调用Mapper文件时: getMapper(Mapper接口名称.class). 方法()
     */

    @Test
    public void totalCountTest() {
        // 通过工具类获取 sqlSession
        SqlSession sqlSession = SqlSessionFactoryUtil.getSqlSession();
        // sqlSession 调用 Mapper
        Integer count = sqlSession.selectOne("cn.kgc.tangcco.demo01.dao.UserMapper.totalCount");
		// 输出log日志
        log.info("totalCount  count== " + count);
        // 关闭 sqlSession
        if (null != sqlSession) sqlSession.close();
    }

    @Test
    public void totalCountTest02() {
        // 通过工具类获取 sqlSession
        SqlSession sqlSession = SqlSessionFactoryUtil.getSqlSession();
        // 通过sqlSession 调用Mapper
        Integer count = sqlSession.getMapper(UserMapper.class).totalCount();
		// 输出log日志
        log.info("totalCount  count== " + count);
        // 关闭sqlSession
        if (null != sqlSession) sqlSession.close();
    }
}
<!--在build中配置resources,来防止我们资源导出失败的问题-->
	<build>
		<resources>
			<resource>
				<directory>src/main/resources</directory>
				<includes>
				<include>**/* . properties</include>
				<include>**/* . xml</include>
				</includes>
				<filtering>true</filtering>
            </resource>
			<resource>
				<directory>src/main/java</directory>
				< includes>
				<include>**/* . properties</include>
				<include>**/* . xm1</ include>
				</includes>
				<filtering>true</filtering>
			</resource>
		</resources>
	</build>

三、配置文件 mybatis-config.xml详解

  • MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。

  • 配置文档的顶层结构

1. configuration(配置)

<configuration>
	<!-- configuration 是最顶级的标签,
	所有的配置子标签 都写在该标签的内部 -->
</configuration>

2. properties(属性)

<!-- 如果一个属性在不只一个地方进行了配置,那么,MyBatis 将按照下面的顺序来加载:
	首先读取在 properties 元素体内指定的属性。
	然后根据 properties 元素中的 resource 属性读取类路径下属性文件,或根据 url 属性指定的路径读取属性文件,并覆盖之前读取过的同名属性。
	最后读取作为方法参数传递的属性,并覆盖之前读取过的同名属性。
	因此,通过方法参数传递的属性具有最高优先级,resource/url 属性中指定的配置文件次之,最低优先级的则是 properties 元素中指定的属性。-->

<!-- 该标签 可以是双标签 也可以时单标签 -->

<!-- 双标签
 	例: 使用 xml 配置 数据库配置文件 db.properties-->
<properties>
    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
	<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis"/>
    <property name="username" value="root"/>
    <property name="password" value="123456"/>
</properties>

<!-- 单标签 
	例: 使用标签的resource属性 引用其他文件夹的配置文件-->
<properties resource="db.properties"/>

3. settings(设置)

<!-- settings标签是 MyBatis 中极为重要的调整设置,它会改变 MyBatis 的运行时行为-->

<!-- 设置名:autoMappingBehavior	
	指定 MyBatis 应如何自动映射列到字段或属性。 
	NONE 表示关闭自动映射;
	PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 (默认)
	FULL 会自动映射任何复杂的结果集(无论是否嵌套)。-->

<!-- 一个配置完整的 settings 元素的示例 -->
<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="multipleResultSetsEnabled" value="true"/>
  <setting name="useColumnLabel" value="true"/>
  <setting name="useGeneratedKeys" value="false"/>
  <setting name="autoMappingBehavior" value="PARTIAL"/>
  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
  <setting name="defaultExecutorType" value="SIMPLE"/>
  <setting name="defaultStatementTimeout" value="25"/>
  <setting name="defaultFetchSize" value="100"/>
  <setting name="safeRowBoundsEnabled" value="false"/>
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  <setting name="localCacheScope" value="SESSION"/>
  <setting name="jdbcTypeForNull" value="OTHER"/>
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

4. typeAliases(类型别名)

<!-- 类型别名可为Java类型设置一个缩写名字,仅用于XML配置,意在降低冗余的全限定类名书写 -->

<!-- 示例一:  User类 设置别名
	完全限定名为: cn.kgc.tangcco.demo01.pojo.User
	设置别名: user 
	当使用了类型别名时,所有出现该类型的完全限定名的地方,都可以使用 alias 别名代替-->
<typeAliases>
	<typeAlias alias="user" type="cn.kgc.tangcco.demo01.pojo.User"/>
</typeAliases>

<!-- 使用 typeAliases标签 指定一个包名 -->
<!-- 对包使用package 指定 
	则该包中的类,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名 
	若有注解,则别名为其注解值-->
<typeAliases>
	<package name="cn.kgc.tangcco.demo01.pojo"/>
</typeAliases>

5. typeHandlers(类型处理器)

6. objectFactory(对象工厂)

7. plugins(插件)

8. environments(环境配置)

1. 尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境

2. 需要配置默认使用哪一套环境 (默认使用的环境ID)
		比如:default="development"
		
3. 标签中必须要有: environment标签
  • 8.1 environment(环境变量)
1. 该标签在<environments> </environments> 中可以允许有多个.

2. 必须指定 id
	例如:<environment id="development"></environment>

3. 环境可以随意命名,但务必保证默认的环境environments中的id要匹配其中一个环境id

4. 标签中必须要有:transactionManager、dataSource标签
    • 8.1.1 transactionManager(事务管理器)
1. 配置事务管理器的类型
	例: <transactionManager type="JDBC"/>
    • 8.1.2 dataSource(数据源)
1. 标签属性:type 指定数据源类型
	UNPOOLED、POOLED、JNDI
	
2. 子标签:<property name="" value=""/>
	例: 使用${} 从数据库配置文件db.properties中读取 
	  <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>

9. databaseIdProvider(数据库厂商标识)

10. mappers(映射器)

<!-- 告知配置文件 从何处找到Mapper.xml的四种方法 -->

<!-- 使用相对于类路径的资源引用 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>

<!-- 使用完全限定资源定位符(URL) -->
<!--  不能使用这一种方式  -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>

<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>

<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

<!--
	最后两个方式需要注意以下两点:
	接口和他的Mapper配置文件必须同名!
	接口和他的Mapper配置文件必须在同一个包下!-->

四、Mapper.xml 映射文件(动态SQL)

Map传递参数,直接在sq|中取出key即可! [parameterType="map"]
对象传递参数,直接在sq|中取对象的属性即可! [parameterType-"Object"]
只有一个基本类型参数的情况下,可以直接在sq|中取到!
多个参数用Map, 或者注解!

1. SELECT 查询语句

1. select标签的属性
	id: 在命名空间中唯一的标识符,可以被用来引用这条语句。
	parameterType: 将会传入这条语句的参数的类全限定名或别名。
	resultType: 期望从这条语句中返回结果的类全限定名或别名。 
        注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 
	resultMap: 对外部 resultMap 的命名引用。
		结果映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂的映射问题都能迎刃而解。
		resultType 和 resultMap 之间只能同时使用一个。

2. 解决属性名个字段名不一致的问题(resultMap)

  • 解决方式
1. 解决方式一(不建议使用):
	修改SQL语句  为字段取别名: 	
		不一致的字段名 as 属性名
2. 解决方式二:
	在Mapper.xml文件中使用 结果集映射(resultMap):
  • 2. resultMap结果集映射
<!-- resu1tMap元素是MyBatis中最重要最强大的元素
	ResultMap的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂- -点的语句只需要描述它们的关系就行了。
	Resu1tMap最优秀的地方在于,虽然你已经对它相当了解了,但是根本就不需要显式地用到他们。-->

<resultMap id="为此映射所取得名称(供下方的结果集调用)" type="需要映射成的类型(实体类)">
    <result property="实体类属性名称" column="数据库中对应的字段名称"/>
</resultMap>

<select id="对应接口方法名" resultMap="对应上方resultMap标签的id值">
    <!--SQL语句-->
</select>

1. 判断 if

判断传递的参数是否有值
如果传入的参数不为空
String===>""、null 

2. 循环 foreach

<!--
           collection:指定要遍历的集合
           item:取出当前集合中元素,赋给 item 中的值
           separator:遍历出的多个元素之间用什么分隔符分隔开
           open:遍历集合前用什么字符进行拼接
           close:遍历集合后用什么字符进行拼接

           在 foreach 标签中还有一个属性 index,
           遍历集合的时候 index 表示的是当前元素的索引,item 对应索引中的值
           遍历 map 的时候 index 表示的是当前 map 中的 key,item 是 key 对应的 value
       -->
        <foreach collection="入参名称" item="别名" separator="," open="(" close=")">
            #{别名}
        </foreach>

五、 Mybatis 缓存

1. 一级缓存

1. sqlSession级别的,在sqlSession范围内的缓存.

2. 只在当前(同一个)的sqlSession中有效.

3. 默认开启,本身已经存在,可以直接使用.

4. 用处:  当参数和SQL 多次(2+)完全一致时,直接从缓存中获取第一次查询时所得的数据
		同一个SqlSession对象,在参数和SQL完全一致的情况, 默认使用一级缓存,将从缓存中获取数据
		
5. 注意: 当对数据库做了增删改时 会清空sqlSession级别的一级缓存
		任何的UPDATE, INSERT, DELETE 语句都会清空缓存

2. 二级缓存

1. Mapper映射级别的缓存,(相当于是sqlSessionFactory范围内的)
	pojo类需要实现序列化Serializable接口() 并生成serialVersionUID

2. 作用范围跨越SqlSession,即可以在多个SqlSession 之间共享二级缓存数据。

3. 只有在需要使用的时候开启,可以避免资源的过度消耗(需手动开启)
	
	<settings>
		<!-- 二级缓存总开关 位于核心配置文件mybatis-config.xml当中 -->
		<setting name="cacheEnabled" value="true"/>
	</settings>


	<!-- 二级缓存分开关 位于Mapper.xml中 -->
	<cache 
		eviction="FlFO" 
		flushInterval="60000"
		size="512" 
		readOnly="true"/>

eviction: 淘汰策略
FIFO:先进先出
flushInterval: 刷新时间(有效时间)
size: 缓存大小(个数) :不给定值时 默认为1024
readOnly:只读

待续 - - - !

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值