MyBatis3 (2) 增删改查

436 阅读8分钟

1. SQL配置文件

概念: SQL配置文件用于配置SQL语句块以及SQL相关配置:

  • 开发实体类:数据库主键无符号使用Integer对应,有符号使用Long对应。
  • 开发核心配置文件:使用 <typeAliases> 配置自定义别名:
    • <typeAlias type="类全名" alias="别名">:单类配置别名。
    • <package name="包名">:整包配置别名,此时类名即别名,不区分大小写。
  • 开发SQL配置文件:配置根标签 <mapper>namespace 以隔离语句。
    • 在核心配置文件中使用 <mappers resource=""> 引入SQL配置文件。
  • 取消IDEA中SQL语句黄绿色背景:File - Settings - Editor
    • Inspections - SQL - 取勾 No data sources configuredSQL dialect detection
    • Color Scheme - General - Code - Injected language fragment - 取勾 Background

mybatis内置别名.md

源码: /mybatis3/

  • res: classpath:mybatis-crud.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/db.propertiesyap"/>

<!--别名扫描-->
    <typeAliases>
        <!--<typeAlias type="com.yap.pojo.Student" alias="student"/>-->
        <package name="com.yap.pojo"/>
    </typeAliases>

    <environments default="development">

        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>

    </environments>

    <mappers>
        <mapper resource="mapper/student-mapper.xml"/>
        <mapper resource="mapper/teacher-mapper.xml"/>
        <mapper resource="mapper/worker-mapper.xml"/>
    </mappers>

</configuration>
  • src: c.y.pojo.Student/Worker/Teacher
package com.yap.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @author yap
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Serializable {
    private Integer id;
    private String name;
    private Integer gender;
    private Integer age;
    private String info;
}

2. DML语句块

流程: DML操作可以省略 parameterType,必须省略 resultType

  • 开发 <insert id="insert">:单表添加普通版语句块:
    • useGeneratedKeys="true":启用主键回注机制。
    • keyProperty="id":指定主键回注到哪个字段中。
  • 开发 <insert id="insertWithSelectKey">:单表添加SelectKey版语句块:
    • <selectKey>:设置子语句块,伴随 <insert> 一同执行。
    • order="BEFORE":设置子语句块在 <insert> 语句之前执行。
    • keyProperty="id":设置子语句块的查询结果回注到 id 字段中。
    • resultType:指定回注字段的类全名,不可省略。
    • SELECT last_insert_id():返回最后一条插入记录的注解。
    • SELECT uuid():返回一个随机字符串。
  • 开发 <update id="updateById">:单表修改语句块。
  • 开发 <delete id="deleteById">:单表删除语句块。
  • 开发SQL语句: 支持占位符 #{} 时,自动补充单引号:
    • 参数若为实体类,则占位符中必须为实体类中对应属性名,支持多级连调。
    • 参数若为简单类,则占位符中内容可以随意填写,但不能不写。
  • 测试:
    • session.insert("命名空间.SQL语句块ID", 入参):添加数据。
    • session.update("命名空间.SQL语句块ID", 入参):修改数据。
    • session.delete("命名空间.SQL语句块ID", 入参):删除数据。

源码: /mybatis3/

  • res: classpath:mapper/student-mapper.xml
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="studentSpace">

    <cache readOnly="true"/>

    <sql id="cols">`id`, `name`, `gender`, `age`, `info`</sql>

    <insert id="insert" parameterType="student" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO `student` (<include refid="cols"/>)
        VALUES (#{id}, #{name}, #{gender}, #{age}, #{info})
    </insert>

    <insert id="insertWithSelectKey">
        <selectKey order="AFTER" keyProperty="id" resultType="int">
            SELECT last_insert_id()
        </selectKey>

        INSERT INTO `student` (<include refid="cols"/>)
        VALUES (#{id}, #{name}, #{gender}, #{age}, #{info})
    </insert>

    <select id="findById" resultType="student">
        SELECT
        <include refid="cols"/>
        FROM `student`
        WHERE `id` = #{id}
    </select>

    <select id="findLikeName" resultType="student">
        SELECT
        <include refid="cols"/>
        FROM `student`
        WHERE `name` like '%${value}%'
    </select>

    <select id="findLikeNameWithConcat" resultType="student">
        SELECT
        <include refid="cols"/>
        FROM `student`
        WHERE `name` like concat('%', #{name}, '%')
    </select>

    <update id="updateById">
        UPDATE `student`
        SET `name`   = #{name},
            `age`    = #{age},
            `gender` = #{gender},
            `info`   = #{info}
        WHERE `id` = #{id}
    </update>

    <delete id="deleteById">
        DELETE
        FROM `student`
        WHERE `id` = #{id}
    </delete>
</mapper>
  • tst: c.y.crud.StudentTest.insert()
package com.yap.crud;

import com.yap.pojo.Student;
import com.yap.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;

/**
 * @author yap
 */
public class StudentTest {

    private SqlSessionFactory factory = MyBatisUtil.getFactory("mybatis-crud.xml");

    @Test
    public void insert() {
        Student zhaosi = new Student(null, "赵四", 1, 58, "亚洲舞王");
        Student liunneng = new Student(10, "刘能", 0, 19, "玉田花圃");
        SqlSession session = factory.openSession();
        try {
            session.insert("studentSpace.insert", zhaosi);
            session.insert("studentSpace.insert", liunneng);
            session.commit();
            System.out.println(zhaosi);
            System.out.println(liunneng);
        } catch (Exception e) {
            session.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}
  • tst: c.y.crud.StudentTest.insertWithSelectKey()
    @Test
    public void insertWithSelectKey() {
        Student dajiao = new Student(null, "大脚", 0, 18, "大脚超市");
        SqlSession session = factory.openSession();
        try {
            session.insert("studentSpace.insertWithSelectKey", dajiao);
            session.commit();
            System.out.println(dajiao);
        } catch (Exception e) {
            session.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
  • tst: c.y.crud.StudentTest.updateById()
    @Test
    public void updateById() {
        SqlSession session = factory.openSession();
        Student zhaosi = new Student(1, "谢广坤", 1, 60, "广坤山货");
        try {
            session.update("studentSpace.updateById", zhaosi);
            session.commit();
        } catch (Exception e) {
            session.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

  • tst: c.y.crud.StudentTest.deleteById()

    @Test
    public void deleteById() {
        SqlSession session = factory.openSession();
        try {
            session.delete("studentSpace.deleteById", 1);
            session.commit();
        } catch (Exception e) {
            session.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

3. DQL语句块

流程: DQL可以省略 parameterType,必须使用 resultType 指定返回值或其泛型的类全名或别名:

  • 开发 <select id="findById">:单表单查语句块。
  • 开发 <select id="findLikeName">:单表多查拼接符版语句块。
  • 开发 <select id="findLikeNameWithConcat">:单表多查占位符版语句块。
  • 开发SQL语句:支持拼接符 ${value} 时,不会自动补充单引号,有注入漏洞:
    • 参数若为实体类,则占位符中必须为实体类中对应属性名,支持多级连调。
    • 参数若为简单类,则占位符中内容必须是 value
  • SQL注入漏洞:此WEB漏洞的本质是将用户输入的数据当做代码执行以攻击系统:
    • like '%${value}%':有漏洞,若攻击者传入 'or' 时会直接执行全查。
    • like concat('%', #{name}, '%'):无注入漏洞问题。
  • SQL重用块:
    • <sql id=""> 用来封装一个SQL重用代码段。
    • <include refid=""> 可以在当前文件中任意位置引入某个SQL重用代码段。
  • SQL高级映射:resultMap 用于替代 resultType,指向一个独立的 <resultMap id="">
    • 使用属性 type 指定最终返回值类型全名或别名。
    • 使用子标签 <result> 中的 column 映射表字段名。
    • 使用子标签 <result> 中的 jdbcType 映射表字段类型,必须大写。
    • 使用子标签 <result> 中的 property 映射实体类对应属性名。
    • 使用子标签 <result> 中的 javaType 映射实体类的属性类型,可以省略。
    • 使用子标签 <id> 配置主键字段,属性同上。
  • 配置二级缓存:<cache> 用于开启二级缓存,此时所有DQL都会被缓存,所有DML都会更新缓存:
    • eviction:缓存逐出机制,默认 LRU,逐出最长时间不被使用的缓存对象,可改为 FIFO,按对象进入缓存的顺序逐出,或改为 SOFT,按照GC规则逐出,或改为 WEAK,更积极地按照GC规则逐出。
    • flushInterval:缓存刷新间隔,单位毫秒,默认不设置,表示缓存仅仅调用语句时刷新。
    • readOnly:默认 false,表示所有调用者都只能得到缓存对象的一个拷贝,效率低但安全,可改为 true,所有调用者得到的都是相同的缓存对象,性能高但不安全。
    • size:缓存大小,默认1024个,表示缓存会存储1024个列表集合或对象的引用。
    • type:覆盖缓存类,允许使用第三方或者自定义缓存的类全名,覆盖mybatis的预定义缓存机制。
    • <cache-ref namespace=""> 用于引入其他SQL配置文件的缓存配置,归一原则。
  • DQL语句块其他属性:
    • resultMap:引用 <resultMap> 的id 名,不能与 resultType 同时使用。
    • flushCache:每次调用该语句块前是否清空其缓存以保证结果最新,默认 false
    • useCache:该语句块的结果集是否会被缓存,默认 true
    • timeout:语句块超时时间,默认数值由驱动器决定。
    • fetchSize:结果集条目数达到此阈值时立刻返回结果,默认数值由驱动器决定。
    • statementType:SQL媒介类型默认为预处理 PREPARED,可改为不预处理 STATEMENT 或存储过程 CALLABLE
  • 测试:
    • session.selectOne("命名空间.SQL语句块ID", 入参):查询单条数据。
    • session.selectList("命名空间.SQL语句块ID", 入参):查询多条数据。

jdbcType枚举类型.png

源码: /mybatis3/

  • res: classpath:mapper/student-mapper.xml
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="studentSpace">

    <cache readOnly="true"/>

    <sql id="cols">`id`, `name`, `gender`, `age`, `info`</sql>

    <insert id="insert" parameterType="student" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO `student` (<include refid="cols"/>)
        VALUES (#{id}, #{name}, #{gender}, #{age}, #{info})
    </insert>

    <insert id="insertWithSelectKey">
        <selectKey order="AFTER" keyProperty="id" resultType="int">
            SELECT last_insert_id()
        </selectKey>

        INSERT INTO `student` (<include refid="cols"/>)
        VALUES (#{id}, #{name}, #{gender}, #{age}, #{info})
    </insert>

    <select id="findById" resultType="student">
        SELECT
        <include refid="cols"/>
        FROM `student`
        WHERE `id` = #{id}
    </select>

    <select id="findLikeName" resultType="student">
        SELECT
        <include refid="cols"/>
        FROM `student`
        WHERE `name` like '%${value}%'
    </select>

    <select id="findLikeNameWithConcat" resultType="student">
        SELECT
        <include refid="cols"/>
        FROM `student`
        WHERE `name` like concat('%', #{name}, '%')
    </select>

    <update id="updateById">
        UPDATE `student`
        SET `name`   = #{name},
            `age`    = #{age},
            `gender` = #{gender},
            `info`   = #{info}
        WHERE `id` = #{id}
    </update>

    <delete id="deleteById">
        DELETE
        FROM `student`
        WHERE `id` = #{id}
    </delete>
		<!--高级映射-->
    <resultMap id="findAllMap" type="student">
        <id column="id" property="id" javaType="int" jdbcType="INTEGER"/>
        <result column="name" property="name" javaType="string" jdbcType="VARCHAR"/>
        <result column="age" property="age" jdbcType="VARCHAR"/>
        <result column="gender" property="gender"/>
        <result column="info" property="info"/>
    </resultMap>
    
    <select id="findAll" resultMap="findAllMap">
        SELECT
        <include refid="cols"/>
        FROM `student`
    </select>

</mapper>
  • tst: c.y.crud.StudentTest.findById()
    @Test
    public void findById() {
        try (SqlSession session = factory.openSession();) {
            System.out.println((Student) session.selectOne(
                    "studentSpace.findById", 1));
            System.out.println((Student) session.selectOne(
                    "studentSpace.findById", new Student(1, null, null, null, null)));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

  • tst: c.y.crud.StudentTest.findLikeName()
    @Test
    public void findLikeName() {
        try (SqlSession session = factory.openSession()) {
            System.out.println(session.selectList(
                    "studentSpace.findLikeName", "刘"));
            System.out.println(session.selectList(
                    "studentSpace.findLikeName", "'or'"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

  • tst: c.y.crud.StudentTest.findLikeNameWithConcat()
    @Test
    public void findLikeNameWithConcat() {
        try (SqlSession session = factory.openSession()) {
            System.out.println(session.selectList(
                    "studentSpace.findLikeNameWithConcat", "刘"));
            System.out.println(session.selectList(
                    "studentSpace.findLikeNameWithConcat", "'or'"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  • tst: c.j.crud.StudentTest.findAll()
    @Test
    public void findAll() {
        try (SqlSession session = factory.openSession()) {
            System.out.println(session.selectList("studentSpace.findAll"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

4. 接口开发

流程: 接口动态代理模式需要额外开发一个遵守对应关系的java接口:

  • 四大对应:
    • 接口类全名对应SQL配置文件的 namespace
    • 接口方法返回值类型对应SQL语句块的 resultType
    • 接口方法方法名对应SQL语句块的 id
    • 接口方法形参对应SQL语句块的 parameterType
  • 注解SQL:接口开发时,可使用注解替代SQL语句块以简化代码:
    • 删除SQL配置文件中的所有SQL语句块,但命名空间仍要对应接口类全名。
    • 接口方法上使用 @Select/@Insert/@Update/@Delete 来编写SQL。
    • 接口方法上使用 @Options 来配置缓存,超时时间,主键回注等功能。
  • 接口包扫描:接口开发时,可在核心配置文件中使用 <mappers> 的子标签 <package name=""> 整包扫描接口,但要求SQL配置文件和接口同名同包:
    • s/m/javas/m/resources 在maven打包时会合并,所以也算同包。
    • s/m/java 中默认仅打包java文件,XML文件需要额外在 pom.xml 中配置。
  • 测试:session.getMapper():获取接口对象后直接调用接口方法。

源码: /mybatis3/

  • res: pom.xml
        <!--maven打包时将*Mapper文件一并打包 写在build下-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*Mapper.xml</include>
                </includes>
            </resource>
        </resources>

接口开发

  • src: c.y.pojo.Worker
package com.yap.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @author yap
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Worker implements Serializable {
    private Integer id;
    private String name;
    private Integer gender;
    private Integer age;
    private String info;
}
  • res: classpath:mapper/worker-mapper.xml
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.yap.mapper.WorkerMapper">

    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO `worker` (`id`, `name`, `gender`, `age`, `info`)
        VALUES (#{id}, #{name}, #{gender}, #{age}, #{info})
    </insert>

    <select id="findById" resultType="worker">
        SELECT `id`, `name`, `gender`, `age`, `info`
        FROM `worker`
        WHERE `id` = #{id}
    </select>

    <select id="findLikeName" resultType="worker">
        SELECT `id`, `name`, `gender`, `age`, `info`
        FROM `worker`
        WHERE `name` like concat('%', #{name}, '%')
    </select>

    <update id="updateById">
        UPDATE `worker`
        SET `name`   = #{name},
            `age`    = #{age},
            `gender` = #{gender},
            `info`   = #{info}
        WHERE `id` = #{id}
    </update>

    <delete id="deleteById">
        DELETE
        FROM `worker`
        WHERE `id` = #{id}
    </delete>

</mapper>
  • src: c.y.mapper.WorkerMapper
package com.yap.mapper;
import com.yap.pojo.Worker;
import java.util.List;

/**
 * @author yap
 */
public interface WorkerMapper {

    /**
     * 根据主键查询一条信息
     *
     * @param id 主键
     * @return 对应主键的一条信息
     */
    Worker findById(int id);

    /**
     * 添加一条工人信息
     *
     * @param worker 工人实体
     */
    void insert(Worker worker);

    /**
     * 按照姓名模糊查询所有符合条件的工人
     *
     * @param name 姓名的模糊查询部分
     * @return 所有符合条件的工人
     */
    List<Worker> findLikeName(String name);

    /**
     * 根据主键修改一条工人信息
     *
     * @param worker 工人实体
     */
    void updateById(Worker worker);

    /**
     * 根据主键删除工人
     *
     * @param id 主键
     */
    void deleteById(int id);
}
  • tst: c.y.crud.WorkerTest
package com.yap.crud;

import com.yap.mapper.WorkerMapper;
import com.yap.pojo.Worker;
import com.yap.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;

/**
 * @author yap
 */
public class WorkerTest {

    private SqlSessionFactory factory = MyBatisUtil.getFactory("mybatis-crud.xml");

    @Test
    public void insert() {
        SqlSession session = factory.openSession();
        WorkerMapper workerMapper = session.getMapper(WorkerMapper.class);
        try {
            workerMapper.insert(new Worker(null, "赵四", 1, 58, "亚洲舞王"));
            workerMapper.insert(new Worker(null, "赵五", 1, 58, "亚洲舞王"));
            workerMapper.insert(new Worker(null, "王四", 1, 58, "亚洲舞王"));
            workerMapper.insert(new Worker(null, "王五", 1, 58, "亚洲舞王"));
            session.commit();
        } catch (Exception e) {
            session.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    @Test
    public void findById() {
        try (SqlSession session = factory.openSession()) {
            WorkerMapper workerMapper = session.getMapper(WorkerMapper.class);
            System.out.println(workerMapper.findById(1));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void findLikeName() {
        try (SqlSession session = factory.openSession()) {
            WorkerMapper workerMapper = session.getMapper(WorkerMapper.class);
            System.out.println(workerMapper.findLikeName("四"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void updateById() {
        SqlSession session = factory.openSession();
        WorkerMapper workerMapper = session.getMapper(WorkerMapper.class);
        try {
            workerMapper.updateById(new Worker(1, "刘能", 1, 58, "村副主任"));
            session.commit();
        } catch (Exception e) {
            session.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    @Test
    public void deleteById() {
        SqlSession session = factory.openSession();
        WorkerMapper workerMapper = session.getMapper(WorkerMapper.class);
        try {
            workerMapper.deleteById(1);
            session.commit();
        } catch (Exception e) {
            session.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}

注解开发

  • src: c.y.pojo.Teacher
package com.yap.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @author yap
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher implements Serializable {
    private Integer id;
    private String name;
    private Integer gender;
    private Integer age;
    private String info;
}
  • res: classpath:mapper/teacher-mapper.xml
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.yap.mapper.TeacherMapper">
    <cache-ref namespace="studentSpace"/>

</mapper>
  • src: c.y.mapper.TeacherMapper
package com.yap.mapper;

import com.yap.pojo.Teacher;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * @author yap
 */
public interface TeacherMapper {

    /**
     * 添加一条教师信息
     *
     * @param teacher 教师实体
     */
    @Insert("INSERT INTO `teacher` (`name`, `gender`, `age`, `info`) VALUES (#{name}, #{gender}, #{age}, #{info})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    void insert(Teacher teacher);

    /**
     * 根据主键查询一条信息
     *
     * @param id 主键
     * @return 对应主键的一条信息
     */
    @Select("SELECT `id`, `name`, `gender`, `age`, `info` FROM `teacher` WHERE `id` = #{id}")
    Teacher findById(int id);

    /**
     * 按照姓名模糊查询所有符合条件的教师
     *
     * @param name 姓名的模糊查询部分
     * @return 所有符合条件的教师
     */
    @Select("SELECT `id`, `name`, `gender`, `age`, `info` FROM `teacher` WHERE `name` like concat('%', #{name}, '%')")
    List<Teacher> findLikeName(String name);

    /**
     * 根据主键修改一条教师信息
     *
     * @param teacher 教师实体
     */
    @Update("UPDATE `teacher` SET `name` = #{name}, `age` = #{age}, `gender` = #{gender}, `info` = #{info} WHERE `id` = #{id}")
    void updateById(Teacher teacher);

    /**
     * 根据主键删除教师
     *
     * @param id 主键
     */
    @Delete("DELETE FROM `teacher` WHERE `id` = #{id}")
    void deleteById(int id);
}
  • tst: c.y.crud.TeacherTest
package com.yap.crud;

import com.yap.mapper.TeacherMapper;
import com.yap.pojo.Teacher;
import com.yap.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;

/**
 * @author yap
 */
public class TeacherTest {

    private SqlSessionFactory factory = MyBatisUtil.getFactory("mybatis-crud.xml");

    @Test
    public void insert() {
        SqlSession session = factory.openSession();
        TeacherMapper teacherMapper = session.getMapper(TeacherMapper.class);
        try {
            teacherMapper.insert(new Teacher(null, "赵四", 1, 58, "亚洲舞王"));
            teacherMapper.insert(new Teacher(null, "赵五", 1, 58, "亚洲舞王"));
            teacherMapper.insert(new Teacher(null, "王四", 1, 58, "亚洲舞王"));
            teacherMapper.insert(new Teacher(null, "王五", 1, 58, "亚洲舞王"));
            session.commit();
        } catch (Exception e) {
            session.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    @Test
    public void findById() {
        try (SqlSession session = factory.openSession()) {
            TeacherMapper teacherMapper = session.getMapper(TeacherMapper.class);
            System.out.println(teacherMapper.findById(1));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void findLikeName() {
        try (SqlSession session = factory.openSession()) {
            TeacherMapper teacherMapper = session.getMapper(TeacherMapper.class);
            System.out.println(teacherMapper.findLikeName("四"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void updateById() {
        SqlSession session = factory.openSession();
        TeacherMapper teacherMapper = session.getMapper(TeacherMapper.class);
        try {
            teacherMapper.updateById(new Teacher(1, "刘能", 1, 58, "村副主任"));
            session.commit();
        } catch (Exception e) {
            session.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    @Test
    public void deleteById() {
        SqlSession session = factory.openSession();
        TeacherMapper teacherMapper = session.getMapper(TeacherMapper.class);
        try {
            teacherMapper.deleteById(1);
            session.commit();
        } catch (Exception e) {
            session.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}

整体配置核心开发

  • src: c.y.pojo.Leader
package com.yap.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @author yap
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Leader implements Serializable {
    private Integer id;
    private String name;
    private Integer gender;
    private Integer age;
    private String info;
}
  • res: classpath:mybatis-package.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/db.properties"/>
    <!--    起别名-->
    <typeAliases>
        <package name="com.yap.pojo"/>
    </typeAliases>

    <environments default="development">

        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>

    </environments>
    <mappers>
        <package name="com/yap/mapper"/>
    </mappers>
</configuration>
  • res: classpath:com/yap/mapper.LeaderMapper.xml
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--指定接口位置-->
<mapper namespace="com.yap.mapper.LeaderMapper">

    <!--    二级缓存-->
    <cache eviction="LRU" readOnly="true" size="1024"/>

    <!--- SQL重用块:-->
    <sql id="cols">
        `id`,`name`,`gender`,`age`,`info`
    </sql>

    <!--    主键回注-->
    <insert id="insert" parameterType="leader" useGeneratedKeys="true" keyProperty="id">
        insert into mybatis.`student` (`name`, `gender`, `age`, `info`)
        values (#{name}, #{gender}, #{age}, #{info})
    </insert>


    <select id="findById" resultType="leader">
        SELECT
        <include refid="cols"/>
        from mybatis.leader
        where id = #{id}
    </select>

</mapper>
  • src: c.y.mapper.LeaderMapper
package com.yap.mapper;

import com.yap.pojo.Leader;

/**
 * @author yap
 */
public interface LeaderMapper {


    /**
     * 根据主键查询一条信息
     *
     * @param id 主键
     * @return 对应主键的一条信息
     */
    Leader findById(int id);
}

  • tst: c.y.crud.LeaderTest
package com.yap.crud;

import com.yap.mapper.LeaderMapper;
import com.yap.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;

/**
 * @Author Yap
 */
public class LeaderTest {
    private SqlSessionFactory factory = MyBatisUtil.getFactory("mybatis-package.xml");

    @Test
    public void findById() {

        try (SqlSession sqlSession = factory.openSession()) {
            LeaderMapper leaderMapper = sqlSession.getMapper(LeaderMapper.class);
            System.out.println(leaderMapper.findById(1));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

sql语句

CREATE TABLE IF NOT EXISTS `student`
(
    `id`     INT(11) AUTO_INCREMENT PRIMARY KEY,
    `name`   VARCHAR(50)  NOT NULL COMMENT '学生姓名',
    `gender` TINYINT(1)   NULL COMMENT '学生性别',
    `age`    INT(3)       NULL COMMENT '学生年龄',
    `info`   VARCHAR(500) NULL COMMENT '学生信息'
)
    COMMENT '学生表';

CREATE TABLE IF NOT EXISTS `teacher`
(
    `id`     INT(11) AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(50) NOT NULL COMMENT '教师姓名',
    `gender` TINYINT(1) NULL COMMENT '教师性别',
    `age` INT(3) NULL COMMENT '教师年龄',
    `info` VARCHAR(500) NULL COMMENT '教师信息'
)
    COMMENT '教师表';

CREATE TABLE IF NOT EXISTS `worker`
(
    `id`     INT(11) AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(50) NOT NULL COMMENT '工人姓名',
    `gender` TINYINT(1) NULL COMMENT '工人性别',
    `age` INT(3) NULL COMMENT '工人年龄',
    `info` VARCHAR(500) NULL COMMENT '工人信息'
)
    COMMENT '工人表';

CREATE TABLE IF NOT EXISTS `leader`
(
    `id`     INT(11) AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(50) NOT NULL COMMENT '领导姓名',
    `gender` TINYINT(1) NULL COMMENT '领导性别',
    `age` INT(3) NULL COMMENT '领导年龄',
    `info` VARCHAR(500) NULL COMMENT '领导信息'
)
    COMMENT '领导表';

内置别名

- `_byte``byte`                 的别名。 
- `_short``short`                的别名。
- `_int/_integer``int`                  的别名。
- `_long``long`                 的别名。
- `_float``float`                的别名。
- `_double``double`               的别名。
- `_boolean``boolean`              的别名。
- `byte``java.lang.Byte`       的别名。
- `short``java.lang.Short`      的别名。
- `int/integer``java.lang.Integer`    的别名。
- `long``java.lang.Long`       的别名。
- `float``java.lang.Float`      的别名。
- `double``java.lang.Double`     的别名。
- `boolean``java.lang.Boolean`    的别名。
- `string``java.lang.String`     的别名。
- `date``java.util.Date`       的别名。
- `map``java.util.Map`        的别名。
- `hashmap``java.util.HashMap`    的别名。
- `list``java.util.List`       的别名。
- `arraylist``java.util.ArrayList`  的别名。
- `collection``java.util.Collection` 的别名。
- `iterator``java.util.Iterator`   的别名。
- `decimal/bigdecimal``java.util.BigDecimal` 的别名。