Mybatis的快速入门超详细

什么是 MyBatis?

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

MyBatis的优点

  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件就可以了,易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供xml标签,支持编写动态sql。

Mybatis官网:mybatis – MyBatis 3 | 简介

MyBatis开发步骤

① 添加MyBatis,Mysql等相关依赖
<!--mybatis坐标-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.13</version>
</dependency>
<!--mysql驱动坐标-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.32</version>
</dependency>
<!--单元测试坐标-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>
② 编写核心文件mybatis-config.xml

附代码:

<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件-->
    <properties resource="db.properties"/>  
    <settings>
        <!--配置驼峰命名映射-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <!--使用扫描包的形式定义别名 -->
    <typeAliases>
        <package name="pojo" />
    </typeAliases> 
    <environments default="development">        <!--指定默认的环境名称-->
        <environment id="development">          <!--指定当前环境的名称-->
            <transactionManager type="JDBC"/>   <!--指定事务管理类型是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="com/example/mapper/UserMapper.xml"/> 
    </mappers>
</configuration>
③ 编写连接配置db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/freshman?useUnicode=true&characterEncoding=utf-8
username=root
password=123456
④ 创建mapper接口

MyBatis中的mapper接口相当于以前的dao。但是区别在于,mapper仅仅是接口,我们不需要提供实现类

public interface UserMapper {  
    /**  
    * 添加用户信息  
    */  
    int insertUser();  
}
⑤ 编写映射文件xxxMapper.xml

  • 映射配置文件文件名与Mapper接口名一致,且放在相同的包下(同包同名)。

⑥ 编写工具类MybatisUtils

因为在测试时需要多次的从 XML 中构建 SqlSessionFactory且从SqlSessionFactory 中获取 SqlSession,为了更方便的复用,把其封装到MybatisUtils工具类中。

/**
 * 工具类
 */
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory = null;
    // 初始化SqlSessionFactory对象
    static {
        try {
            // 使用MyBatis提供的Resources类加载MyBatis的配置文件
            Reader reader = 
                    Resources.getResourceAsReader("mybatis-config.xml");
            // 构建SqlSessionFactory工厂
            sqlSessionFactory = 
                    new SqlSessionFactoryBuilder().build(reader);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 获取SqlSession对象的静态方法
    public static SqlSession getSession() {
        //openSession() 会默认开启一个事务,但事务不会自动提交
        return sqlSessionFactory.openSession();
    }
}
⑦ 编写测试
public class DeptTest {

    @Test
    public void findInfoByDeptIdTest(){
        //调用工具类MybatisUtils中的getSession()方法
        SqlSession sqlSession = MybatisUtils.getSession();    
        Dept dept = sqlSession.selectOne
                ("com.example.mapper.DeptMapper.findInfoByDeptId",401);
        System.out.println(dept.toString());
        sqlSession.close();
    }

association解决多对一的映射关系

  • association:处理多对一的映射关系
  • property:需要处理多对的映射关系的属性名
  • javaType:该属性的类型

实体类Dept:

public class Dept {
    private Integer deptId;//系别ID
    private String deptName;//系名
    private List<Major> majorList;
    //构造方法....
}

实体类Major:

public class Major {

    private String majorId;//专业ID
    private String majorName;//专业
    private Integer tuition;//学费
    private Integer deptId;//系别ID
    private Dept dept;
    //构造方法....
}

MajorMapper.xml

<!--嵌套查询方式:根据专业名称模糊查找专业及相关的系部信息-->
<select id="findDeptByMajor" parameterType="String" resultMap="majorList">
    select * from tb_major where major_name like concat('%',#{majorName},'%')
</select>

<resultMap id="majorList" type="Major">
    <id property="majorId" column="major_id"/>
    <result property="majorName" column="major_name"/>
    <result property="tuition" column="tuition"/>
    <!-- 方式一:嵌套查询 -->
    <!-- 多对一:association使用select属性引入另外一条SQL语句 -->
    <association property="dept" column="dept_id"
                 javaType="Dept"
                 select="com.example.mapper.DeptMapper.findDeptById"/>
</resultMap>

DeptMapper.xml

<!-- 根据系编号查询系信息-->
<select id="findDeptById" resultType="Dept">
    select * from tb_dept where dept_id=#{deptId}
</select>

输出结果:

注:输出结果取决于实体类中构造方法toString()

collection解决一对多的映射关系

  • collection:用来处理一对多的映射关系
  • ofType:表示该属性对饮的集合中存储的数据的类型

DeptMapper.xml

<!--嵌套结果查询方式:根据系编号查询系部及相关专业信息-->
<!--根据系编号(dept_id)查询,要求使用嵌套结果查询指定系的所有专业信息(一对多)-->
<select id="findInfoByDeptId" resultMap="DeptWithMajorsResult">
    SELECT d.dept_id,d.dept_name,m.major_id,m.major_name,m.tuition
    from tb_dept d left join tb_major m on d.dept_id = m.dept_id
    where d.dept_id = #{deptId}
</select>

<resultMap id="DeptWithMajorsResult" type="Dept">
    <id property="deptId" column="dept_id"/>
    <result property="deptName" column="dept_name"/>
    <!--collection:一对多关联映射-->
    <collection property="majorList" ofType="Major">
        <id property="majorId" column="major_id"/>
        <result property="majorName" column="major_name"/>
        <result property="tuition" column="tuition"/>
    </collection>
</resultMap>

输出结果:

注:输出结果取决于实体类中构造方法toString()

动态SQL

  • <if>
    • 用于判断条件是否成立,如果条件为true,则拼接SQL
    • 形式:<if test = "name != null">..</if>
  • <where>
    • where元素只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或OR
<!--resultType:单条记录所封装得类型-->
<select id="list" resultType="com.example.springbootmybatiscrudxml.pojo.Emp">
    /*ctrl+alt+l    快速排列格式*/
    <include refid="commonSelect"></include>
    /*
    mybatis动态sql:
    where:where元素只会在子元素有内容的情况下才插入where子句。而且会自动去除子句的开头的AND或        OR
    if:用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL
      */
    <where>
        <if test="name != null">
            name like concat('%', #{name}, '%')
        </if>
        <if test="gender != null">
            and gender = #{gender}
        </if>
        <if test="begin != null and end != null">
            and entrydate between #{begin} and #{end}
        </if>
    </where>
    order by update_time desc
</select>
  • <set>
    • 动态地在行首插入SET关键字,并会删掉额外的逗号。(用在update语句中)
<!--动态更新员工-->
<update id="update2">
    update emp
    /*set:
        动态的在行首插入SET关键字,并会删掉额外的逗号。(用在update语句中)
      */
    <set>
        <if test="username != null">username = #{username},</if>
        <if test="name != null">name = #{name},</if>
        <if test="gender != null">gender = #{gender},</if>
        <if test="image != null">image = #{image},</if>
        <if test="job != null">job = #{job},</if>
        <if test="entrydate != null">entrydate = #{entrydate},</if>
        <if test="deptId != null">dept_id = #{deptId},</if>
        <if test="updateTime != null">update_time = #{updateTime}</if>
    </set>
    where id = #{id}
</update>
  • <foreach>
    • ​​​​​​​<foreach collection="集合名称" item="集合遍历出来的元素/项" separator="每一次遍历使用的分隔符" open="遍历开始前拼接的片段" close="遍历结束后拼接的片段">

</foreach>

<delete id="deleteByIds">
    delete from emp where id in
    <foreach collection="ids" item="id" separator="," open="(" close=")">
        #{id}
    </foreach>
</delete>
  • sql片段
    • ​​​​​​​<sql>
      • ​​​​​​​定义可重用的SQL片段
<sql id="commonSelect">
    select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time
    from emp
</sql>
  • <include>
    • ​​​​​​​通过属性refid,指定包含的sql片段
 <include refid="commonSelect"></include>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值