专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

初识Mybatis

什么是 MyBatis?

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

Mybatis 官方文档 : http://www.mybatis.org/mybatis-3/zh/index.html

GitHub : https://github.com/mybatis/mybatis-3

持久化

持久化是将程序数据在持久状态和瞬时状态转换的机制。

  • 即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等。
  • JDBC就是一种持久化机制。文件IO也是一种持久化机制。
  • 在生活中 : 将鲜肉冷藏,吃的时候再解冻的方法也是。将水果做成罐头的方法也是。

为什么需要持久化服务?那是由于内存本身的缺陷引起的

  • 内存断电后数据会丢失,但有一些对象是无论如何都不能丢失的,比如银行账号等,遗憾的是,人们还无法保证内存永不掉电。
  • 内存过于昂贵,与硬盘、光盘等外存相比,内存的价格要高2~3个数量级,而且维持成本也高,至少需要一直供电吧。所以即使对象不需要永久保存,也会因为内存的容量限制不能一直呆在内存中,需要持久化来缓存到外存。

持久层

什么是持久层?

  • 完成持久化工作的代码块 . —-> dao层 【DAO (Data Access Object) 数据访问对象】
  • 大多数情况下特别是企业级应用,数据持久化往往也就意味着将内存中的数据保存到磁盘上加以固化,而持久化的实现过程则大多通过各种关系数据库来完成。
  • 不过这里有一个字需要特别强调,也就是所谓的“层”。对于应用系统而言,数据持久功能大多是必不可少的组成部分。也就是说,我们的系统中,已经天然的具备了“持久层”概念?也许是,但也许实际情况并非如此。之所以要独立出一个“持久层”的概念,而不是“持久模块”,“持久单元”,也就意味着,我们的系统架构中,应该有一个相对独立的逻辑层面,专著于数据持久化逻辑的实现.
  • 与系统其他部分相对而言,这个层面应该具有一个较为清晰和严格的逻辑边界。 【说白了就是用来操作数据库存在的!】

为什么需要 Mybatis

  • Mybatis就是帮助程序猿将数据存入数据库中 , 和从数据库中取数据 .
  • 传统的jdbc操作 , 有很多重复代码块 .比如 : 数据取出时的封装 , 数据库的建立连接等等… , 通过框架可以减少重复代码,提高开发效率 。
  • MyBatis 是一个半自动化的ORM框架 (Object Relationship Mapping) –>对象关系映射
  • 所有的事情,不用Mybatis依旧可以做到,只是用了它,所有实现会更加简单!技术没有高低之分,只有使用这个技术的人有高低之别
  • MyBatis的优点
  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件就可以了,易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis 不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过 sql 语句可以满足操作数据库的所有需求。
  • 解除 sql 与程序代码的耦合:通过提供 DAO 层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql 和代码的分离,提高了可维护性。
  • 提供 xml 标签,支持编写动态sql。

Mybatis 入门

数据库环境

----新建数据库
CREATE DATABASE `mybatis`;

USE `mybatis`;

----新建表
DROP TABLE if EXISTS `user`;
CREATE TABLE `user`(
    `id` INT(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
    `name` VARCHAR(30) DEFAULT NULL COMMENT '姓名',
    `pwd` VARCHAR(30) DEFAULT NULL COMMENT '密码',
    PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT charset=utf8;

---插入数据
INSERT into `user` (`name`,`pwd`) VALUES
('hresh','123456'),
('hresh2','123456'),
('hresh3','123456')

基本环境搭建

1、pom.xml

dependencies>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.10</version>
</dependency>
</dependencies>

2、mybatis-config.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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!--jdbc.url=jdbc:mysql://localhost:3306/oto?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC-->
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&useSSL=true&serverTimezone=UTC&characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="1234567"/>
            </dataSource>
        </environment>
    </environments>

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

3、工具类:MybatisUtil.java

public class MybatisUtil {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        String resource = "mybatis-config.xml";
        try {
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。 接着再从 SqlSessionFactory 实例中获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法 。

4、实体类:User.java

@Data
@AllArgsConstructor
public class User {
    private int id;
    private String name;
    private String pwd;
}

5、接口类:UserMapper.java

public interface UserMapper {

    List<User> getUserList();
    User selectUser(int id);
    User getUser(Map<String,Object> map);
    List<User> getUserLike(String name);
    List<User> getUserLike2(String name);
    int updateUser(User user);
    int insertUser(User user);
    int deleteUser(User user);
}

6、编写 UserMapper.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="com.msdn.mapper.UserMapper">
    <select id="getUserList" resultType="com.msdn.bean.User">
        select * from mybatis.user
    </select>

    <select id="selectUser" parameterType="int" resultType="com.msdn.bean.User">
        select * from mybatis.user where id = #{id}
    </select>

    <select id="getUser" parameterType="map" resultType="com.msdn.bean.User">
        select * from mybatis.user where name = #{name}
    </select>

    <!--select * from mybatis.user where name like "%"#{name}"%"-->
    <select id="getUserLike" parameterType="String" resultType="com.msdn.bean.User">
        select * from mybatis.user where name like #{name}
    </select>

    <select id="getUserLike2" parameterType="String" resultType="com.msdn.bean.User">
        select * from mybatis.user where name like "%"#{name}"%"
    </select>

    <insert id="insertUser" parameterType="com.msdn.bean.User">
        insert into mybatis.user(name,pwd) values(#{name},#{pwd})
    </insert>

    <update id="updateUser" parameterType="com.msdn.bean.User">
        update mybatis.user set name = #{name} where id=#{id};
    </update>

    <delete id="deleteUser" parameterType="com.msdn.bean.User">
        delete from mybatis.user where id=#{id}
    </delete>
</mapper>

7、测试类

public class UserTest {

    @Test
    public void getUser(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        //方式一
        //方法一有很多优势,首先它不依赖于字符串字面值,会更安全一点
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = userMapper.getUserList();

        //方式二
//        List<User> users = sqlSession.selectList("com.msdn.mapper.UserMapper.getUserList");

        for (User user :
                users) {
            System.out.println(user);
        }

        sqlSession.close();
    }

    @Test
    public void getUser2(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        Map<String, Object> map = new HashMap<String, Object>();

        map.put("name","hresh");
        map.put("id","2");
        User user = userMapper.getUser(map);

        System.out.println(user);

        sqlSession.close();
    }

    @Test
    public void getUserLike(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        String name = "%hresh%";
//        List<User> users = userMapper.getUserLike(name);
        List<User> users = userMapper.getUserLike2("resh");
        for (User u :
                users) {
            System.out.println(u);
        }

        sqlSession.close();
    }

    @Test
    public void selectOne(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.selectUser(2);
        System.out.println(user);

        sqlSession.close();
    }

    @Test
    public void insertOne(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User(11,"acorn","23455");
        int res = userMapper.insertUser(user);

        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void updateOne(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User(3,"she","123453");
        userMapper.updateUser(user);

        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void deleteOne(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User(3,"she","123453");
        userMapper.deleteUser(user);

        sqlSession.commit();
        sqlSession.close();
    }
}

Mybatis 执行流程

55_1.png

作用域理解

  • SqlSessionFactoryBuilder 的作用在于创建 SqlSessionFactory,创建成功后,SqlSessionFactoryBuilder 就失去了作用,所以它只能存在于创建 SqlSessionFactory 的方法中,而不要让其长期存在。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。
  • SqlSessionFactory 可以被认为是一个数据库连接池,它的作用是创建 SqlSession 接口对象。因为 MyBatis 的本质就是 Java 对数据库的操作,所以 SqlSessionFactory 的生命周期存在于整个 MyBatis 的应用之中,所以一旦创建了 SqlSessionFactory,就要长期保存它,直至不再使用 MyBatis 应用,所以可以认为 SqlSessionFactory 的生命周期就等同于 MyBatis 的应用周期。
  • 由于 SqlSessionFactory 是一个对数据库的连接池,所以它占据着数据库的连接资源。如果创建多个 SqlSessionFactory,那么就存在多个数据库连接池,这样不利于对数据库资源的控制,也会导致数据库连接资源被消耗光,出现系统宕机等情况,所以尽量避免发生这样的情况。
  • 因此在一般的应用中我们往往希望 SqlSessionFactory 作为一个单例,让它在应用中被共享。所以说 SqlSessionFactory 的最佳作用域是应用作用域。
  • 如果说 SqlSessionFactory 相当于数据库连接池,那么 SqlSession 就相当于一个数据库连接(Connection 对象),你可以在一个事务里面执行多条 SQL,然后通过它的 commit、rollback 等方法,提交或者回滚事务。所以它应该存活在一个业务请求中,处理完整个请求后,应该关闭这条连接,让它归还给 SqlSessionFactory,否则数据库资源就很快被耗费精光,系统就会瘫痪,所以用 try…catch…finally… 语句来保证其正确关闭。
  • 所以 SqlSession 的最佳的作用域是请求或方法作用域。

55_2.png

注意事项

Maven静态资源过滤问题

在 pom.xml 文件中新增如下配置:

<resources>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.properties</include>
            <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
    </resource>
    <resource>
        <directory>src/main/resources</directory>
        <includes>
            <include>**/*.properties</include>
            <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
    </resource>
</resources>

IDEA 连接 Mysql 数据库

55_3.png

Mysql 依赖根据版本不同配置略有不同

Mysql 5.x

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&useSSL=true&serverTimezone=UTC&characterEncoding=utf-8
username=root
password=123456

Mysql 8.x

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&useSSL=true&serverTimezone=UTC&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username=root
password=123456

需要更换 driver 对象,同时需要在 url 中指定时区。

文章永久链接:https://tech.souyunku.com/18760

未经允许不得转载:搜云库技术团队 » 初识Mybatis

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们