MyBatis入门笔记

2022-06-08 18:34:19 浏览数 (1)

MyBatis介绍

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

框架优点
  • 提高开发效率
  • 统一的编码规则,利于团队管理
  • 灵活配置的应用,拥有更好的维护性
SSM开发框架
MyBatis开发流程
单元测试与JUnit 4

单元测试:

  1. 单元测试是指对软件中的最小可测试单元进行检查和验证
  2. 测试用例是指编写一段代码对已有功能(方法)进行校验
  3. JUnit 4是Java中最著名的单元测试工具,主流IDE内置支持

JUnit 4使用方法:

  1. 引入JUnit Jar包或增加Maven依赖
  2. 编写测试用例验证目标方法是否正确运行
  3. 在测试用例上增加@Test注解开始单元测试

MyBatis基本使用

MyBatis配置

  • MyBatis采用XML格式配置数据库环境信息
  • MyBaits环境配置标签
  • environment包含数据库驱动、URL、用户名与密码

(47条消息) Mybatis连接池介绍与分类 Mybatis使用POOLED UNPOOLED配置连接池的原理分析_韦恩少爷的背的博客-CSDN博客_pooled

SqlSessionFactory
  • SqlSessionFactory是MyBatis的核心对象
  • 用于初始化MyBatis,创建SqlSession对象
  • 保证SqlSessionFactory在应用中全局唯一
代码语言:javascript复制
//利用Reader加载classpath下的mybatis-config.xml核心文件
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
//初始化SqlSessionFactory对象,同时解析mybatis-config.xml文件
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
System.out.println("sqlSessionFactory加载成功");
SqlSession sqlSession = null;
try {
    //创建SqlSession对象,SqlSession是JDBC的扩展类,用于数据库交互
    sqlSession = sqlSessionFactory.openSession();
    //创建数据库连接(测试用)
    Connection connection = sqlSession.getConnection();
    System.out.println(connection);
} catch (Exception e) {
    e.printStackTrace();
} finally {
    if (sqlSession != null) {
        // 如果type="POOLED",代表使用连接池,close则是将连接回收至连接池中
        // 如果type="UNPOOLED",代表直连,close则会调用Connection.close()方法关闭连接
        sqlSession.close();
    }
}
MyBatisUtils工具类
代码语言:javascript复制
/**
 * MyBatisUtils工具类,创建全局唯一的SqlSessionFactory对象
 */
public class MyBatisUtils {
    // 利用static(静态)属于类不属于对象,且全局唯一
    private static SqlSessionFactory sqlSessionFactory = null;

    //利用静态块在初始化类时实例化SqlSessionFactory
    static {
        try {
            Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
            //初始化错误时,通同抛出异常 ExceptionInInitializerError 通知调用者
            throw new ExceptionInInitializerError(e);
        }
    }

    /**
     * openSession 创建一个新的SqlSession对象
     *
     * @return SqlSession对象
     */
    public static SqlSession openSession() {
        return sqlSessionFactory.openSession();
    }

    /**
     * 释放一个SqlSession对象
     *
     * @param session 准备释放SqlSession对象
     */
    public static void closeSession(SqlSession session) {
        if (session != null) {
            session.close();
        }
    }
}

MyBatis数据查询

SQL传参

  1. 但参数传递:使用parameterType指定参数的数据类型即可,SQL中#{value}提取参数
代码语言:javascript复制
public void testSelectById() {
    SqlSession sqlSession = null;
    try {
        sqlSession = MyBatisUtils.openSession();
        Goods goods = sqlSession.selectOne("goods.selectById", 1520);
        System.out.println(goods.getTitle());
    } catch (Exception e) {
        throw e;
    } finally {
        MyBatisUtils.closeSession(sqlSession);
    }
}
  1. 多参数传递:使用parameterType指定Map接口,SQL中#{Key}提取参数
代码语言:javascript复制
public void testSelectByPriceRange() {
    SqlSession sqlSession = null;
    try {
        sqlSession = MyBatisUtils.openSession();
        Map param = new HashMap();
        param.put("min", 100);
        param.put("max", 500);
        param.put("limt", 10);
        List<Goods> list = sqlSession.selectList("selectByPriceRange", param);
        for (Goods g : list) {
            System.out.println(g.getTitle()   " 价格:"   g.getCurrentPrice());
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        MyBatisUtils.closeSession(sqlSession);
    }
}

多表关联查询

利用LinkedHashMap保存多表关联结果

MyBatis会将每一条记录包装为LinkedHashMap对象

key是字段名value是字段对应的值,字段类型根据表结构进行自动判断优点:易于扩展,易于使用

缺点:太过灵活,无法进行编译时检查

代码语言:javascript复制
<!--利用LinkedHashMap保存多表关联结果
    MyBatis会将每一条记录包装为LinkedHashMap对象
    key是字段名value是字段对应的值,字段类型根据表结构进行自动判断
    优点:易于扩展,易于使用
    缺点:太过灵活,无法进行编译时检查-->
<select id="selectGoodsMap" resultType="java.util.LinkedHashMap">
    select g.*, c.category_name
    from t_goods g,
         t_category c
    where g.category_id = c.category_id;
</select>
ResultMap结果映射
  • ResultMap可以将查询结果映射为复杂类型的Java对象
  • ResultMap适用于Java对象保存多表关联结果
  • ResultMap支持对象关联查询等高级特性
代码语言:javascript复制
<!--结果映射,id:一般为rm 单词-->
<resultMap id="rmGoods" type="pers.hua.mybatis.dto.GoodsDTO">
    <!--设置主键字段与属性映射-->
    <id property="goods.goodsId" column="goods_id"></id>
    <!--设置非主键字段与属性映射-->
    <result property="goods.title" column="title"></result>
    <result property="goods.originalCost" column="original_cost"></result>
    <result property="goods.currentPrice" column="current_price"></result>
    <result property="goods.discount" column="discount"></result>
    <result property="goods.isFreeDelivery" column="is_free_delivery"></result>
    <result property="goods.categoryId" column="category_id"></result>
    <result property="categoryName" column="category_name"/>
</resultMap>
<select id="selectGoodsDTO" resultMap="rmGoods">
    select g.*, c.category_name
    from t_goods g,
         t_category c
    where g.category_id = c.category_id;
</select>

MyBatis的数据插入、修改与删除

插入数据
代码语言:javascript复制
<!--1. parameterType:要指向实体类,
    2. 同时在传入的时候要新增传入的数据
    3. 对于主键自动生成的情况,获取每次新产生数据ID号(selectKey)-->
<insert id="insert" parameterType="pers.hua.mybatis.entity.Goods">
    INSERT INTO t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery,
    category_id)
    VALUES (#{title}, #{subTitle}, #{originalCost}, #{currentPrice}, #{discount}, #{isFreeDelivery}, #{categoryId});
    <selectKey resultType="Integer" keyProperty="goodsId" order="AFTER">
        select last_insert_id();
    </selectKey>
</insert>
selectKey和useGeneratedKeys的区别

selectKey标签用法

useGeneratedKeys属性用法

二者区别
  • selectKey标签需要明确编写获取最新主键的SQL语句
  • useGeneratedKeys属性会自动根据驱动生成对应SQL语句
应用场景
  1. selectKey适合所有的关系型数据库
  2. useGeneratedkeys只支持"自增主键"类型的数据库
更新数据
删除数据

Sql注入攻击

MyBatis两种传值方式
  • ${}文本替换,未经任何处理对SQL文本替换
  • #{}预编译传值,使用预编译传值可以预防SQL注入

MyBatis工作流程

0 人点赞