MyBatis 基本用法

1 MyBatis简介

1.1 什么是MyBatis

  • MyBatis 是一款优秀的持久层框架半自动ORM

  • 它支持自定义 SQL、存储过程以及高级映射,MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作,MyBatis 可以通过简单的 XML注解配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录

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

1.2 为什么要学MyBatis

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

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

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

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

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

  • 提供xml标签,支持编写动态sql

  • 跟JDBC相比使用方便,跟Hibernate相比首先是学习成本低(方法,缓存

2 MyBatis入门

2.1 MyBatis的开发步骤

MyBatis图标需要下载插件MyBatisX,lombok也需要下载插件(File --> Settings --> Plugins)

  • 搭建环境、导包

  • 编写MyBatis核心配置文件(configuration.xml)

  • 编写代码

  • 测试

2.2 搭建环境

新建module,导入maven

<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

<build>
    <!--
      资源插件 告诉maven把 src/main/java目录中的 指定扩展名的文件 拷贝到 target/classes目录中。
     -->
    <resources>
        <resource>
            <directory>src/main/java</directory><!--所在的目录-->
            <includes>
                <!--包括目录下的.properties,.xml 文件都会扫描到-->
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <!--  filtering 选项 false 不启用过滤器, *.property 已经起到过
                    滤的作用了 -->
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

2.3 编写核心配置文件(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>

    <!-- 读取db.properties文件的内容 -->
    <properties resource="db.properties">
        <!-- 如果properties中有跟name相同的属性,以文件为准 -->
        <property name="password" value="123456"/>
    </properties>

    <!-- 在控制台显示执行的sql语句 -->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <!-- 给参数设置别名,就不用写全量限定名称 -->
    <typeAliases>
        <package name="cn.blb.mybatis01.pojo"/>
    </typeAliases>

    <!-- 环境 可以多套 default 选择环境id-->
    <environments default="development">
        <environment id="development">
            <!-- 事务 - 默认JDBC -->
            <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>

    <!-- 映射,作用就是将接口跟实现类进行注册 -->
    <mappers>
        <mapper resource="cn/blb/demo02/mapper/mapper.xml"/>
    </mappers>
</configuration>

2.4 db.properties数据库连接文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///person?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=root

2.5 编写代码

  • 实体类
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Staff {
  private int id;
  private String name;
  private int age;
  private String address;
}
  • Dao接口
public interface StaffDao {

    // 查询所有
    List<Staff> selectAll();

    // 添加
    int insertStall(Staff staff);

    // 删除
    int deleteStall(int id);

    // 修改
    int updateStall(Staff staff);
}
  • 接口实现类
<?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">
<!-- namespace 相当于是实现interface,相当于implements -->
<mapper namespace="cn.blb.demo02.dao.StaffDao">

    <!--
        id = 实现的方法名
        resultType = 返回值类型
    -->
    <!--查询所有-->
    <select id="selectAll" resultType="cn.blb.demo02.pojo.Staff">
        select * from staff;
    </select>

    <!--添加-->
    <insert id="insertStall">
        insert into staff value(#{id},#{name},#{age},#{address})
    </insert>

    <!--删除-->
    <delete id="deleteStall">
        delete from staff where id = #{id}
    </delete>

    <!--修改-->
    <update id="updateStall">
        update staff set name = #{name},age = #{age},address = #{address} where id = #{id}
    </update>

</mapper>
  • 编写测试类
public class test01 {

    SqlSessionFactory sqlSessionFactory;

    @Before
    public void beforeTest() throws IOException {
        // 相对路径,相对的是resources下的资源
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void selectAll(){
        // sqlSerssion 相当于statement对象,用于操作数据库
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 获取mapper对象 接口的类型
        StaffDao staffDao = sqlSession.getMapper(StaffDao.class);
        List<Staff> list = staffDao.selectAll();
        list.forEach(System.out::println);
    }

    @Test
    public void insertStaff(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        StaffDao staffDao = sqlSession.getMapper(StaffDao.class);
        Staff staff = new Staff();
        staff.setName("路人甲");
        staff.setAge(28);
        staff.setAddress("南昌");
        int i = staffDao.insertStall(staff);

        // 手动提交事务 - 新增、删除。修改才需要
        sqlSession.commit();
        System.out.println("i = " + i);
    }

    @Test
    public void deleteStaff(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        StaffDao staffDao = sqlSession.getMapper(StaffDao.class);
        int i = staffDao.deleteStall(5);

        // 手动提交事务 - 新增、删除。修改才需要
        sqlSession.commit();
        System.out.println("i = " + i);
    }

    @Test
    public void updateStall(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        StaffDao staffDao = sqlSession.getMapper(StaffDao.class);
        Staff staff = new Staff();
        staff.setId(3);
        staff.setName("王五五");
        staff.setAge(25);
        staff.setAddress("北京");
        int i = staffDao.updateStall(staff);

        // 手动提交事务 - 新增、删除。修改才需要
        sqlSession.commit();
        System.out.println("i = " + i);
    }
}

3 配置解析

3.1 核心配置文件

MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:

configuration(配置)

  • properties(属性)

  • settings(设置)

  • typeAliases(类型别名)

  • typeHandlers(类型处理器)

  • objectFactory(对象工厂)

  • plugins(插件)

  • environments(环境配置)

    • environment(环境变量)

      • transactionManager(事务管理器)

      • dataSource(数据源)

  • databaseIdProvider(数据库厂商标识)

  • mappers(映射器)

3.2 环境配置 environments

MyBatis 可以配置成适应多种环境

不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境

注意一些关键点:

  • 默认使用的环境 ID(比如:default="development")

  • 每个 environment 元素定义的环境 ID(比如:id="development")

  • 事务管理器的配置(比如:type="JDBC")

  • 数据源的配置(比如:type="POOLED")

3.2.1 事务管理器(transactionManager)

在 MyBatis 中有两种类型的事务管理器(也就是 type="[JDBC|MANAGED]"):

  • JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。

  • MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。例如:

<transactionManager type="MANAGED">
    <property name="closeConnection" value="false"/>
</transactionManager>

3.2.2 属性 properties

我们可以通过properties属性来实现引用配置文件

这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。【db.properties】

  • 编写db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///staff?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=root
  • 在核心配置文件中引入

    <!--引用外部配置文件-->
    <properties resource="db.properties">
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </properties>

    • 可以直接引入外部文件

    • 可以在其中增加一些属性配置

    • 如果两个文件有同一个字段,优先使用外部配置文件的

3.3 映射器 mappers

MapperRegistry:注册绑定我们的Mapper文件;

<!-- 使用相对于类路径的资源引用 -->
<mappers>
    <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
    <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
    <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 
	使用映射器接口实现类的完全限定类名
    接口和他的Mapper配置文件必须同名
    接口和他的Mapper配置文件必须在同一个包下
-->
<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>

3.4 类型别名 typeAliases

  • 类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置

  • 意在降低冗余的全限定类名书写

<!--可以给实体类起别名-->
<typeAliases>
    <typeAlias type="cn.blb.pojo.User" alias="person"/>
</typeAliases>
  • 也可以指定一个包,每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author,;若有注解,则别名为其注解值。见下面的例子:
<typeAliases>
    <package name="cn.blb.pojo"/>
</typeAliases>
@Alias("author")
public class Author {
    ...
}

3.5 设置 Settings

设置名描述有效值默认值
cacheEnabled

全局性地开启或关闭所有映射器配置文件中已配置的任何缓存

true~false

true
lazyLoadingEnabled延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态true~falsefalse
mapUnderscoreToCamelCase是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumntrue~falsefalse

一个配置完整的 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>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值