Mybatis框架详解1

什么是Mybatis

Mybatis是有个持久层的ORM框架,简化了JDBC的操作,让我们只专注与sql语句的拼装,其他复杂的过程交给Mybatis去完成。Mybatis是apache一个开源的项目ibatis,2010年迁移到了Google code上,2013年11月迁移到Git Hub上。
Mybatis框架在市面上应用广泛,他像其他的框架一样,都有一个核心的配置文件,还有每个接口的sql关系映射文件,通过new SqlSessionFactoryBuilder().builder(Resources.getResourceAsStream(“mybatis-config.xml”)),生成SqlSessionFactory对象,进而生成SqlSession对象,提供了很多的API供我们使用与数据库进行CRUD的操作,深度研究,其实SqlSession只是一个接口规范,真正干活的是通过一个Execute执行器生成了自己的MappedStatement对象,进行输入输出映射。

  • Mybatis框架的架构图
    在这里插入图片描述

  • JDBC存在的问题

    • 频繁的创建打开和关闭连接,消耗资源
    • sql语句硬编码,不利于维护
    • sql参数设置硬编码,不利于维护
    • 执行完之后的结果获取和遍历比较复杂,存在硬编码,不利于维护,期望是返回一个封装好的java对象。

Mybatis的入门案例(原始Dao层开发)

第一步:导入相关jar包(Mybatis本身jar包和数据库连接jar包)
在这里插入图片描述
第二步:配置核心配置文件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>
    <!-- 加载规则:首先加载标签内部属性,再加载外部文件,名称相同时,会替换相同名称的内容 -->
    <properties resource="jdbc.properties">
        <property name="jdbc.username" value="root11"></property>
    </properties>
    <!--别名配置-->
    <typeAliases>
        <!--单个别名设置-->
        <typeAlias alias="user" type="com.pojo.User" />
        <!--自动的别名设置:扫描包下面的所有的类,设置的别名为类名,不区分大小写-->
        <package name="com" />
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <!--事物管理:使用JDBC的提交和回滚设置,依赖于从数据源的到的连接来管理事物-->
            <transactionManager type="JDBC" />
            <!-- 配置数据库连接信息 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverClass}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
        </environment>
    </environments>

    <!--导入sql映射配置文件-->
    <mappers>
        <!-- 引入sql映射文件userMapper.xml文件,
        userMapper.xml位于com这个包下,所以resource写成com/userMapper.xml-->
        <mapper resource="com/dao/UserDao.xml"/>
        <!--class扫描器的要求:
            1.sql映射文件必须和接口在同一个目录下
            2.映射文件的名字要和接口名一样
        -->
        <mapper class="com.mappers.UserMappers"></mapper>
        <!-- 第三种方式,包扫描器要求(推荐使用此方式):
			 1、映射文件与接口同一目录下
			 2、映射文件名必需与接口文件名称一致
		-->
        <package name="com.mappers"/>
    </mappers>

</configuration>

第三步:配置sql关系映射配置文件

<?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">
<!--使用的dtd约束,标签必须严格按照顺序-->
<!--
    namespace:命名空间,相当于包名,用来区分sql ID
    #{ } : 相当于sql语句中的占位符 ?
-->
<mapper namespace="user">
    <!--
        parameterType:传入参数的类型
        resultType:执行完sql之后返回的查询结果
        #{ }中的参数随便写
        mybatis只能传一个参数,那当传多个参数的时候怎么办呢?,将不在一个对象的两个参数放在一个对象中,使用#{0},#{1}
                索引的方式,或者对象中有该属性的get方法,但是前提属性名和 #{名字} 要一致才可以。
        ${ }:标识符,用于字符串的拼装,当parameterType是基本类型的时候,${value},只能写value,当时其他的引用类型,可以随便写,前提是传递单个参数。
        当传递多个参数时候,就不能随便写了,下篇博客会具体讲解。
        例如:select * from user where username like '%${value}%'
    -->
    <select id="findUserById" parameterType="int" resultType="com.pojo.User">
        select * from user where id = #{ida}
    </select>

    <!--resultType:返回的是集合的时候,返回的类型写集合中保存元素的类型-->
    <select id="findUserByAll" resultType="com.pojo.User">
        select * from user
    </select>

    <!--使用User类中的get方法获取参数的值-->
    <!--
        userGnerateKeys:使用生成的key,默认false,标识插入使用自增id,将id绑定在keyProperty属性上,配套使用
        只是简化了写selectKey属性的步骤,底层还是调用了 LAST_INSERT_ID()函数
    -->
    <insert id="insertUser" parameterType="com.pojo.User" useGeneratedKeys="true" keyProperty="id">
       <!-- <selectKey keyProperty="id" resultType="int" order="AFTER">
            SELECT LAST_INSERT_ID()
        </selectKey>-->
        INSERT INTO `user` (
          `username`,
          `birthday`,
          `sex`,
          `address`
        )
        VALUES
          (
            #{username},
            #{birthday},
            #{sex},
            #{address}
          )

    </insert>

    <!---->
    <delete id="deleteUser" parameterType="int">

        DELETE  FROM `user`  WHERE `id` = #{id}

    </delete>

    <update id="updateUser" parameterType="com.pojo.User" >
      <!--<selectKey keyProperty="uuid" resultType="string" order="AFTER">-->
          <!--SELECT UUID()-->
       <!--</selectKey>-->
        update user set `username` = #{username} where id = #{id}
    </update>

</mapper>

第四步:配置日志文件log4j.properties和jdbc.properties属性文件
log4j.properties

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# 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

jdbc.properties

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456

第五步:编写测试类
抽取工具类SqlSessionFactoryUtils.java

package com.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;


public class SqlSessionFactoryUtils {
    //相当于连接池,一个工程只能有一个,为什么不是SqlSession对象呢?因为官网说了,SqlSession对象非线程安全的,
    //必须保证一个线程有一份SqlSession
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            //使用mybatis提供的Resource加载配置文件
            InputStream inputStream = null;
            inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            //根据配置文件生成SqlSessionFactory对象
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSessionFactory getSqlSessionFactory(){
        return sqlSessionFactory;
    }

}

实现类,dao层

public class UserDaoImpl implements UserDao {
    @Override
    public User findUserById(int id) throws IOException {

//        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //自己抽取工具类,实现一个工程只有一个工厂
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();

        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = sqlSession.selectOne("findUserById",1);

        sqlSession.close();
        return user;
    }

    @Override
    public List<User> findUserByAll() throws IOException {
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();

        List<User> list = sqlSession.selectList("findUserByAll");
        return list;
    }

    @Override
    public void insertUser() throws IOException {
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();

        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = new User();
        user.setUsername("侯征明3");
        user.setSex("1");
        user.setBirthday(new Date());
        user.setAddress("ads");
        sqlSession.insert("insertUser", user);
        System.out.println(user);

        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public void deleteUser(int id) throws IOException {
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.delete("deleteUser",id);
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public void updateUser(int id) throws IOException {
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = new User();
        user.setUsername("王然1");
        user.setId(id);
        sqlSession.update("updateUser", user);

        System.out.println(user);
        sqlSession.commit();
        sqlSession.close();
    }
}

Mybatis框架Dao层开发使用接口动态代理

就是之前dao层自己写接口和实现类,现在是只写接口,实现类动态代理得到。

  • dao层动态代理的sql映射文件的写法规则
    • namespace必须是接口的全路径名称
    • 接口的方法名必须和配置文件中的 SQL ID相同
    • 接口的方法的参数类型必须和配置文件中的parameterType属性值相同
    • 接口的方法返回值必须和配置文件中的resultType属性值相同

Mybatis配置文件详解

配置文件使用的是dtd约束,所以标签的写法一定按顺序写,否则报错。
在这里插入图片描述

  • properties标签
<!-- 引入外部的jdbc.properties属性文件,相对路径是src目录下
加载规则:首先加载标签内部属性,再加载外部文件,名称相同时,会替换相同名称的内容 
-->
    <properties resource="jdbc.properties">
        <property name="jdbc.username" value="root11"></property>
    </properties>
  • typeAliases标签
    设置完别名之后,以后在sql映射文件中用到的话直接写别名就可以,比如parameterType、resultType等。
<!--别名配置-->
    <typeAliases>
        <!--单个别名设置-->
        <typeAlias alias="user" type="com.pojo.User" />
        <!--自动的别名设置:扫描包下面的所有的类,设置的别名为类名,不区分大小写-->
        <package name="com" />
    </typeAliases>

注解别名设置
@Alias(“user”)
public class student{}
注意:注解别名会覆盖配置文件中的typeAliases配置。
除了自己定义别名外,Mybatis框架对java的基本类型及其他的特殊类型也做了别名映射关系。
在这里插入图片描述

  • mappers标签
 <!--导入sql映射配置文件-->
    <mappers>
        <!-- 引入sql映射文件userMapper.xml文件,
        相对路径是src目录
        userMapper.xml位于com这个包下,所以resource写成com/userMapper.xml-->
        <mapper resource="com/dao/UserDao.xml"/>
        <!--class扫描器的要求:
            1.sql映射文件必须和接口在同一个目录下
            2.映射文件的名字要和接口名一样
        -->
        <mapper class="com.mappers.UserMappers"></mapper>
        <!-- 第三种方式,包扫描器要求(推荐使用此方式):
			 1、映射文件与接口同一目录下
			 2、映射文件名必需与接口文件名称一致
		-->
        <package name="com.mappers"/>
    </mappers>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值