MyBatis应用案例

01 项目结构

lua 复制代码
mybatis
|- src
   |-- main
       |-- java 
       |-- resources
|- build.gradle
|- setting.gradle

02 初始化配置

文件 文件路径
setting.gradle setting.gradle
properties 复制代码
rootProject.name = 'mybatis'
文件 文件路径
build.gradle build.gradle
gradle 复制代码
plugins {
    id 'java'
}

group 'net.feiyu'
version '1.0-SNAPSHOT'

dependencies {
    // spring data jpa
    implementation group: 'org.mybatis', name: 'mybatis', version: '3.5.4'
    
    // mysql
    implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.11'
}
文件 文件路径
hibernate.cfg.xml resources/hibernate.cfg.xml
vbnet 复制代码
@Data
public class User {
    private Integer id;
    private String userName;
    private String realName;
    private String password;
    private Integer age;
}
文件 文件路径
db.properties resources/db.properties
ini 复制代码
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://host:3306/db?characterEncoding=utf-8&serverTimezone=UTC
jdbc.username=root
jdbc.password=root
文件 文件路径
mybatis-config.xml resources/mybatis-config.xml
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="db.properties"/>
    <settings>
        <!-- 打印查询语句 -->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!-- 控制全局缓存(二级缓存), 默认 true -->
        <setting name="cacheEnabled" value="true"/>
        <!-- 延迟加载全局开关: 开启时所有关联对象都会延迟加载, 默认false  -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 当开启时, 任何方法调用都会加载对象所有属性, 默认false -->
        <!-- 可通过select标签fetchType覆盖 -->
        <setting name="aggressiveLazyLoading" value="false"/>
        <!--  Mybatis创建具有延迟加载能力对象所用到的代理工具, 默认JAVASSIST -->
        <!-- <setting name="proxyFactory" value="CGLIB" /> -->
        <!-- STATEMENT级别缓存,致使一级缓存只针对当前执行Statement有效 -->
        <setting name="localCacheScope" value="STATEMENT"/>
        <!--<setting name="localCacheScope" value="SESSION"/>-->
    </settings>

    <typeAliases>
        <!-- 别名 -->
        <!-- <typeAlias alias="user" type="com.feiyu.model.User" /> -->
        <package name="com.feiyu.model"/>
    </typeAliases>

    <!-- 创建POJO对象工厂 -->
    <objectFactory type="com.feiyu.factory.MyObjectFactory"></objectFactory>

    <plugins>
        <!-- 插件 -->
        <plugin interceptor="com.boge.interceptor.MyInterceptor">
            <property name="interceptorName" value="aaaaa"/>
        </plugin>
        <!-- 分页插件 -->
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <property name="dialect" value="mysql"/>
            <!-- 是否使用RowBounds第一个参数offset当成pageNum页码使用, 默认false -->
            <!-- 与startPage中pageNum效果一致 -->
            <property name="offsetAsPageNum" value="true"/>
            <!-- 是否使用RowBounds分页进行count查询, 默认false -->
            <property name="rowBoundsWithCount" value="true"/>
            <!-- 是否允许pageSize=0或RowBounds.limit=0查询全部结果, 返回结果仍是Page类型 -->
            <property name="pageSizeZero" value="true"/>
            <!-- 分页参数合理化, 默认false禁用, 3.3.0版本可用 -->
            <!-- 启用合理化时, 如果pageNum < 1查询第一页, pageNum > pages查询最后一页 -->
            <!-- 禁用合理化时, 如果pageNum < 1或pageNum > pages返回空数据 -->
            <property name="reasonable" value="false"/>
            <!-- 支持startPage(Object params)方法, 3.5.0版本可用 -->
            <!-- 增加params参数配置参数映射, 用于从Map或ServletRequest取值 -->
            <!-- 可以配置pageNum、pageSize、count、pageSizeZero和reasonable, 不配置使用默认值映射 -->
            <!-- 不理解该含义的前提, 不要随便复制该配置 -->
            <property name="params" value="pageNum=start;pageSize=limit;"/>
            <!-- always总是返回PageInfo类型, check检查返回类型为PageInfo, none返回Page -->
            <property name="returnPageInfo" value="check"/>
        </plugin>
    </plugins>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!-- 单独使用时配置成MANAGED没有事务ACID-->
            <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/UserMapper.xml"/>
        <!-- <mapper class="com.feiyu.mapper.UserMapper" /> -->
    </mappers>

</configuration>
文件 包路径
UserMapper.java com.feiyu.mapper
csharp 复制代码
public interface UserMapper {
    public List<User> selectUserList();
    public User selectUserById(Integer id);
}
文件 文件路径
UserMapper.xml resources/mapper/UserMapper.xml
xml 复制代码
<?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="mapper.UserMapper">
    <!-- 开启二级缓存 -->
    <cache/>

    <resultMap id="BaseResultMap" type="user">
        <id property="id" column="id" jdbcType="INTEGER"/>
        <result property="userName" column="user_name" jdbcType="VARCHAR"/>
        <result property="realName" column="real_name" jdbcType="VARCHAR"/>
        <result property="password" column="password" jdbcType="VARCHAR"/>
        <result property="age" column="age" jdbcType="INTEGER"/>
    </resultMap>
    
    <sql id="BaseSQL">
        id, user_name, real_name, password, age
    </sql>

    <select id="selectUserById" resultMap="BaseResultMap" statementType="PREPARED" parameterType="_int">
        select 
            <include refid="baseSQL"/>
        from 
            t_user
        where id = #{id}
    </select>

    <select id="selectUserList" resultMap="BaseResultMap">
        select
            <include refid="baseSQL"/>
        from 
            t_user
    </select>
</mapper>

03 编程式

MyBatis编程式调用方式解决重复代码、资源管理、SQL耦合和结果集映射4大问题,但也存在一些问题,比如很难维护硬编码Statement ID,以及输错namespace或者Statement ID只能在运行时报错,不能编译时检查类型。

java 复制代码
public class MyBatisMain {
    // MyBatis启动执行操作
    // 1.加载全局配置文件
    // 2.加载映射文件
    // 3.配置内容存储Configuration
    public static void main(String[] args) {
        // 1. 获取配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        // 2. 加载解析配置文件通过Builder对象建造SqlSessionFactory对象,
        // 建造者模式: 构建复杂对象
        // (1) 完成配置文件加载解析
        // (2) 完成SqlSessionFactory创建
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        // 3. 根据SqlSessionFactory获取SqlSession对象
        SqlSession sqlSession = factory.openSession();
        // 4. 通过SqlSession提供API操作数据库
        List<User> list = sqlSession.selectList("mapper.UserMapper.selectUserList");
        for (User user : list) {
            System.out.println(user);
        }
        // 5. 关闭会话
        sqlSession.close();
    }
}

04 代理方式

通常使用新版MyBatis推荐代理方式,通过Mapper接口方式与XML配置文件约束namespace和Statement ID,完成编译时检测是否配错问题。

java 复制代码
public class MyBatisMain {
    /**
     * MyBatis API使用
     * MyBatis启动时候会做哪些操作
     *   1.加载全局配置文件
     *   2.加载映射文件
     *   3.加载的内容存储在哪个Java对象中?Configuration
     */
    public static void main(String[] args) {
        // 1. 获取配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        // 2. 加载解析配置文件通过Builder对象建造SqlSessionFactory对象
        // 建造者模式: 构建复杂对象
        // (1) 完成配置文件加载解析
        // (2) 完成SqlSessionFactory创建
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        // 3. 根据SqlSessionFactory获取SqlSession对象
        SqlSession sqlSession = factory.openSession();
        // 4. 获取接口代码对象获得JDBC代理对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> list = mapper.selectUserList();
        for (User user : list) {
            System.out.println(user);
        }
        // 5. 关闭会话
        sqlSession.close();
    }
}
相关推荐
微笑听雨33 分钟前
Java 设计模式之单例模式(详细解析)
java·后端
微笑听雨33 分钟前
【Drools】(二)基于业务需求动态生成 DRL 规则文件:事实与动作定义详解
java·后端
snakeshe101034 分钟前
Java运算符终极指南:从基础算术到位运算实战
后端
ezl1fe37 分钟前
RAG 每日一技(七):只靠检索还不够?用Re-ranking给你的结果精修一下
后端
天天摸鱼的java工程师1 小时前
🔧 MySQL 索引的设计原则有哪些?【原理 + 业务场景实战】
java·后端·面试
snakeshe10101 小时前
Maven核心功能与IDEA高效调试技巧全解析
后端
*愿风载尘*2 小时前
ksql连接数据库免输入密码交互
数据库·后端
追风少年浪子彦2 小时前
mybatis-plus实体类主键生成策略
java·数据库·spring·mybatis·mybatis-plus
溟洵2 小时前
Qt 窗口 工具栏QToolBar、状态栏StatusBar
开发语言·前端·数据库·c++·后端·qt
ppo922 小时前
MCP简单应用:使用SpringAI + Cline + DeepSeek实现AI创建文件并写入内容
人工智能·后端