mybatis01_mybatis入门

一、MyBatis简介

​ MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github。

​ MyBatis 是一个简化和实现了 Java 数据持久化层(persistence layer)的开源框架,它抽象了大量的 JDBC 冗余 代码,并提供了一个简单、易用的 API 和数据库交互。和SSH中的Hibernate有着同样的作用。

1、为什么使用mybatis框架

​ 在我们之前的数据库操作种使用单纯的 Java 的 JDBC 编程仍然存在大量的问题,比如频繁的打开和关闭链接造成资源浪费、硬编码问题等。

⬇️使用传统JDBC操作数据

try
    {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8";
        String user = "root";
        String password = "123456";
        Connection conn = DriverManager.getConnection(url, user, password);
        String sql = "select * from user where user_name=?";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setString(1, "zhangsan");
        ResultSet rs = ps.executeQuery();
        while (rs.next()) {
            User us = new User();
            us.setUserId(rs.getInt("user_id"));
            us.setUsername(rs.getString("user_name"));
            us.setPassword(rs.getString("user_pass"));
            us.setCname(rs.getString("cname"));
        }
        conn.close();
    } catch(
    Exception e)

    {
        e.printStackTrace();
    }
	MyBatis框架可以让编程人员注意在SQL 语句的编写上,通过 MyBatis 提供的映射方式,自由灵活的创建出满足业务需求的各种 SQL 语句,不管是单表查询,还是多表查询,都 可以很好的完成。如果要执行的 SQL 语句中存在占位符,那么 JDBC 在执行之前,需要向执行该 SQL 语句的 PreparedStatement 对象传入参数。Mybatis 可以将参数进行自动的输入映射,查询之后的结果集,Mybatis 可以灵活的映射成 Java 对象,这就是MyBatis的输入映射和输出映射。

2、快速入门

​ 可以进入mybatis的官网下载所需要的文件或者教程(https://mybatis.org/mybatis-3/zh/index.html)。

​ 1、pom依赖

需要的依赖有mybatis、mysql-connector、junit、log4j

 <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>

        <mybatis.version>3.5.6</mybatis.version>
        <mysql.version>8.0.30</mysql.version>
        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <lombok.version>1.18.26</lombok.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!--mybatis核心依赖-->
            <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>${mybatis.version}</version>
            </dependency>

            <!--mysql驱动-->
            <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!--单元测试-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
            <!--日志-->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>
        </dependencies>

    </dependencyManagement>

log4j的内容

# 定义输出级别为 debug,输出名称为 stdout
log4j.rootLogger=debug,stdout
# 定义 stdout 的输出采用哪个类来执行
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# 定义 stdout 的输出类型的样式布局
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# 定义 stdout 样式布局的消息格式
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

​ 2、核心配置文件 mybatis-config.xml

​ 配置文件采用dtd校验,DTD校验的限定为configuration(properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)

​ 主要元素有

configuration元素:所有配置的根元素

environments元素:元素用于配置 MyBatis 的运行环境,内部可以有多个environment 对应不同的数据库(开发时、测试时、生产时),只需要更改 中default的值即可切换环境。

transactionManager 元素:用于配置事务管理。

dataSource 元素:用于配置数据源,type 指定数据源类型,值为 pooled 表示数据库连接。

mappers元素:内部有多个mapper,对应XXXmapper.xml文件中的数据操作,mapper中提供resource属性,表示xxxmaper.xml文件的位置,当然你也可以选择url和class两个属性来代替resource。但是当文件比较多的时候我们可以直接写“文件所在的文件夹”,即,mybatis即可自动扫描所有问价夹下所需的文件,当然这部分会在Mapper高级代理中详解。

<?xml version="1.0" encoding="GBK"?>

<!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://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value=""/>
                <property name="password" value=""/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/bookMapper.xml"></mapper>
    </mappers>
</configuration>

​ 3、mapper.xml

​ mapper.xml文件的根标签为

​ mapper标签提供namespace属性用于指定命名空间以区别不同mapper.xml文件中的SQL,在这个入门案例中namespace的值可以自行定义,但是再高级Mapper代理中该值有其他重要作用。

​ 与下面的select标签中的语句一样,mapper标签中有所有CRUD的标签,其中id对应方法名(这里的方法名你可以理解为本来应该由dao层实现的方法放到了mapper.xml配置文件中,在以后的Mapper高级代理中也可以这么认为),resultType为返回值类型(输出映射),一般写成全路径的包名,parameterType代表参数类型(输入映射)。

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="bookMapper">

    <select id="findById" resultType="com.ls.model.BookTest">
        select book_id,book_name bookName,book_author bookAuthor from book where book_id = #{bookId}
    </select>

    <select id="findAll" resultType="com.ls.model.BookTest">
        select book_id bookId,book_name bookName,book_author bookAuthor from book
    </select>
</mapper>

3、创建数据库连接数据源

​ 数据表如下:

CREATE TABLE `book` (
  `book_id` int NOT NULL AUTO_INCREMENT,
  `book_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `book_author` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`book_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

​ 在Idea中配置数据库连接,这个就不细讲了:

image-20230228185238636

4、创建项目

​ 项目的结构如下,这里我创建的是聚合工程,这个随自己的喜好。

image-20230228185613898

​ 其他文件在上文已经给出,下面给出主程序TestSqlSession和实体类BookTest的代码块。

/**
 * date: 2023/2/23
 *
 * @author Arc
 */
package com.ls.model;

import lombok.Data;
import lombok.experimental.Accessors;

import java.util.Date;

@Data
@Accessors(chain = true)
public class BookTest {
    private int book_id;
    private String bookName;
    private String bookAuthor;
    private Date createTime;
    private Date updateTime;
}

/**
 * date: 2023/2/23
 *
 * @author Arc
 */
package com.ls;

import com.ls.model.BookTest;
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 TestSqlSession {
    public static void main(String[] args) throws IOException {

        InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
        SqlSession sqlsession = factory.openSession();
//        BookTest book = sqlsession.selectOne("bookMapper.findById", 2);
//        System.out.println(book);
        List<BookTest> books = sqlsession.selectList("bookMapper.findAll");
        for (BookTest book1 : books) {
            System.out.println(book1);
        }
    }
}

​ 下面简单讲解一下程序的内容:

​ BookTest中使用了lombok插件所以省略了gettersetter,且启用了链式编程风格。

​ 下面是TestSqlSession的内容,不论怎样的操作基本都是这几步。

//创建一个流来读取核心配置文件
InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
//根据配置文件创建了一个SQLSessionFactory工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
//通过工厂获得SqlSession对象,通过调用工厂的openSession方法
SqlSession sqlsession = factory.openSession();

​ 需要注意factory.openSession();的时候尚未与数据库进行连接,可见下图我们将数据源的密码删除掉,程序并没有给出报错。

image-20230228193912979

在mapper.xml文件中我们写一个select的“方法”findAll,并把这个mapper配置到mybatis-config.xml中,具体的SQL语句无异于JDBC所学的。

  <select id="findAll" resultType="com.ls.model.BookTest">
        select book_id bookId,book_name bookName,book_author bookAuthor from book
    </select>
    <mappers>
        <mapper resource="mapper/bookMapper.xml"></mapper>
    </mappers>

​ 调用我们写的findAll“方法”,通过sqlsession对象来调用mapper.xml中的“方法”,可以看到sqlsession有很多已经写好的方法,我们使用selectList,注意在参数名之前加上namespace的前缀,来让程序区分不同的mapper。

image-20230228194219050

        List<BookTest> books = sqlsession.selectList("bookMapper.findAll");
        for (BookTest book1 : books) {
            System.out.println(book1);
        }
    }

​ 使用一个List的对象来接受结果集,使用迭代器迭代打印出结果。

image-20230228194453844

5、后话

​ 关于事务的提交:在我们之前的JDBC中,事务会自动提交,但是在MyBatis中,凡是对数据修改(增删改)的操作,都需要将事务手动提交,即调用sqlsession.commit();\

​ selectList和selectOne:二者都是接收返回的结果,ctrl点击selectList后你就会发现selectone

也是基于selectList实现的,所以除非你能确定返回的是一条记录,否则不要轻易使用selectOne。

​ 输出、输入映射:mybatis自动识别入参对象,但返回值类型不能不写。之前我们说resultType的value是返回值的类型,但是findAll返回的是一个List但是我们写的却是BookTest,这一点mybatis会自动识别,所以我们只需要写集合泛型内的类型即可。

image-20230228195134855

​ 在findById这一配置中,入参是一个Integer,我们并没有指明parameterType,但是在更复杂的数据类型,推荐使用注解将参数传入。

image-20230228195312932

posted @   Purearc  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
点击右上角即可分享
微信分享提示