12月22, 2018

MyBatis手把手跟我做(一) 快速开始

MyBatis手把手跟我做(一) 快速开始

该系列课程全套PPT及相关代码:

链接: https://pan.baidu.com/s/1wuWrJBh4LBAB7bwPXU8QXg 密码: 6m40

一.什么是MyBatis

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

上面是MyBatis官方的简介,我们把这段话说的直白一点,什么是MyBatis,为什么要用MyBatis

  1. MyBatis是让你写的java程序对数据库进行增删改查的一个工具。
  2. java对数据库进行增删改查的工具很多,较之于其他工具,mybatis容易上手,而且开发起来也很简单,同时与spring的组合也非常容易。
  3. 目前各大互联网公司多是使用mybatis。

所以,废话不多说,我们直接开始吧

二.测试用的数据库和表

既然是一个对数据库进行操作的工具,所以,我们首先准备好数据库和表

DROP DATABASE IF EXISTS `crm`;

CREATE DATABASE `crm`;

use `crm`;

DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_tel` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL,
  `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `password` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `registration_time` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB CHARSET=utf8;

INSERT INTO `t_user` VALUES ('1', '13880000001', '金庸', '0b4e7a0e5fe84ad35fb5f95b9ceeac79', '2018-12-15 06:54:16'),
 ('2', '13880000002', '张三丰', '875f26fdb1cecf20ceb4ca028263dec6', '2018-12-15 06:54:16'), 
 ('3', '13880000003', '张无忌', 'c1f68ec06b490b3ecb4066b1b13a9ee9', '2018-12-15 06:54:16'), 
 ('4', '13880000004', '黄蓉', '980ac217c6b51e7dc41040bec1edfec8', '2018-12-15 06:54:16'), 
 ('5', '13880000005', '郭靖', 'cd87cd5ef753a06ee79fc75dc7cfe66c', '2018-12-15 06:54:16'),
 ('6', '13880000006', '周伯通', 'eed8cdc400dfd4ec85dff70a170066b7', '2018-12-15 06:54:16'),
  ('7', '13880000006', '杨过', '594f803b380a41396ed63dca39503542', '2018-12-17 17:05:40');

三.建立Maven工程

给Maven小白稍微介绍以下,如果熟悉Maven的,你可以看一下2.pom.xml文件,导入相关包,或者直接跳过这段内容

1.Maven工程的基本结构

你可以建立一个简单的java工程进行测试,不过这样子的话,你需要自己去导入相关的jar包,不过其实也不多,关键的就两个,一个MySql的连接jar包,一个MyBatis的jar包,不过还是强烈建议大家直接使用Maven工程. 不过可能你还没有接触过Maven,无所谓,常用的开发工具IntelliJ IDEA和最新的Eclipse都默认安装了Maven插件,直接创建Maven工程就好了 没使用过Maven工程也无所谓,知道下面两点,其实我们就可以无障碍的写代码了

  1. 日常使用Maven常用的功能其实就是自动帮我们导入相关的关联包
  2. Maven是一个工程构建工具,简单来说,就是我们的Java工程要按照Maven规定的模式创建,java源文件应该放在什么位置,配置文件,测试文件该放在什么位置等等都有规定 maven工程目录

上面展示的就是一个刚刚创建好的Maven工程的基本结构,接下来,我们在IntelliJ IDEA中创建一个Maven工程 -w844 2018-12-22_15-48-09 -w792

这个样子创建好之后,就是上面Maven项目第一个截图的样子了

2.修改pom.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.yingside</groupId>
    <artifactId>mybatisdemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--mysql数据库驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!--引入mybatis包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
        <!--引入junit测试包-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

<dependencies></dependencies>标签中加入相应包的Maven标签,就能自动引入了

3.查找相关包的dependency标签

当然每个包相应的maven标签是什么也不用纠结,你可以在maven repository网站中搜索对应的包名就行了 比如你要查找mybatis的包 -w946 -w741 搜索出很多mybatis相关内容,我们只是使用原始的mybatis包,选择第一个 -w709 选择你需要的mybatis版本,这里的版本划分的很细,其实并不重要,你随便选一个版本都可以 -w725

当你修改好pom.xml文件之后,IntelliJ IDEA会在右下角提示你是否在pom.xml文件修改后自动导入相关包 -w304 我们选择Enable Auto-Import 就可以了

四.MyBatis配置文件

上面主要是和maven相关的,接下来才是MyBatis最重要的内容 我们要使用MyBatis,肯定需要相关配置,现在主流的其实就两种XML配置文件,以及注解配置,我们先来看一下通过XML配置文件实现的过程 下面是整个工程的结构 -w338

1.在resources目录中加入mybatis-configuration.xml文件

mybatis-configuration.xml文件是整个MyBatis的全局配置文件

<?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"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3307/crm"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

其实不用我多解释,大家也看的出来,现在这里主要配置的是数据库连接的相关内容,当然现在这里只是一个很简单的配置,后面我们还需要做修改

注意:mysql默认端口是3306,我这里由于使用了Docker映射出来的端口,所以端口做出了修改,你不必和我一样

2.定义表所对应的实体类

-w337

package com.yingside.bean;

public class User {
    private Integer id;
    private String userTel;
    private String username;
    private String password;
    private String registrationTime;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUserTel() {
        return userTel;
    }

    public void setUserTel(String userTel) {
        this.userTel = userTel;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRegistrationTime() {
        return registrationTime;
    }

    public void setRegistrationTime(String registrationTime) {
        this.registrationTime = registrationTime;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", userTel='" + userTel + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", registrationTime='" + registrationTime + '\'' +
                '}';
    }
}

3.定义操作 t_user 表的sql映射文件UserMapper.xml

-w341

<?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">
<!-- 这个XML文件其实就相当于我们三层架构中的DAO层的实现类xxxDaoImpl,如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。
    也就是说,有了这个配置文件,至少之前原始JDBC中经常出现的Connection,PreparedStatement,ResultSet这些接口不需要你再创建了
    当然要编写这个文件,需要对<mapper>标签中出现的属性和标签都要熟悉,不过没有必要去一一熟悉,用到什么我们再去查询就行了
-->
<!-- 为这个mapper指定一个唯一的namespace,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的
例如namespace="om.yingside.mapper.UserMapper"就是com.yingside.mapper(包名)+UserMapper(UserMapper.xml文件去除后缀)
 -->
<mapper namespace="com.yingside.mapper.UserMapper">
    <!--
       根据 id 查询 user 表中的数据
       id:唯一标识符,此文件中的id值不能重复,简单来说,就是DAO层中的方法名
       resultType:返回值类型,一条数据库记录也就对应实体类的一个对象,注意现在要跟上全名(包名+类名)
       parameterType:参数类型,也就是查询条件的类型
       #{}表示一个占位符即?,在使用时不需要关心参数值的类型,mybatis会自动进行java类型和jdbc类型的转换。
     -->
    <select id="getUser" parameterType="int"
            resultType="com.yingside.bean.User">
        select * from t_user where id=#{id}
    </select>
</mapper>

4.在mybatis-configuration.xml配置文件中注册UserMapper.xml文件

mybatis-configuration.xml文件的<configuration></configuration>标签中加入<mappers></mappers>标签

通过下面的截图,注意<mappers></mappers>的位置 -w581

<!-- 注册UserMapper.xml文件,
       UserMapper.xml位于com.yingside.mapper这个包下,
       所以resource写成com/yingside/mapper/UserMapper.xml-->
    <mappers>
        <mapper resource="com/yingside/mapper/UserMapper.xml" />
    </mappers>

5.创建测试

-w338

package com.yingside.test;

import com.yingside.bean.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;

import java.io.InputStream;

public class Test {
    SqlSession sqlSession = null;

    @Before
    public void init(){
        //mybatis全局配置文件
        String resource = "mybatis-configuration.xml";
        //加载全局配置文件
        InputStream is = this.getClass().getClassLoader().getResourceAsStream(resource);
        //创建SqlSession工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        //通过工厂生成sqlSession
        sqlSession = factory.openSession();
    }

    @org.junit.Test
    public void testGetUser(){
        /*这个字符串由 userMapper.xml 文件中 两个部分构成
        <mapper namespace="com.yingside.mapper.UserMapper"> 的 namespace 的值
        <select id="getUser" > id 值
        其实就相当于之前Dao层中xxxDaoImpl.getUser()方法
        */
        String stmt = "com.yingside.mapper.UserMapper.getUser";
        //传入字符串以及参数id
        User user = sqlSession.selectOne(stmt,1);
        System.out.println(user);
        //关闭sqlSession
        sqlSession.close();
    }
}

其实现在已经可以测试运行了,我们试一试,结果打印了下面的内容

User{id=1, userTel='null', username='金庸', password='0b4e7a0e5fe84ad35fb5f95b9ceeac79', registrationTime='null'}

User对象确实成功的获取到了,并且id,username和password属性都成功的取得,但是userTel和registrationTime却是null,这明显是有问题的,不过至少现在已经成功的获取了数据库中的内容,其他的问题,我们下面的章节再来一一解决

五. IDEA开发工具不能找到XML文件的问题

如果你按照步骤一步一步做下来,结果还是有问题,报了下面的错误,那么很有可能就是你IDEA工具自身的问题

org.apache.ibatis.exceptions.PersistenceException: 
### Error building SqlSession.
### The error may exist in com/yingside/mapper/UserMapper.xml
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/yingside/mapper/UserMapper.xml
...

简单来说,这个错误就是告诉你没有找到相应的xml文件,但是我们在配置文件中确实也配置了UserMapper.xml的位置.

导致这个问题的原因是: 某些版本的IDEA不会编译src的java目录的xml文件

解决思路就是:将IDEA maven项目中src源代码下的xml等资源文件编译进classes文件夹

体操作方法就是:配置maven的pom文件配置,在节点下添加代码

 <build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>

这样就可以解决现在的问题了,当然,我们以后肯定要和Spring结合起来一起用,到时候通过Spring去配置XML也不会存在这些问题了

本文链接:http://www.yanhongzhi.com/post/mybatis-quick.html

-- EOF --

Comments