mybatis-入门

发布于:2025-07-31 ⋅ 阅读:(23) ⋅ 点赞:(0)

一、mybatis安装

最简单的方式是使用maven来构建项目,将下面的依赖置于pom.xml文件中:

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>x.x.x</version>
</dependency>

截止目前,最新的版本为:3.5.14

二、构建 SqlSessionFactory

mybatis应用中的核心是SqlSessionFactory,SqlSessionFactory可以创建出sqlSession对象,而sqlSession对象可以执行sql语句。

方式一:从xml中构建

完整版目录树截图如下,mybatis-config.xml是myabtis应用的核心配置,用于定义数据库连接信息等,mapper用于定义mybatis对象对外提供的功能,pojo用于接收数据库的表记录对象,resources目录下的mapper.xml文件用于实现mybatis对象对外提供的功能。

1、创建mybatis-config.xml

在resources目录下创建一个mybatis-config.xml文件,内容为:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

 mybatis是操作数据库表对象的,这里先简单配置了最基本的数据库连接信息。

注意:mysql数据库需要提前安装好,数据库表也需要提前创建好。我这里有一个demo表:

CREATE TABLE `t_user` (
    `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID,自增主键',
    `username` VARCHAR(50) NOT NULL COMMENT '用户名',
    `password` VARCHAR(100) NOT NULL COMMENT '密码(建议存储加密后的密码)',
    `gender` VARCHAR(10) DEFAULT NULL COMMENT '性别,如:男、女',
    `addr` VARCHAR(255) DEFAULT NULL COMMENT '地址',
    PRIMARY KEY (`id`),
    UNIQUE KEY `idx_username` (`username`) COMMENT '用户名唯一,避免重复注册'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

-- 初始化用户数据
INSERT INTO `t_user` (`username`, `password`, `gender`, `addr`)
VALUES
    ('zhangsan', 'e10adc3949ba59abbe56e057f20f883e', '男', '北京市朝阳区'),
    ('lisi', 'e10adc3949ba59abbe56e057f20f883e', '女', '上海市浦东新区'),
    ('wangwu', 'e10adc3949ba59abbe56e057f20f883e', '男', '广州市天河区');

2、创建User类

User类用于接收数据库查询出来的对象

package com.cosseen.pojo;

import lombok.Data;

@Data
public class User {
    Integer id;
    String username;
    String password;
    String gender;
    String addr;
}

这里我添加了@Data注解,有了这个注解,可以省略getId, setId等函数。

这里我使用的是1.18.3版本,因此需要给pom.xml中添加如下代码:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.34</version>
</dependency>

3、创建Mapper接口

mapper接口主要用于封装 库表对象 对外提供的功能,比如,我把返回所有用户的查询封装成一个selectAll函数,那么调用这个函数,就相当于执行select * from t_user;

package com.cosseen.mapper;

import com.cosseen.pojo.User;

import java.util.List;

public interface UserMapper {
    List<User> selectAll();
}

4、创建UserMapper.xml文件

这个文件是mapper接口函数的具体实现,其中id属性和mapper的函数名需要对应。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cosseen.mapper.UserMapper">
    <select id="selectAll" resultType="com.cosseen.pojo.User">
        select * from t_user;
    </select>
</mapper>

注意:

想让程序识别到这个配置,还需要给mybatis-config.xml中加一个配置,内容如下:

    <mappers>
        <mapper resource="com/cosseen/mapper/UserMapper.xml"/>
    </mappers>

5、创建主应用类MybatisApp

代码内容如下:

package com.cosseen;

import com.cosseen.mapper.UserMapper;
import com.cosseen.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MybatisApp {
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = userMapper.selectAll();
        for (User user : users) {
            System.out.println(user.getUsername());
        }
    }
}

6、执行结果

日志打印了执行的sql语句和执行结果。

注意:

打印数据库日志,需要配置logback,pom依赖如下:

<!-- SLF4J 核心API,日志门面 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.36</version>
</dependency>

<!-- Logback 核心模块 -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.2.11</version>
</dependency>

<!-- Logback 经典模块(包含对 SLF4J 的实现) -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.11</version>
</dependency>

logback.xml内容如下,和mybatis-config.xml放到同级目录下即可。

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <!-- 定义日志输出格式 -->
    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n" />

    <!-- 定义日志存储路径 -->
    <property name="LOG_PATH" value="./logs" />

    <!-- 控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- 控制台输出格式 -->
            <pattern>${LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 按天滚动的文件输出 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 日志文件路径及名称 -->
        <file>${LOG_PATH}/app.log</file>

        <!-- 滚动策略:按天生成日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 滚动后文件的命名格式 -->
            <fileNamePattern>${LOG_PATH}/app.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志文件保留天数 -->
            <maxHistory>30</maxHistory>
            <!-- 总日志大小限制 -->
            <totalSizeCap>1GB</totalSizeCap>
        </rollingPolicy>

        <!-- 日志输出格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 错误日志单独输出 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/error.log</file>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>

        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>

        <!-- 只输出ERROR级别及以上的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 根日志配置 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
        <appender-ref ref="ERROR_FILE" />
    </root>

    <!-- 可以为特定包配置不同的日志级别 -->
    <logger name="com.cosseen" level="DEBUG" additivity="false">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </logger>

    <!-- 关闭第三方框架的日志输出(如Spring、MyBatis等) -->
    <logger name="org.springframework" level="WARN" />
    <!--<logger name="org.mybatis" level="WARN" />-->
    <logger name="org.mybatis" level="DEBUG" />
</configuration>

方式二、通过java代码创建

这种方式会复用方式一中的大部分类,这里只列出了差异的文件。目录树如下:

1、创建一个数据库工厂类

package com.cosseen.factory;

import org.apache.ibatis.datasource.pooled.PooledDataSource;

import javax.sql.DataSource;

public class UserDataSourceFactory {
    // 数据库连接信息(实际开发中建议通过配置文件或配置中心读取)
    private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
    private static final String URL = "jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=UTC";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "123456";

    /**
     * 获取 mybatis内置连接池数据源(生产环境推荐)
     */
    public static DataSource getBlogDataSource() {
        // 配置 HikariCP 连接池参数
        PooledDataSource pooledDataSource = new PooledDataSource(DRIVER, URL, USERNAME, PASSWORD);

        return pooledDataSource;
    }
}

2、创建主应用类MybatisDatasourceApp

package com.cosseen;

import com.cosseen.factory.UserDataSourceFactory;
import com.cosseen.mapper.UserMapper;
import com.cosseen.pojo.User;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

import javax.sql.DataSource;
import java.util.List;

public class MybatisDatasourceApp {
    public static void main(String[] args) {
        DataSource dataSource = UserDataSourceFactory.getBlogDataSource();
        TransactionFactory transactionFactory = new JdbcTransactionFactory();
        Environment environment = new Environment("development", transactionFactory, dataSource);
        Configuration configuration = new Configuration(environment);
        configuration.addMapper(UserMapper.class);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = userMapper.selectAll();
        for (User user : users) {
            System.out.println(user.getUsername());
        }

    }
}

三、SqlSession直接调用Mapper方法

代码如下:

package com.cosseen;

import com.cosseen.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MybatisSqlsessionApp {
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        List<User> users = null;
        try (SqlSession session = sqlSessionFactory.openSession()) {
            users = session.selectList("com.cosseen.mapper.UserMapper.selectAll", null);
        }

        for (User user : users) {
            System.out.println(user.getUsername());
        }
    }
}
session对象直接调用了Mapper方法中的函数,因为selectAll没有参数,所以传递的是null。

四、命名空间

在UserMapper.xml配置文件中,有一个namespace属性,值是com.cosseen.mapper.UserMapper, 这个值有什么用呢?

<mapper namespace="com.cosseen.mapper.UserMapper">
    <select id="selectAll" resultType="com.cosseen.pojo.User">
        select * from t_user;
    </select>
</mapper>

思考这么一个问题:

假设我还有一个Teacher表,里面也有一个selectAll方法,那程序如何区分调用的是哪个对象的selectAll方法呢? namespace的作用就是隔离不同对象的相同方法,避免混淆。

五、使用注解来完成映射

上面的UserMapper.xml文件以不写,把sql语句写入到UserMapper.java文件中。

package com.cosseen.mapper;

import com.cosseen.pojo.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface UserMapper {
    @Select("select * from t_user")
    List<User> selectAll();
}

六、作用域和生命周期

  • SqlSessionFactoryBuilder

   SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量),该对象不需要始终存在,一旦创建SqlSessionFactory,就不再需要它了。 

  • SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,且只应该存在一份,所以,该对象最好是单例模式。

  •  SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。

 下面的示例就是一个确保 SqlSession 关闭的标准模式:

try (SqlSession session = sqlSessionFactory.openSession()) {
  // 你的应用逻辑代码
}


网站公告

今日签到

点亮在社区的每一天
去签到