Mybatis知识总结及具体应用

一、什么是MyBatis?

1.MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

2.Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

3.可以将向 preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。(输出映射)

二、Mybatis框架执行流程是什么?

  1. 读取MyBatis 配置文件mybatis-config.xml,加载数据源、事务等,管理映射文件
  2. 加载映射文件mapper.xml,用于映射表中列和实体属性的关系
  3. 定义SQL语句,在上一步的文件中加载。
  4. 创建会话工厂。(SqlSessionFactory),数据库连接池
  5. 创建会话(SqlSession),连接对象
  6. 通过Executor 操作数据库
  7. 输入参数和输出结果

三、实现Mybatis的具体步骤

1.先在pom.xml上添加Mybatis依赖

<dependencies>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>版本号</version>
</dependency>
<!-- MySQL JDBC 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>版本号</version>
</dependency>
</dependencies>

2. 配置 MyBatis

创建 mybatis-config.xml 文件,配置数据库连接和环境等:

<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/数据库名"/>
                <property name="username" value="用户名"/>
                <property name="password" value="密码"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    </mappers>
</configuration>

3.配置 SqlSessionFactory 的操作:创建 SqlSession 实例,进而执行数据库操作

package util;

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.Reader;

public class BuilderSessionFactory {
    private static final String RESOURCE = "mybatis-config.xml";
    private static SqlSessionFactory sqlSessionFactory = null;

    static { //静态代码块
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader(RESOURCE);
        } catch (IOException e) {
            throw new RuntimeException("Get resource error:"+RESOURCE, e);
        }

        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    }


    /**
     * 获得SqlSessionFactory
     */
    public static SqlSessionFactory getSqlSessionFactory(){
        return sqlSessionFactory;
    }

}

4.根据数据库创建实体类对象,例如

 private Integer cardid;
    private String cardcode;
    private Integer perid;

    public Integer getCardid() {
        return cardid;
    }

    public void setCardid(Integer cardid) {
        this.cardid = cardid;
    }

    public String getCardcode() {
        return cardcode;
    }

    public void setCardcode(String cardcode) {
        this.cardcode = cardcode;
    }

    public Integer getPerid() {
        return perid;
    }

    public void setPerid(Integer perid) {
        this.perid = perid;
    }

    public Card(Integer cardid, String cardcode, Integer perid) {
        this.cardid = cardid;
        this.cardcode = cardcode;
        this.perid = perid;
    }

    public Card() {
    }

    @Override
    public String toString() {
        return "Card{" +
                "cardid=" + cardid +
                ", cardcode='" + cardcode + '\'' +
                ", perid=" + perid +
                '}';
    }

5.创建映射文件

(1)首先,什么是映射文件?


映射文件是 MyBatis 框架中用于定义 SQL 语句和 Java 对象之间映射的 XML 文件。它们允许开发者将数据库表的字段与 Java 类的属性关联起来,从而简化数据库操作。

(2)映射文件作用

  1. SQL 语句定义:在映射文件中,可以编写 SQL 查询、插入、更新和删除语句。
  2. 结果映射:定义 SQL 查询结果如何映射到 Java 对象的属性。
  3. 参数映射:定义如何将 Java 对象的属性作为参数传递给 SQL 语句。
  4. 动态 SQL:使用 MyBatis 的动态 SQL 功能,根据条件动态生成 SQL 语句。
  5. 缓存配置:可以为特定的 SQL 语句配置缓存策略。
  6. 事务管理:虽然通常在 MyBatis 配置文件中配置,但映射文件也可以包含事务管理的相关信息。

(3)映射文件通常遵循以下结构

  • namespace:定义映射文件的命名空间,通常是 Mapper 接口的完全限定名。
  • select|insert|update|delete:定义 SQL 语句,每个元素对应一种类型的数据库操作。
  • resultMap:定义结果映射,将 SQL 查询结果映射到 Java 类的属性。
  • sql:可以定义可重用的 SQL 片段。
  • cache:定义缓存配置。

(4)映射文件示例

<?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="com.example.mapper.CardMapper">

    <!-- ResultMap 定义 -->
    <resultMap id="cardResultMap" type="com.example.model.Card">
        <id property="cardid" column="cardid" />
        <result property="cardcode" column="cardcode" />
        <result property="perid" column="perid" />
    </resultMap>

    <!-- 查询单个 Card 记录 -->
    <select id="selectCardById" resultMap="cardResultMap">
        SELECT cardid, cardcode, perid FROM cards WHERE cardid = #{cardid}
    </select>

    <!-- 查询所有 Card 记录 -->
    <select id="selectAllCards" resultMap="cardResultMap">
        SELECT cardid, cardcode, perid FROM cards
    </select>

    <!-- 插入 Card 记录 -->
    <insert id="insertCard" useGeneratedKeys="true" keyProperty="cardid">
        INSERT INTO cards (cardcode, perid) VALUES (#{cardcode}, #{perid})
    </insert>

    <!-- 更新 Card 记录 -->
    <update id="updateCard">
        UPDATE cards SET cardcode=#{cardcode}, perid=#{perid} WHERE cardid=#{cardid}
    </update>

    <!-- 删除 Card 记录 -->
    <delete id="deleteCard">
        DELETE FROM cards WHERE cardid=#{cardid}
    </delete>

</mapper>

(5)创建 Mapper 接口: 创建一个接口作为映射文件的访问点

package com.example.mapper;

import com.example.model.Card;
import java.util.List;

public interface CardMapper {
    Card selectCardById(Integer cardid);
    List<Card> selectAllCards();
    void insertCard(Card card);
    int updateCard(Card card);
    int deleteCard(Integer cardid);
}

6.不使用映射文件也可根据注解形式写

package com.example.mapper;

import com.example.model.Card;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface CardMapperTwo {

    // 根据 cardid 查询单个 Card 记录
    @Select("SELECT cardid, cardcode, perid FROM cards WHERE cardid = #{cardid}")
    Card selectCardById(Integer cardid);

    // 查询所有 Card 记录
    @Select("SELECT cardid, cardcode, perid FROM cards")
    List<Card> selectAllCards();

    // 插入 Card 记录
    @Insert("INSERT INTO cards (cardcode, perid) VALUES (#{cardcode}, #{perid})")
    @Options(useGeneratedKeys = true, keyProperty = "cardid")
    void insertCard(Card card);

    // 更新 Card 记录
    @Update("UPDATE cards SET cardcode=#{cardcode}, perid=#{perid} WHERE cardid=#{cardid}")
    int updateCard(Card card);

    // 删除 Card 记录
    @Delete("DELETE FROM cards WHERE cardid=#{cardid}")

    
    int deleteCard(Integer cardid);
        @Select("select * from person where perid=#{perid}")
    @Results(value = {
            @Result(id = true,column = "perid",property = "perid" ),
            @Result(column = "pername",property = "pername" ),
            @Result(column = "perid",property = "card",one=@One(select = "org.example.dao.AnyToAnyTwoDao.getCardByPerid"))
    })
    Person personAndCard(int perid);
    @Select("select * from card  where perid=#{perid}")
    Card getCardByPerid(int perid);
}

7.先创建一个BuilderSessionFactory 来获取 SqlSessionFactory 并使用它来执行数据库操作的步骤


public class BuilderSessionFactory {
    private static final String RESOURCE = "mybatis-config.xml";
    private static SqlSessionFactory sqlSessionFactory = null;

    static { //静态代码块
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader(RESOURCE);
        } catch (IOException e) {
            throw new RuntimeException("Get resource error:"+RESOURCE, e);
        }

        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    }


    /**
     * 获得SqlSessionFactory
     */
    public static SqlSessionFactory getSqlSessionFactory(){
        return sqlSessionFactory;
    }

}

8.调用Mysql方法

(1)通过映射文件接口调用Mysql方法

 public class CardMapperDemo {
    public static void main(String[] args) {
        try (SqlSession sqlSession = BuilderSessionFactory.getSqlSessionFactory().openSession(true)) {
            CardMapper mapper = sqlSession.getMapper(CardMapper.class);
            
            // 示例:根据 ID 查询单个 Card 记录
            Integer cardIdToFind = 1; // 假设我们要查找 cardid 为 1 的记录
            Card card = mapper.selectCardById(cardIdToFind);
            System.out.println("Selected Card: " + card);
            
            // 示例:查询所有 Card 记录
            List<Card> cards = mapper.selectAllCards();
            System.out.println("All Cards: " + cards);
            
            // 示例:插入一个新的 Card 记录
            Card newCard = new Card(/* 构造 Card 对象 */);
            mapper.insertCard(newCard);
            // 注意:这里不需要提交事务,因为 openSession(true) 已经自动提交
            
            // 示例:更新 Card 记录
            Card cardToUpdate = /* 获取或构造 Card 对象 */;
            mapper.updateCard(cardToUpdate);
            // 同上,不需要手动提交事务
            
            // 示例:删除 Card 记录
            Integer cardIdToDelete = 2; // 假设我们要删除 cardid 为 2 的记录
            mapper.deleteCard(cardIdToDelete);
            // 同上,不需要手动提交事务

        } catch (Exception e) {
            // 处理异常,如果需要可以回滚事务
            e.printStackTrace();
        }
    }
}

(2)通过注解形式调用mysql方法

public class CardMapperDemo {
    public static void main(String[] args) {
        try (SqlSession sqlSession = BuilderSessionFactory.getSqlSessionFactory().openSession(true)) {
            CardMapperTwo mapper = sqlSession.getMapper(CardMapperTwo.class);
            
            // 示例:根据 ID 查询单个 Card 记录
            Integer cardIdToFind = 1; // 假设我们要查找 cardid 为 1 的记录
            Card card = mapper.selectCardById(cardIdToFind);
            System.out.println("Selected Card: " + card);
            
            // 示例:查询所有 Card 记录
            List<Card> cards = mapper.selectAllCards();
            System.out.println("All Cards: " + cards);
            
            // 示例:插入一个新的 Card 记录
            Card newCard = new Card(/* 构造 Card 对象 */);
            mapper.insertCard(newCard);
            // 注意:这里不需要提交事务,因为 openSession(true) 已经自动提交
            
            // 示例:更新 Card 记录
            Card cardToUpdate = /* 获取或构造 Card 对象 */;
            mapper.updateCard(cardToUpdate);
            // 同上,不需要手动提交事务
            
            // 示例:删除 Card 记录
            Integer cardIdToDelete = 2; // 假设我们要删除 cardid 为 2 的记录
            mapper.deleteCard(cardIdToDelete);
            // 同上,不需要手动提交事务

        } catch (Exception e) {
            // 处理异常,如果需要可以回滚事务
            e.printStackTrace();
        }
    }
}
  • 19
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值