MyBatis入门

1.什么是MyBatis

MyBatis 是一个支持普通SQL查询、存储过程以及高级映射的持久层框架,它消除了几乎所有的JDBC 代码和参数的手动设置以及对结果集的检索,并使用简单的XML 或注解进行配置和原始映射,用以将接口和Java的POJO(Plain Old Java Object,普通Java 对象)映射成数据库中的记录,使得Java开发人员可以使用面向对象的编程思想来操作数据库。

归纳总结一下

  • MyBatis是一个持久层框架
  • 支持普通SQL查询,存储过程,还有ORM
    • ORM=>app不用再直接访问数据库,而是以面向对象的方式来操作持久化对象PO(Persisten Object),ORM框架会通过映射关系将这些操作转化为SQL操作
    • 支持普通SQL查询=>可以优化SQL
    • 支持存储过程=>同样可以优化SQL性能
  • 消除了繁琐的JDBC操作和配置

2.怎么使用MyBatis

  1. 在pom.xml引入mybatis依赖
  2. (在mysql建个表,插入些数据,等等用)
    CREATE TABLE users(
    	id int(32) PRIMARY KEY AUTO_INCREMENT,
    	username varchar(50),
    	job varchar(50),
    	phone varchar(16)
    );
    
    INSERT INTO users VALUES(1,'f','b','110');
    INSERT INTO users VALUES(2,'fo','ba',120);
    INSERT INTO users VALUES(3,'foo','bar',119);
    
  3. 在classpath下配置log4j.properties配置文件<=MyBatis使用log4j输出日志信息
    # Global logging configuration  
    log4j.rootLogger=ERROR, stdout
    # MyBatis logging configuration
    log4j.logger.com.ssm=DEBUG
    Console output...
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
    
  4. 写个持久化类/POJO(属性字段与数据库中的表字段对应)
  5. 创建UserMapper映射文件
<?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="tech.rpish.mapper.UserMapper">  
    <select id="findUserById" parameterType="Integer" resultType="tech.rpish.po.User">  
 select * from users where id=#{id} </select>  
</mapper>
  1. 创建MyBatis核心配置文件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>  
    <environments default="mysql">  
        <environment id="mysql">  
            <transactionManager type="JDBC"></transactionManager>  
            <dataSource type="POOLED">  
                <property name="driver" value="com.mysql.jdbc.Driver" />  
                <property name="url" value="jdbc:mysql://localhost:3306/spring_db" />  
                <property name="username" value="root" />  
                <property name="password" value="pass" />  
            </dataSource>  
        </environment>  
    </environments>  
    <mappers>  
        <mapper resource="tech.rpish.mapper.UserMapper.xml"/>  
    </mappers>  
</configuration>
  1. 编写测试类
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 org.junit.Test;  
import tech.rpish.po.User;  
  
import java.io.InputStream;  
  
public class MyBatisTest {  
    @Test  
 public void findUserByIdTest() throws Exception {  
// 读配置文件  
 String resource = "mybatis-config.xml";  
        InputStream inputStream = Resources.getResourceAsStream(resource);  
// 根据配置文件构建SqlSessionFactory Instance  
 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  
// 公共SqlSessionFactory创建SqlSession Instance  
 SqlSession sqlSession = sqlSessionFactory.openSession();  
//        sqlSession执行映射文件中定义的sql,并返回结果  
 User user = sqlSession.selectOne("tech.rpish.mapper.UserMapper.findUserById", 1);  
// 输出结果  
 System.out.println(user);  
// 关闭sqlSession  
 sqlSession.close();  
    }  
}

调试运行,就能查询到结果了.

  1. 注意目录结构
    这边需要注意的是目录结构
    在IDEA中,UserMapper.xml必须放到resources目录下,否则无法加载资源
    我尝试按照网上的教程修改pom.xml,手动添加build资源和很多其他方法都无济于事
    所以这边特地指出来,给大家避个坑
    MyBatis入门

然后记得要修改mybatis配置文件中mapper的资源路径
MyBatis入门

Okay,这就是大致的一个过程,然后上面这是findUserById的Demo,那大家可以仿照着写下findAllUsers,addUser,deleteUser,updateUser
(只要修改mapper.xml,然后写测试类就可以了)
然后,如果遇到卡壳,可以参考下我发到github的demo

3.MyBatis核心配置

3.1 MyBatis核心对象

  • SqlSessionFactory
    • SqlSessionFactory是单个数据库映射关系经过编译后的内存镜像,用于创建 SqlSession.
    • SqlSessionFactory对象的实例通过 SqlSessionFactoryBuilder 对象来构建,通过 XML配置文件或一个预先定义好的Configuration 实例构建出 SqlSessionFactory 的实例
    • 通过 XML 配置文件构建出SqlSessionFactory demo
    InputStream inputStream = Resources.getResourceAsStream("ConfigurationFile");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream)
    
    • SqlSessionFactory 对象是线程安全的,一旦被创建,在整个应用执行期间都会存在
    • 如果多次创建同一个数据库的SqlSessionFactory,那么此数据库的资源将很容易被耗尽=>在构建SqlsessionFactory 实例时,建议使用单例模式
  • SqlSession
    • SqlSession 是应用程序与持久层之间执行交互操作的一个单线程对象,其主要作用是执行持久化操作
    • SqiSession对象包含数据库中所有执行SQL操作的方法,底层封装了JDBC连接,所以可以直接使用其实例来执行已映射的SQL语句
    • SqlSession实例是不能被共享的,也是线程不安全的,因此其使用范围最好限定在一次请求或一个方法中,绝不能将其放在一个类的静态字段、实例字段或任何类型的管理范围中使用=>使用完SqlSession对象之后,要及时将它关闭,通常可以将其放在finally块中关闭
    • 常用方法:

3.2 MyBatis配置文件

  • 配置文件-结构
<configuration xmlns="http://mybatis.org/schema/mybatis-config">  
<!-- 属性-->  
 <properties></properties>  
<!-- 设置-->  
 <settings></settings>  
<!-- 类型命名-->  
 <typeAliases></typeAliases>  
<!-- 类型处理器-->  
 <typeHandlers></typeHandlers>  
<!-- 对象工厂-->  
 <objectFactory type=""></objectFactory>  
<!-- 插件-->  
 <plugins></plugins>  
<!-- 配置环境(事务管理器,数据源)-->  
 <environments default="">  
        <environment id="">  
            <transactionManager type=""></transactionManager>  
            <dataSource type=""></dataSource>  
        </environment>  
    </environments>  
<!-- 数据库厂商标识符-->  
 <databaseIdProvider type=""></databaseIdProvider>  
<!-- 映射器-->  
 <mappers></mappers>  
</configuration>
  • 配置文件-主要元素
    • <properties>:通过外部配置资源,动态替换内部定义的属性
    • <settings>:改变mybatis运行时的行为(开启cache,lazyloading)
    • <typeAliases>:为配置文件中的po类型设置一个别名=>可开启自动扫包,会自动给它们定义别名(首字母小写的非限定类名)
    • <typeHandler>:对mybatis的prepared statement的参数和结果集进行java type和jdbc type之间的转换
    • <objectFactory>:实例化目标类,通常用来实例化mybatis的结果对象
    • <plugins>:配置用户所开发的插件=>在已映射语句执行过程中的某一点进行拦截调用
    • <environments>:配置环境=>主要是数据源和事务管理器
    • <mappers>:指定mybatis配置文件位置
      • 类路径<mapper resource="tech/rpish/mapper/Mapper.xml" />
      • 本地文件路径<mapper url=file:///C:/SSM-bootstrap/mapper/Mapper.xml />
      • 接口类<mapper class="tech.rpish.mapper.Mapper" />
      • 包名<package name"tech.rpish.mapper" />

3.3 MyBatis Mapper配置

  • <select>
  • <insert>
  • <update>
  • <delete>
  • <sql>:sql代码片段,可在其他语句include复用
  • <resultMap>:结果映射集,定义映射规则,级联更新,类型转化器

4.动态SQL

mybatis的动态sql就是对sql语句动态组装的功能.
通过使用OGNL Expression+tags 对sql语句进行逻辑判断,代替开发人员手动拼接sql语句.
大致有如下几类:

  • <if>:单条件分支判断
  • <chose>(<when>,<otherwise>):多条件分支判断
  • <where>,<trim>:辅助元素,用于处理sql拼装,特殊字符处理
  • <set>:和if配合,实现对一个对象特定字段的更新,代替update对所有字段的更新
  • <foreach>:循环语句,常和in联用
  • <bind>:从OGNL express创建一个变量,绑定到上下文(常用于模糊查询的sql中)=>不考虑数据库进行字符串拼接

具体demo,详见:Commit:MyBatis-2 动态SQL · rpishgithub/SSM-bootstrap@d314427

4.关联映射

我们常用的查询不可能总像getUsernameById这么简单,时常要处理复杂类型和多张表多个对象间的复杂的关系.
这时候就要用到mybatis的关联映射来处理对象间的一对一,一对多,多对多关联关系了.

mybatis有两种加载关联关系的方式:

  • 嵌套查询:在查询的resultMap中嵌套一个子查询
  • 嵌套结果:在查询的resultMap中对子集进行解析

一对一关系通常在resultMap中添加association嵌套查询嵌套结果

一对多和多对多则是利用resultMap中的collection,它的大部分属性association相同,不同的是它的ofType属性,它与javaType属性对应,用于指定实体对象中集合类属性所包含的元素类型.
具体使用,详见:

然后提一下注意事项

  • 写完mapper记得在mybatis配置文件中注册mapper
  • 记得检查mapper的拼写

6.mybatis和spring的整合

  1. 传统DAO方式
    1. 通过 DAO实现类 实现对应DAO接口定义的方法,同时extend SqlSessionDaoSupport,通过getSqlSession()方法获取spring注入的sqlSessionFactory获取session,调用mapper定义的查询 (详见SSM-bootstrap/MyBatis-04)
    2. 缺点:实现类会出现大量重复代码;需要指定映射文件中执行语句的id(运行才能知道正确性)
  2. Mapper接口方式
    1. 基于mapperFactoryBean的整合
      1. 编辑mapper.xmlnamespace同名的mapper接口,声明一方法与查询名参数返回类型对应
      2. 在spring配置文件创建mapperFactoryBean类型的bean/mapper代理(注入上述mapper interface 和 sqlSessionFactory)
      3. 编写测试类,通过Mapper取代Dao接口实例调用查询方法
    2. 基于mapperScannerConfiguration的整合
      1. 像上面这样每个mapper都要写个bean注册还是很麻烦,特别是Dao层有很多接口时,这时候就得用MapperScannerConfigurer类,来自动扫描接口,为它们创建对应mapper的bean
      2. 只需要在spring配置文件中配置mapperScannerConfigurer bean,再指定basePackage (详见:SSM-bootstrap/MyBatis-04)

7.更多内容

这上边只是我看书上讲mybatis做的笔记,更多具体内容还得看官方文档.
mybatis – MyBatis 3 | 简介
然后,肯定会接触到一些sql语句,这部分可以看菜鸟教程
MySQL 教程 | 菜鸟教程 (runoob.com)

上一篇:mybatis的配置步骤


下一篇:10.29第一个Mybatis程序