MyBatis学习与问题总结

MyBatis

为什么要学习MyBatis?

首先了解JDBC:
JDBC是Java程序实现访问数据库的基础,提供了一套数据库操作API
JDBC实现数据库操作得步骤:

  1. 加载驱动
  2. 获取连接
  3. 获取连接、执行者对象等
  4. 发送SQL语句等

操作比较繁琐,并且有一定局限性。劣势主要有:

  • 频繁的创建、释放数据库连接会造成系统资源的浪费,影响系统性能
  • 代码中的语句硬编码,会造成代码不易于维护,频繁修改SQL,违反开闭原则
  • 使用PreparedStatment向占位符传参数存在硬编码,因为SQL where条件不确定,也许有修改需求,不易维护
  • JDBC对结果及解析存在硬编码(查询列名),SQL变化导致解析代码变化,不易维护

解决方案:使用ORM框架完成数据库的编程操作。常用的ORM框架MyBatis,Hibernate。

MyBatis:支持普通SQL查询、存储及高级映射的持久层框架,几乎消除了JDBC冗余代码,无需手动设置参数和对结果集进行检索,使用简单的XML或注解进行配置和原始映射,将接口和Java的POJO映射成数据库中的记录,使工作人员可以使用面向对象的编程思想来操作数据库。

ORM框架:为了解决面向对象与关系型数据库中数据类型不匹配的技术,通过描述Java对象与数据库表之间的映射关系,自动将Java应用程序对象持久化到关系型数据库对应表中。

ORM框架工作原理
开发者只需关注SQL本身,不需要花精力 注册驱动、创建Connection对象、创建Statement对象、手动设置参数结果集检索等JDBC繁杂的过程代码。

MyBatis环境搭建以及测试

1. 创建Maven工程(IDEA)

2. 引入相关依赖(pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>mybatis-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <dependencies>
        <!--   Alt + Inster dependecy Serach查询依赖,也可以上Maven中央仓库找     -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.11</version>
        </dependency>
        
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>

    </dependencies>
    
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
</project>

4. 创建数据库连接配置(需在 src/main/resources 目录下创建db.properties)

mysql.driver=com.mysql.cj.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&\
            characterEncoding=utf8&useUnicode=true&useSSL=false
mysql.username=root
mysql.password=123456

5. 创建MyBatis核心配置文件(需在 src/main/resources 目录下创建mybatis-config.xml,可根据情况命名)

<?xml version="1.0" encoding="UTF-8" ?>
<!--上面的必须要写在第一行,否则报错-->
<!--创建MyBatis的核心配置文件-->
 <!--注意路径 config-->
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--配置连接数据库的环境-->
    <!--  加载类路径下的属性文件  -->
    <properties resource="db.properties"/>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!--      数据库连接相关配置,db.properties文件中的内容      -->
            <dataSource type="POOLED">
<!--                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>-->
<!--                <property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC"/>-->
<!--                <property name="username" value="root"/>-->
<!--                <property name="password" value="123456"/>-->
                <property name="driver" value="${mysql.driver}"/>
                <property name="url" value="${mysql.url}"/>
                <property name="username" value="${mysql.username}"/>
                <property name="password" value="${mysql.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--引入mybatis的映射文件-->
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>

</configuration>

6. 创建表(数据准备)

7. 创建POJO实体

8. 创建映射文件POJOMapper.xml(POJO对应的实体bean名称)

src/main/resources 文件下创建mapper文件夹,SQL语句与Java对象的关系映射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指定Dao接口完整类名
mybatis会根据这个接口动态创建一个实现类去实现这个接口,
而这个实现类是mapper的对象
-->
<mapper namespace="org.chiyu.pojo.User">
    <!--
    id = "接口中的方法名"
    parameterType = "传入参数类型"
    resultType="返回的实体对象,使用包.类名">
     -->
    <select id="findById" parameterType="Integer"
            resultType="org.chiyu.pojo.User">
        SELECT *
        FROM users
        where uid = #{id}
    </select>
</mapper>

9.修改mybatis.config.xml配置文件射文件的路径加载到程序中)

添加映射文件路径配置,将映射文件的路径加载到程序中

<mappers>
    <mapper resource="mapper/UserMapper.xml"/>
</mappers>

10. 编写测试类

public class UserTest {

    @Test
    public void userFindByIdTest(){
        String resources = "mybatis-config.xml";
        //创建字符流
        Reader reader = null;

        try {
            //读取mybatis-config.xml文件内容到reader对象中
            reader = Resources.getResourceAsReader(resources);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //初始化MyBatis数据库,创建SqlSessionFactory类的实例
        SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);
        //创建SqlSession实例
        SqlSession session = sqlMapper.openSession();
        //传入参数查询,返回结果
        User user = session.selectOne("findById",1);
        //输出结果
        System.out.print(user.getUname());
        //关闭session
        session.close();

    }
}

后续改动

public class MyBatisUtils {

    private static SqlSessionFactory sqlSessionFactory = null;

    //初始化SqlSessionFactory对象,静态代码块
    //todo resource mybatis-config.xml配置文件信息  是否可以使用动态配置
    static {
        try {
            //使用MyBatis提供的Resources的类加载MyBatis的配置文件
            Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
            //构建SqlSessionFactory工厂
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获取SqlSession对象的静态方法
    public static SqlSession getSession() {
        return sqlSessionFactory.openSession();
    }

10. MyBatis工作原理

MyBatis工作原理

(1) mybatis-config.xml 主要配置mybatis运行时环境
(2)mapper.xml SQL映射文件,配置SQL语句,需要再mybatis-config.xml配置才能执行;mybatis-conifg.xml可以配置多个映射文件,每个映射文件对应数据库的一张表
(3)通过MyBatis的环境等配置信息构建会化工厂SqlSessionFactory,用于创建SqlSession
(4)创建会话对象:SqlSessionFactory创建SqlSession对象,该对象包含了执行SQL语句的所有方法
(5)创建执行器:会话本身不能直接操作数据库,MyBatis底层定义一个Executor接口用于操作数据库,执行器会根据SqlSession传递的藏书动态生成需要执行的SQL语句,同时负责查询缓存地维护
(6)封装SQL信息:SqlSession内部通过执行器Executor操作数据库,执行器将待处理的SQL信息封装到MapperStatement对象中,MappedStatement对象中存储了要映射的SQL语句的id、参数等。Mapper.xml文件中一个SQL语句对应一个MapperedStatement对象,SQL语句的id即是MappedStatementid。Executor执行器会在执行SQL语句之前,通过MappedStatement将输入的参数映射到SQL语句中。
(7)操作数据库:根据动态生成的SQL操作数据库
(8)输出结果映射集:执行SQL语句之后,通过MappedStatement对象将输出结果映射至Java对象中。

mybatis核心配置

1. 三个核心对象

SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession

MyBatis以SqlSessionFactoryBuilder为中心
SqlSessionFactoryBuilder是SqlSessionFactory的构造者,通过重载的builder()方法构建SqlSessionFactory对象

1.1 SqlSessionFactoryBuilder

形式一:

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties)

InputStream字节流封装了XML文件形式的配置信息;参数environment和properties是可选参数
environment:用于指定要加载的环境,包括数据源和事务管理器
properties:用于指定要加载的properties文件

形式二:

public SqlSessionFactory build(Reader reader, String environment, Properties properties)

与上一种方法形式基本相同,区别是该方法使用了Reader字符流封装了XML配置文件信息

形式三:

public SqlSessionFactory build(Configuration config)

Configuration对象用于封装MyBatis项目中的配置信息

通过读取XML配置文件里的的方式来构建SqlSessionFactory对象

 //读取配置配置文件,创建字节流
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//根据配置文件构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
1.2 SqlSessionFactory

用于创建SqlSession
是MyBaits的中心
在SqlSessionFactoryBuilder创建完SqlSessionFactory 对象后,SqlSessionFactory 就可以调用opeanSession()对象

方法描述
SqlSession openSession();开启一个事务,连接对象从活动环境配置的数据源对象中得到,事务隔离界别将会使用驱动或数据源的默认设置,预处理语句不会复用,也不会批量处理更新
SqlSession openSession(boolean autoCommit);autoCommit设置是否开启事务,true表示关闭事务控制(默认,自动提交);false开启事务控制
SqlSession openSession(Connection connection);connection可以提供自定义连接
SqlSession openSession(TransactionIsolationLevel level);level设置隔离级别
SqlSession openSession(ExecutorType execType);execType为执行器的类型,3个可选类型:ExecutorType .SIMPLE表示每条语句创建一条新的预处理语句;ExecutorType.REUSE表示会复用预处理语句;ExecutorType .BATCH
SqlSession openSession(ExecutorType execType, boolean autoCommit);ExecutorType 执行器类型;autoCommit是否开启事务
SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);ExecutorType 执行器类型;level设置隔离级别
SqlSession openSession(ExecutorType execType, Connection connection);ExecutorType 执行器类型;connection可以提供自定义连接
1.3 SqlSession

是应用程序与持久层之间执行交互操作的对象,主要作用是执行持久化操作,类似于JDBC中Connection。SqlSession对象包含了执行SQL操作的方法,由于其底层封装了JDBC连接,所以可以使用SqlSession对象来执行已映射的SQL语句。

方法描述
T selectOne(String statement);查询方法,参数statement是在配置文件中定义的元素的id,该方法会返回SQL语句查询结果的一个泛型对象
T selectOne(String statement, Object parameter);parameter是查询语句所需的参数。该方法会返回SQL语句查询结果的一个泛型对象
List selectList(String statement);该方法会返回SQL语句查询结果的一个泛型集合
List selectList(String statement, Object parameter);
List selectList(String statement, Object parameter, RowBounds rowBounds);RowBounds 用于分页的参数对象。
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);
Cursor selectCursor(String statement);
Cursor selectCursor(String statement, Object parameter);
Cursor selectCursor(String statement, Object parameter, RowBounds rowBounds);
void select(String statement, Object parameter, ResultHandler handler);插入方法,该方法返回执行SQL语句所影响的行数
void select(String statement, ResultHandler handler);
void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);
int insert(String statement);插入方法
int insert(String statement, Object parameter);
int update(String statement);更新方法
int update(String statement, Object parameter);
int delete(String statement);删除方法
int delete(String statement, Object parameter);
void commit();提交事务方法
void commit(boolean force);
void rollback();回滚事务方法
void rollback(boolean force);
List flushStatements();
void close();
void clearCache();
Configuration getConfiguration();
T getMapper(Class type);会返回Mapper接口的代理对象,该对象关联了SqlSession对象,可以使用该对象直接调用相应方法操作数据库;type是Mapper接口的类型。官方推荐通过Mapper对象访问MyBatis
Connection getConnection();获取JDBC数据连接对象的方法

2. MyBatis核心配置文件

主要配置了MyBatis的一些全局信息
数据库连接信息、MyBatis运行时所需的特性,以及设置和影响MyBatis行为的一些属性。
配置文件编写后也不会轻易改动

2.1 配置文件的主要元素

MyBatis核心配置元素
MyBatis核心配置元素子元素,的子元素必须按照由上到下顺序配置,否则MyBatis在解析XML配置文件的时候会报错。

2.2 < proprties >

配置属性元素,读取外部文件的配置信息

如db.properties,配置了MyBatis的数据库连接配置

mysql.driver=com.mysql.cj.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&\
            characterEncoding=utf8&useUnicode=true&useSSL=false
mysql.username=root
mysql.password=123456

读取外部配置信息

<properties resource="db.properties"/>

引入db.properties文件后,如果希望动态获取db.properties文件中的数据库链接信息,可以使用< property>元素配置,属性值根据db.properties中数据的配置动态改变

<dataSource type="POOLED">
    <property name="driver" value="${mysql.driver}"/>
    <property name="url" value="${mysql.url}"/>
    <property name="username" value="${mysql.username}"/>
    <property name="password" value="${mysql.password}"/>
</dataSource>
2.3 < settings>

用于改变MyBatis运行时的行为,如何开启二级缓存、开启延时加载等。

配置参数描述有效值默认值
2.4 < typeAliases>

为POJO起简短的别名,防止容易出现拼写上的错误(觉得用处不大)

2.5 < environments>
  • MyBatis可以配置多套的配置环境,如开发环境、测试环境、生产环境等,可以灵活,从而将SQL映射到不同运行环境的数据库中。该标签来配置不同的运行环境,但不论增加了几套运行环境,都必须要明确选择当前要用的唯一的一个运行环境。
  • MyBatis运行环境信息包括事务管理器和数据源。
  • 子标签:
    < teansactionManager>用于配置运行环境的事务管理器,type = “”:
    JDBC:此配置直接使用JDBC的提交和回滚,它依赖于从数据源得到的连接来管理事务的作用域
    MANAGED:此配置不提交或回滚一个连接,而是让容器来管理事务的整个声明周期。默认情况下,它会关闭连接,但有些容器并不希望这样,为此可以将< transactionManager>元素的closeConnection属性设置为false来阻止它默认的关闭行为。
    < dataSource>用于配置运行环境的数据原信息

如果Spring+MyBatis的项目,则没有必要再MyBatis中配置事务管理器,因为实际开发中项目会使用Spring自带的管理器来实现事务管理。


对于数据源的配置,MyBatis提供了UNPLLDED、POOLED和JNDI 3种数据源类型:

  1. UNPOOLED
    表示书院为无连接池类型。配置此数据源类型后,程序在每次被请求时会打开和关闭数据库连接。适用于对于性能不高的简单应用程序
    需要配置的5种属性
属性说明
driverJDBC驱动的Java类的完全限定名(并不是JDBC驱动中可能包含的数据源类)
url数据库的URL地址
username登录数据库的用户名
password登录数据库的密码
defaultTransactionIsolationLevel默认的连接事务隔离级别
  1. POOLED(合并的)
    表示数据源为连接池类型。POOLED数据源利用“池”的概念将JDBC连接对象组织起来,节省了创建新的链接对象时需要初始化和认证的时间。POOLED使并发Web应用可以快速响应请求,是当前比较流行的数据源配置类型。
    POOLED出了UNPOOLED的5种属性外,还可以配置更多属性
属性说明
poolMaximumActiveConnections在任意时间可以存在的活动(也就是正在使用)连接数量,默认是10
poolMaxinumdleConnections任意时间可能存在的空闲连接数
poolMaximumCheckoutTime在被强制返回前,池中连接被检测出(check out)时间,默认值为20000毫秒,即20秒
poolTimeToWait如果获取连接花费时间较长,它会给连接池打印状态日志并重新尝试获取一个连接(避免在错误配置的情况下一直处于无提示的失败),默认值为20000毫秒,即20秒
poolPingQuery发送到数据库的侦测查询,用于检测连接是否处于正常工作秩序中,默认值是“NO PING QUERY SET”
poolPingEnabled是否启用侦测查询,若开启,则必须使用一个可执行的SQL语句(最好是一个非常快的SQL)设置poolPingEnabled 属性,默认值为false
poolPingCommectionsNotUsedFor配置poolPingQuery的使用频度,该属性的值可以被设置成匹配具体的数据库连接超时时间,从而避免不必要的侦测,默认值为0(表示所有连接每一时刻都被侦测),只有poolPingEnable的属性值为true时适用
  1. JNDI
  • 代办
2.6 < mappers>

MyBatis核心配置文件中,该元素用于引入MyBatis映射文件。映射文件包括POJO对象和数据表之间的映射信息,MyBatis核心配置文件找到映射文件并解析映射信息。

引入映射文件4种方式:

  • 类路径引入
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
  • 本地文件路径引入
    <mappers>
        <mapper url="file:///D:/PersonalFiles/Learn/AboutJava/Base/mybatis-test/src/main/resources/mapper/UserMapper.xml"/>
    </mappers>
  • 接口引入
  • 包名引入

3. MyBatis映射文件

MyBatis专注于SQL语句
常用元素:

元素说明
mapper映射文件根元素,<>只有namespace(命名空间)属性:区分不同的mapper,全局唯一;绑定DAO接口,即面向接口编程。当namespace绑定某一接口的实现类,MyBatis会通过接口的全限定类名查找到对应的mapper配置来执行SQL语句,因此namespace的命名必须跟接口同名
cache配置给定命名空间的缓存
cache-ref从其他命名空间引用缓存配置
select用于映射查询语句
insert用于映射插入语句
update
delete
sql可以重用的SQL块,也可以被其他语句使用
resultMap描述数据库结果集和对象的对应关系,告诉表字段对应对象的哪个属性(column —property)
3.1 select
  • 补充元素属性
3.2 insert
  • 补充元素属性
3.3 update
  • 补充元素属性
3.4 delete
3.5sql
3.6 resultMap
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值