初识MyBatis——构建第一个MyBatis工程

1. 什么是MyBatis

        MyBatis是一个基于java的持久层框架,它的底层封装了jdbc,使我们不用与jdbc api打交道,就可以完成数据库持久层的操作。使用MyBatis框架,开发者只需要关注sql语句本身,不必像传统jdbc编程那样,花费大量时间处理加载驱动、创建连接、创建statement、执行查询、遍历结果集、释放资源等一系列重复步骤。

        MyBatis采用ORM思想(object   relational   mapping  对象关系映射),解决实体和数据库之间的映射问题。

           * O:面向对象领域的Object(JavaBean对象)

           * R:关系数据库领域的Relational(表的结构)

           * M:映射Mapping(XML的配置文件)

        MyBatis通过xml或注解的方式将要执行的各种sql配置起来,并通过MyBatis框架执行该sql语句,将结果映射成java对象返回。

2. JDBC程序回顾

        为了便于阅读和理解,此处对jdbc查询数据库表数据的操作进行回顾

    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try{
            // 加载数据库驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 通过驱动管理类获取数据库连接
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8","root", "root");
            //定义 sql 语句 ?表示占位符
            String sql = "select * from user where username = ?";
            //获取预处理 statement
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1, "张三");
            // 查询数据库,获取结果集
            resultSet = preparedStatement.executeQuery();
            //遍历结果集
            while(resultSet.next()){
                System.out.println(resultSet.getString("id")+resultSet.getString("username"));
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //释放资源
            if(resultSet!=null){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(preparedStatement!=null){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

问题分析:

  1. 每执行一次数据库操作,创建一次数据库连接。频繁创建数据库连接和释放资源,会造成系统资源的浪费,影响系统的性能。(使用连接池可以解决该问题,后面文章会有补充
  2. 在java程序中对sql语句进行硬编码,sql变动,需要对java代码进行维护,维护成本高。
  3. prepareStatement中使用“?”做占位符,sql中的where条件参数不固定,当遇到需要修改参数个数的时候,修改sql还需要维护java代码,系统维护不易
  4. 对结果集的解析存在硬编码,sql 变化导致解析代码变化,系统不易维护。

3. MyBatis框架入门

3.1 创建Maven工程

3.2 添加pom文件坐标依赖

首先添加打包方式,以jar的方式进行打包

    <!--打包方式-->
    <packaging>jar</packaging>

然后添加依赖坐标,主要添加mysql(数据库)、mybatis(持久层框架)、log4j(日志)和junit(单元测试)的依赖

    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.4</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

3.3 编写User实体类

主要包含姓名、年龄、联系方式和住址4个信息。其中getter,setter和toString方法可以通过右键-generater...使用IDE自动生成。

package com.aifocus.domain;

import java.io.Serializable;

public class UserInfo implements Serializable {
    /**
     * 姓名
     */
    String userName;
    /**
     * 年龄
     */
    int age;
    /**
     * 联系方式
     */
    String phoneNumber;
    /**
     * 地址
     */
    String address;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "UserInfo{" +
                "userName='" + userName + '\'' +
                ", age=" + age +
                ", phoneNumber='" + phoneNumber + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

3.4 编写实体层接口UserMapper

该接口用于查询userinfo表中的所有用户信息

package com.aifocus.dao;

import com.aifocus.domain.UserInfo;

import java.util.List;

/**
 * 用户信息持久层接口
 */
public interface UserInfoMapper {
    /**
     * 查询所有用户信息
     * @return 用户信息列表
     */
    List<UserInfo> findAll();
}

3.5 编写持久层接口映射文件UserMapper.xml

注意:resources路径下对应的包路径,无法使用“.”做分割,com/aifocus/dao需要分别创建(类似文件夹创建)

添加UserInfoMapper.xml文件的Mapper约束

<?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">
 

编写findAll的sql查询语句

<mapper namespace="com.aifocus.dao.UserInfoMapper">
    <select id="findAll" resultType="com.aifocus.domain.UserInfo">
        select * from userinfo
    </select>
</mapper>

其中,<mapper>中的namespace表示该配置文件对应的接口文件,<select>中的id,表示对应的是namespace文件中的接口的名字,resultType表示将数据库查询的结果返回值封装到哪个实体类

3.5 编写SqlMapConfig.xml配置文件(主配置文件)

该文件位于resouces目录下的根路径,用于配置数据库连接、事务、映射文件等信息

首先添加mybatis配置文件的config约束

<?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">

配置mybatis环境

<configuration>
    <!-- 配置 mybatis 的环境 -->
    <environments default="mysql">
        <!-- 配置 mysql 的环境 -->
        <environment id="mysql">
            <!-- 配置事务的类型 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置连接数据库的信息:用的是数据源(连接池) -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test_db"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!--映射文件配置-->
</configuration>

映射文件配置(注:映射文件配置需写在configuration标签中)

    <mappers>
        <mapper resource="com/itheima/dao/IUserDao.xml"/>
    </mappers>

至此,使用Mybatis编写的查询所有用户信息的基本架构已经完成。接下来进行测试程序的编写。

3.6编写测试类

package com.aifocus.dao;

import com.aifocus.domain.UserInfo;
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.InputStream;
import java.util.List;

/**
 * UserInfoMapper方法单元测试类
 */
public class UserInfoMapperTest {
    public static void main(String[] args) throws Exception {
        // 1. 读取配置文件,要用来加载SqlMapperConfig中的配置文件信息
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 2. 创建一个sqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        // 3. 使用工厂生成一个sqlSession对象
        SqlSession session = factory.openSession();
        // 4. 使用sqlSession创建dao接口的代理对象[没有创建UserInfoMapper接口的实现,就是这里做了动态代理]
        UserInfoMapper userInfoMapper = session.getMapper(UserInfoMapper.class);
        // 5. 使用代理对象执行方法
        List<UserInfo> userInfoList = userInfoMapper.findAll();
        for(UserInfo user:userInfoList){
            System.out.println(user);
        }
        // 6. 释放资源
        session.close();
        in.close();
    }
}

4 总结

4.1 Mybatis环境搭建

第一步:创建Maven工程,并导入坐标

第二步:创建实体类和Dao的接口

第三步:创建SqlMapConfig.xml主配置文件

第四步:创建UserInfoMapper.xml映射配置文件

4.2 环境搭建注意事项

1. 创建UserInfoMapper.xml和UserInfoMapper.java名称保持一致(便于查找问题)

2. 在src下的java和resource下创建目录时是不一样的。java下穿件的是包com.aifocus.dao是三级结构,在resouce下是一级结构

3. mybatis的映射配置文件位置必须和dao接口的包结构相同

4. 映射配置文件的mapper标签的namespace属性的取值必须是dao的全限定类名

5. 映射配置文件的操作配置(select),id属性的取值必须是接口的方法名

注:遵从了345点要求,在开发中,就无须再写Mapper的实现类。

解惑

使用上述MyBatis进行开发,还没有直接使用JDBC简单?尤其是编写测试类的时候,很多陌生的东西出现了。其实上述调用是为了让大家了解mybatis是如何加载配置文件,框架是如何省略我们接口实现。在实际应用开发中,上述调用过程会被封装,我们直接使用@Resource注解,就能拿到该对象,进行持久层操作。

欢迎大家一起交流学习

发布了4 篇原创文章 · 获赞 3 · 访问量 9541

猜你喜欢

转载自blog.csdn.net/AI_focus/article/details/104734014
今日推荐