Mr. Cappuccino的第52杯咖啡——Mybatis环境搭建与使用

Mybatis环境搭建与使用

Mybatis介绍

Mybatis是一个用Java语言编写的持久层框架,它使用ORM实现了对结果集的封装。

ORM(Object Relational Mapping):对象关系映射。简单来说,就是把数据库表和实体类及实体类的属性对应起来,让开发者操作实体类就能实现操作数据库表,它封装了JDBC操作的很多细节,使开发者只需要关注SQL语句本身,而无需关注注册驱动、创建连接等复杂过程。

Mybatis中文网

Mybatis环境搭建与使用

Mybatis中有两种开发方式:

  1. 基于注解方式;
  2. 基于XML方式;

一般最常用的方式是基于XML的方式进行开发,而基于XML方式开发也有两种方式:

  1. 原生方式开发
  2. mapper代理开发

基于XML方式-原生方式开发

  1. 创建数据库表;
  2. 引入mybatis相关依赖;
  3. 配置数据源、mybatis等相关配置(mybatis-config.xml);
  4. 定义Java对象,对象的成员属性与数据库表中的字段名称对应;
  5. 定义mapper.xml文件,存放需要执行的SQL语句,每个表对应一个mapper;
  6. 调用mybatis框架中的api执行SQL语句并获取结果集;

创建数据库表

sql 复制代码
CREATE DATABASE IF NOT EXISTS db_mybatis
DEFAULT CHARACTER SET utf8;

USE db_mybatis;

CREATE TABLE `tb_user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
);
INSERT INTO `tb_user`(`name`) VALUES('Bob');
INSERT INTO `tb_user`(`name`) VALUES('Tom');
INSERT INTO `tb_user`(`name`) VALUES('Jack');
INSERT INTO `tb_user`(`name`) VALUES('John');

项目准备

项目结构
项目代码

pom.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com</groupId>
    <artifactId>mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.18</version>
        </dependency>
    </dependencies>

</project>

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>
    <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://127.0.0.1:3306/db_mybatis?serverTimezone=GMT%2B8"/>
                <property name="username" value="root"/>
                <property name="password" value="admin"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mappers/userMapper.xml"/>
    </mappers>
</configuration>

UserEntity.java

java 复制代码
package com.mybatis.entity;

/**
 * @author honey
 * @date 2023-07-26 15:29:38
 */
public class UserEntity {

    private Integer id;
    private String name;

    @Override
    public String toString() {
        return "UserEntity{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

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="userMapper">
    <select id="listUser" resultType="com.mybatis.entity.UserEntity">
        select * from tb_user
    </select>
</mapper>

MybatisTest01.java

java 复制代码
package com.mybatis.test;

import com.mybatis.entity.UserEntity;
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;

/**
 * @author honey
 * @date 2023-07-26 15:26:48
 */
public class MybatisTest01 {

    public static void main(String[] args) throws IOException {
        // 1.读取加载mybatis-config.xml(数据源、mybatis等配置)
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 2.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.根据mapper(namespace="userMapper" + id="listUser")执行sql语句,并将查询到的数据映射成对象(orm)
        List<UserEntity> list = sqlSession.selectList("userMapper.listUser", UserEntity.class);
        System.out.println(list);
        sqlSession.close();
    }
}
实体类中添加有参构造方法产生的问题

下面这些情况是没有问题的

  1. 不添加构造方法,默认走无参构造方法;
  2. 添加无参构造方法;
  3. 添加有参构造方法,但是构造方法中的参数与查询结果集相匹配;

第三种情况如下所示(SQL语句查询的结果与构造方法中的参数能够成功映射):

========================================================================================

SQL语句

实体类

========================================================================================

异常情况:

  1. SQL语句保持不变,将实体类调整为下述情况则会报错


  1. 实体类保持不变,将SQL语句调整为下述情况则会报错


========================================================================================

解决方案:在实体类中再额外添加一个无参构造方法。

基于XML方式-mapper代理开发

相较于原生方式开发,mapper代理开发的优势:不依赖于字符串的字面值,减少了硬编码

  1. 定义与SQL映射文件同名的mapper接口;
  2. 设置SQL映射文件的namespace属性为mapper接口全限定名;
  3. mapper接口中的方法需要与SQL映射文件中的SQL语句的ID保持一致;

原生方式开发:

java 复制代码
List<UserEntity> list = sqlSession.selectList("com.mybatis.mapper.UserMapper.listUser", UserEntity.class);

mapper代理开发:

java 复制代码
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<UserEntity> list = mapper.listUser();

项目准备

项目结构
项目代码

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="com.mybatis.mapper.UserMapper">
    <select id="listUser" resultType="com.mybatis.entity.UserEntity">
        select * from tb_user
    </select>
</mapper>

UserMapper.java

java 复制代码
package com.mybatis.mapper;

import com.mybatis.entity.UserEntity;

import java.util.List;

/**
 * @author honey
 * @date 2023-07-26 21:04:23
 */
public interface UserMapper {

    /**
     * 查询用户列表
     *
     * @return List<UserEntity>
     */
    List<UserEntity> listUser();

}

MybatisTest02.java

java 复制代码
package com.mybatis.test;

import com.mybatis.entity.UserEntity;
import com.mybatis.mapper.UserMapper;
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;

/**
 * @author honey
 * @date 2023-07-26 21:15:48
 */
public class MybatisTest02 {

    public static void main(String[] args) throws IOException {
        // 1.读取加载mybatis-config.xml(数据源、mybatis等配置)
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 2.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.根据mapper(namespace="UserMapper全限定名" + id="listUser")执行sql语句,并将查询到的数据映射成对象(orm)
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<UserEntity> list = mapper.listUser();
        System.out.println(list);
        sqlSession.close();
    }
}
SQL映射文件中namespace未设置为接口全限定名产生的问题

SQL映射文件中namespace未设置为接口全限定名会导致程序在执行的时候找不到namespace=接口全限定名所对应的SQL映射文件。

解决方法:

基于注解方式

优点:去除XML配置,提高了开发效率;

缺点:SQL语句植入Java代码,如果需要修改SQL语句必须修改源码,会导致维护成本增加,基于XML方式维护性更强;

项目准备

项目结构
项目代码

pom.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com</groupId>
    <artifactId>mybatis-annotation</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.18</version>
        </dependency>
    </dependencies>

</project>

UserEntity.java

java 复制代码
package com.mybatis.entity;

/**
 * @author honey
 * @date 2023-07-26 15:29:38
 */
public class UserEntity {

    private Integer id;
    private String name;

    @Override
    public String toString() {
        return "UserEntity{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

UserMapper.java

java 复制代码
package com.mybatis.mapper;

import com.mybatis.entity.UserEntity;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * @author honey
 * @date 2023-07-26 21:04:23
 */
public interface UserMapper {

    /**
     * 基于注解方式查询用户列表
     *
     * @return List<UserEntity>
     */
    @Select("select * from tb_user")
    List<UserEntity> listUserByAnnotation();
}

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>
    <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://127.0.0.1:3306/db_mybatis?serverTimezone=GMT%2B8"/>
                <property name="username" value="root"/>
                <property name="password" value="admin"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper class="com.mybatis.mapper.UserMapper"/>
    </mappers>
</configuration>

MybatisTest01.java

java 复制代码
package com.mybatis.test;

import com.mybatis.entity.UserEntity;
import com.mybatis.mapper.UserMapper;
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;

/**
 * @author honey
 * @date 2023-07-26 21:15:48
 */
public class MybatisTest01 {

    public static void main(String[] args) throws IOException {
        // 1.读取加载mybatis-config.xml(数据源、mybatis等配置)
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 2.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.根据mapper(namespace="com.mybatis.mapper.UserMapper" + id="listUser")执行sql语句,并将查询到的数据映射成对象(orm)
        List<UserEntity> list = sqlSession.selectList("com.mybatis.mapper.UserMapper.listUserByAnnotation", UserEntity.class);
        System.out.println(list);

        // 3.根据mapper(namespace="UserMapper全限定名" + id="listUser")执行sql语句,并将查询到的数据映射成对象(orm)
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<UserEntity> list2 = mapper.listUserByAnnotation();
        System.out.println(list2);
        sqlSession.close();
    }
}
相关推荐
一叶屋檐7 分钟前
Neo4j 图书馆借阅系统知识图谱设计
服务器·数据库·cypher
好吃的肘子1 小时前
MongoDB 应用实战
大数据·开发语言·数据库·算法·mongodb·全文检索
weixin_472339461 小时前
MySQL MCP 使用案例
数据库·mysql
lqlj22332 小时前
Spark SQL 读取 CSV 文件,并将数据写入 MySQL 数据库
数据库·sql·spark
遗憾皆是温柔3 小时前
MyBatis—动态 SQL
java·数据库·ide·sql·mybatis
未来之窗软件服务3 小时前
Cacti 未经身份验证SQL注入漏洞
android·数据库·sql·服务器安全
fengye2071613 小时前
在MYSQL中导入cookbook.sql文件
数据库·mysql·adb
Ailovelearning4 小时前
neo4j框架:ubuntu系统中neo4j安装与使用教程
数据库·neo4j
_星辰大海乀5 小时前
表的设计、聚合函数
java·数据结构·数据库·sql·mysql·数据库开发
未来之窗软件服务5 小时前
solidwors插件 开发————仙盟创梦IDE
前端·javascript·数据库·ide·仙盟创梦ide