MyBatis详解(1)--MyBatis初体验(基于xml)

需求缘起

项目需求
最近公司业务不忙,我就想花点时间整理一些Java开发常用的技术知识,顺便发到博客,如果有人看到了帮助到了需要的人,那自然最好不过了。这一系列我想写国内用得最多的ORM框架MyBatis,最后也将涉及一点最近比较火的基于MyBatis 进一步封装的MyBatis-Plus的使用。

本小节的需求:通过MyBatis基于xml形式对数据表进行增删改查。

本小节代码
mybatis-demo-article(1)

1、项目中所使用的技术

技术版本说明
IDEA2018.1.4开发工具
Spring Boot2.1.8容器+MVC框架
MyBatis2.1.0ORM框架
Druid1.1.10数据库连接池
MySQL8.0.11数据库
Lombok1.18.6简化对象封装工具

说明: 本项目代码是基于Springboot 开发,相信做java开发的都会,略过,不会的请单独学习,这里重点讲MyBatis相关。

2、创建项目-MyBatis-demo

2.1 具体创建过程请参考 一起学Springboot – 第二节 EDEA 创建Springboot应用.

2.2 添加依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
            <!--数据连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

2.3 配置数据库
在 application.yml 中添加

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
    username: root
    password: 123456

2.4 向数据库中添加数据

  • 创建用户信息表
create table user_info(
  	id int(11) primary key not null auto_increment,
  	username varchar(64) not null comment '用户昵称',
  	password varchar(32) not null comment  '用户密码'
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT '用户表';
  • 向表中添加数据:
insert into user_info(username,password) values 
  ('Jone','123456'),
  ('Jack','123456'),
  ('Tom','123456'),
  ('王二','123456'),
  ('李璐','123456');

提示: 记得创建数据库 mybatis,数据库名要与配置中的一致。

2.5 创建数据库配置文件mybatis-config.xml
配置 mybatis 的方式有多种,这里使用XMl的方式,也是最简单的一种。
在 src/main/resources 下面创建 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>
    <!-- 引入外部资源文件 -->
    <properties resource="jdbc.properties"></properties>
    
    <settings>
        <!-- 设置驼峰匹配 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <typeAliases>
        <!--扫描的PO类包路径,别名是类名(大小写均可)-->
        <package name="com.mybatis.demo.model"/>
    </typeAliases>
    <!-- 配置环境:可以配置多个环境,default:配置某一个环境的唯一标识,表示默认使用哪个环境 -->
    <environments default="development">
        <environment id="development">
         <!--事务管理器
        一、JDBC:这个配置直接简单使用了 JDBC 的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围
        二、MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期
            比如 spring 或 JEE 应用服务器的上下文,默认情况下,它会关闭连接。然而一些容器并不希望这样,
            因此如果你需要从连接中停止它,就可以将 closeConnection 属性设置为 false,比如:
            <transactionManager type="MANAGED">
                <property name="closeConnection" value="false"/>
            </transactionManager>
      -->
            <transactionManager type="JDBC">
                <property name="" value=""/>
            </transactionManager>
            <dataSource type="POOLED">
                <!-- 配置连接信息 -->
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

同时写一个 jdbc.properties 文件,里面主要是连接数据库的一些参数,同样写在 src/main/resources 路径下

jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=123456

这几个文件所在项目中的位置
相关配置文件的位置

2.6 创建实体类
这个实体类是与数据表是一一映射的。

@Data
public class UserInfo {
    private Long id;
    private String username;
    private String password;
}

2.7 创建操作 user_info 表的sql映射文件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.mybatis.demo">

    <!-- 根据 id 查询 user_info 表中的数据
      id:唯一标识符,此文件中的id值不能重复
      resultType:返回值类型,一条数据库记录也就对应实体类的一个对象
      parameterType:参数类型,也就是查询条件的类型
   -->
    <!--在配置文件 mybatis-config.xml 中如果没有配置别名,则需要写全类名-->
    <!--<select id="selectUserInfoById" resultType="com.mybatis.demo.model.UserInfo" parameterType="Long">-->
    <select id="selectUserInfoById" resultType="UserInfo" parameterType="int">
        <!-- 这里和普通的sql 查询语句差不多,对于只有一个参数,后面的 #{id}表示占位符,里面不一定要写id,写啥都可以,但是不要空着,如果有多个参数则必须写pojo类里面的属性 -->
        select * from user_info where id = #{id}
    </select>


    <!-- 查询 user_info 表的所有数据
        注意:因为是查询所有数据,所以返回的应该是一个集合,这个集合里面每个元素都是User类型
     -->
    <select id="selectUserInfoAll" resultType="UserInfo">
        select * from user_info
    </select>

    <!-- 模糊查询:根据 user_info 表的username字段
            下面两种写法都可以,但是要注意
            1、${value}里面必须要写value,不然会报错
            2、${}表示拼接 sql 字符串,将接收到的参数不加任何修饰拼接在sql语句中
            3、使用${}会造成 sql 注入
     -->
    <select id="selectLikeUserName" resultType="UserInfo" parameterType="String">
        select * from user_info where username like '%${value}%'
        <!-- select * from user where username like #{username} -->
    </select>

    <!-- 向 user_info 表插入一条数据 -->
    <insert id="insertUserInfo" parameterType="UserInfo">
        insert into user_info(id,username,password)
            value(#{id},#{username},#{password})
    </insert>

    <!-- 根据 id 更新 user_info 表的数据 -->
    <update id="updateUserInfoById" parameterType="UserInfo">
        update user_info set username=#{username} where id=#{id}
    </update>

    <!-- 根据 id 删除 user_info 表的数据 -->
    <delete id="deleteUserInfoById" parameterType="int">
        delete from user_info where id=#{id}
    </delete>
</mapper>

2.8 在配置文件mybatis-config.xml 中注册 UserInfoMapper.xml

    <mappers>
        <!--注册UserInfoMapper.xml文件(操作数据表的sql映射文件),也就是UserInfoMapper.xml 的文件路径-->
        <mapper resource="mapper/UserInfoMapper.xml"/>
    </mappers>

注意事项:
如果用的是 IDEA 开发工具,xxxMapper.xml 文件的位置是有讲究的,否则程序是找不到的

  • 1 如果是想要放在 src/main/java 目录下,需要在pom.xml 中添加配置
   <build>
           <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
     </build>
  • 2 将xxxMapper.xml放到Maven构建的resource目录下面
    在 resource 创建多级目录时不要连着写几个文件夹,我连着写的时候程序找不到,分开写就可以了,比如 com.mybatis.demo.mapper,一次性写完就找不到了;我一级一级的写就好了,写好了com,接着写mybatis …

2.9 配置日志
这个是为了方便我们查看运行日志,相关依赖 Springboot 已经默认有了,不需要自己添加。
在application.yml 中添加配置:

logging:
  level:
    com.mybatis.demo.model: trace #该配置要与 <mapper namespace="com.mybatis.demo.model"> 配置的namespace 值一样,否则这个配置不起效果

说明: com.mybatis.demo.model 为实体类所在的包名,trace为级别,这样就可以在控制台中看到相关的日志。

3、测试

经过上面的准备,现在可以将项目跑起来测试了。

写一个测试类

package com.mybatis.demo.mapper;

import com.mybatis.demo.model.UserInfo;
import lombok.extern.slf4j.Slf4j;
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 org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.io.Reader;
import java.util.List;

/**
 * @auther kklu
 * @date 2019/9/29 15:49
 * @describe
 */

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class UserInfoMapperTest {
    private static SqlSessionFactory sqlSessionFactory;

    @BeforeClass
    public static void init() {
        try {
            //将工具类读入 reader
            Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
            //创建 SqlSessionFactory 对象,该对象包含了mybatis-config.xml相关配置信息
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            reader.close();
        } catch (IOException ignore) {
            ignore.printStackTrace();
        }
    }


    //根据id查询user表数据
    @Test
    public void testSelectUserInfoById() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
        /*这个字符串由 userMapper.xml 文件中 两个部分构成
            <mapper namespace="com.mybatis.demo.model"> 的 namespace 的值
            <select id="selectUserById" > id 值*/
            /*可以单独写 <select id="selectUserById" > id 值*/
            
//            String statement = "com.mybatis.demo.model.selectUserInfoById";
            String statement = "selectUserInfoById";
            UserInfo userInfo = sqlSession.selectOne(statement, 1);
            log.info("userInfo={}", userInfo);
        } finally {
            //不要忘记关闭 sqlSession
            sqlSession.close();
        }
    }

    //查询所有user表所有数据
    @Test
    public void testSelectUserInfoAll() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            String statement = "selectUserInfoAll";
            List<UserInfo> listUser = sqlSession.selectList(statement);
            for (UserInfo userInfo : listUser) {
                log.info("userInfo={}", userInfo);
            }
        } finally {
            //不要忘记关闭 sqlSession
            sqlSession.close();
        }
    }

    //模糊查询:根据 user 表的username字段
    @Test
    public void testSelectLikeUserName() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            List<UserInfo> listUser = sqlSession.selectList("selectLikeUserName", "%t%");
            for (UserInfo userInfo : listUser) {
                log.info("userInfo={}", userInfo);
            }
        } finally {
            //不要忘记关闭 sqlSession
            sqlSession.close();
        }
    }

    //向 user 表中插入一条数据
    @Test
    public void testInsertUser() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            UserInfo user = new UserInfo();
            user.setUsername("Bob");
            user.setPassword("123456");
            sqlSession.insert("insertUserInfo", user);
            //提交插入的数据
            sqlSession.commit();
        } finally {
            //不要忘记关闭 sqlSession
            sqlSession.close();
        }
    }

    //根据 id 更新 user 表的数据
    @Test
    public void testUpdateUserById() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            //如果设置的 id不存在,那么数据库没有数据更改
            UserInfo user = new UserInfo();
            user.setId(4L);
            user.setUsername("Jack");
            sqlSession.update("updateUserInfoById", user);
            sqlSession.commit();
        } finally {
            //不要忘记关闭 sqlSession
            sqlSession.close();
        }
    }


    //根据 id 删除 user 表的数据
    @Test
    public void testDeleteUserInfoById() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            sqlSession.delete("deleteUserInfoById", 6);
            sqlSession.commit();
        } finally {
            //不要忘记关闭 sqlSession
            sqlSession.close();
        }
    }
}

总结

本节似乎步骤挺多的,其实真正涉及到MyBatis 的不多,核心的是的就是两个文件;
1. mybatis-config.xml 数据库相关配置,xxxMapper.xml 路径配置
2. UserInfoMapper.xml,操作数据表的sql映射文件
总之这一小节我们实现了从零开始搭建项目到把项目顺利跑起来,体验了下MyBatis基本的用法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值