MyBatis简单易俗讲解,从搭建到实战

MyBatis

一、MyBatis的简介

MyBatis的官网

1.什么是MyBatis

一个半自动的ORM(对象关系映射)持久层框架

2.如何搭建MyBatis项目

1.创建maven项目

2.需要到maven仓库中找到对应的依赖文件

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.6</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.18</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.13</version>
    </dependency>

    <!--这是做单元测试的jar包-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>compile</scope>
    </dependency>

    <!--pageHelper分页插件-->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>4.1.4</version>
    </dependency>
</dependencies>

3.创建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>

    <!--配置SQL日志的输出-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!--当我们ResultMap中没有写的东西不会自动绑定的时候,就需要配置MyBatis的行为映射了-->
        <setting name="autoMappingBehavior" value="FULL"></setting>
    </settings>
    
    <typeAliases>
        <!--package 包-->
        <package name="entity"></package>
    </typeAliases>

    <!-- 配置分页插件 -->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库-->
            <property name="dialect" value="mysql"/>
        </plugin>
    </plugins>

    <!--运行环境  default默认,引用-->
    <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/smbms?characterEncoding=UTF-8&amp;useUnicode=true&amp;serverTimezone=GMT%2B8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--对应SQL映射文件,有多少个xml文件就要配置多少次-->
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
</configuration>

4.创建项目的包

  • entity
  • mapper
  • util
  • test

5.写接口

package mapper;

import entity.User;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

public interface UserMapper {

    /**
     * 查询所有用户
     */
    List<User> findUsers();
}

6.写接口对应的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="mapper.UserMapper">
    <select id="findUsers" resultType="entity.User">
      select * from smbms_user
    </select>
</mapper>

7.工具类

package utils;

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;

public class MyBatisUtil {
    public static SqlSession getSqlSession(){
        //通过流的方式读取配置文件
        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //通过工人获取工厂
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //工厂获取操作sql的对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    }

    public static void closeSqlSession(SqlSession sqlSession){
        if (sqlSession!=null){
            sqlSession.close();
        }
    }
}

8.编写测试类进行测试

package test;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import entity.User;
import mapper.UserMapper;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import utils.MyBatisUtil;

import java.util.List;

public class UserTest {
    @Test
    public void findAll(){
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = userMapper.findUsers();
        users.forEach(user->{
            System.out.println(user.toString());
        });
        MyBatisUtil.closeSqlSession(sqlSession);
    }

    @Test
    public void testPage(){
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //1.开始分页
        PageHelper.startPage(2,4);
        //2.查询所有
        List<User> userList = userMapper.findUsers();
        //3.封装分页对象
        PageInfo<User> pageInfo = new PageInfo<>(userList);
        //4.取数据
        List<User> users = pageInfo.getList();
        users.forEach(user->{
            System.out.println(user.toString());
        });
        MyBatisUtil.closeSqlSession(sqlSession);
    }
}

MyBatis中三个重要的对象生命周期以及作用域

SqlSessionFactoryBuilder: 建造者

SqlSessionFactory:工厂

SqlSession:会话

SQL映射文件

模糊查询如何实现:

select * from user where name like concat('%',#{name},'%')

多参数入参的方式:
1.通过@Param取别名的方式可以实现

List<User> selAll(@Param("userName") String userName,@Param("userRole") String userRole);
select * from user where userName like concat('%',#{userName},'%') and userRole = #{userRole}

2.封装成对象
List selAll(User user)
//主要User对象中的属性(字段)叫什么
select * from user where userName like concat(’%’,#{userName},’%’) and userRole = #{userRole}
3.封装成Map进行传参
List selAll(Map<String,Object> map)
//主要User对象中的属性(字段)叫什么
select * from user where userName like concat(’%’,#{map的key},’%’) and userRole = #{map的key}
赋值如何实现
map.put(“name”,“孙”);

update insert delete

4.当数据库字段和实体类的字段不一致的时候如何解决
多表联查如何实现

1.在User表中添加一个字段 roleName,在SQL映射文件中取别名

在User实体类中添加了一个roleName的一个字段,在通过SQL查询的返回的字段名称也叫roleName

2.使用ResultMap解决字段和属性不一致的问题



一对一和一对多 分页查询
实现方式:
User----->Role
那就在User类中添加一个Role的字段,刚好构成用户和角色一对一的关系
返回值那就不能直接写ResultType,因为Role不属于User表的字段
只能使用ResultMap






用户跟地址的关系就是一对多,供应商跟订单的关系






分页查询:
1.开始分页
PageHelper.startPage(页码,每页条数);
2.查询数据
List userList = userMapper.selAll();
3.封装成分页对象
PageInfo pageInfo = new PageInfo(userList);
4.取值
List users = pageInfo.getList();
pageInfo.getTotal()
pageInfo.getPages()
pageInfo.hasNextPage()…

动态SQL标签

if

<!--出现的问题: 要么多个where  要么多个and-->
<select id="findUserByNameOrRole" resultType="entity.User">
    SELECT
    *
    FROM
    `smbms_user`
    <if test="userName != null and userName != ''">
        where userName LIKE concat( '%', #{userName}, '%' )
    </if>
    <if test="userRole != null">
        AND userRole = #{userRole}
    </if>
</select>

where+if

<!--
	where的作用  
	1.根据条件自动拼接where,如果两个if都为空,则不会拼接where,但是
    只要有一个不为空则会拼接一个where
    2.会自动的删除and
    where的用法:直接将if放入where就OK了,但是要记得加and
-->
<select id="findUserByNameOrRoleByUseWhere" resultType="entity.User">
    SELECT
    *
    FROM
    `smbms_user`
    <where>
        <if test="userName != null and userName != ''">
            AND userName LIKE concat( '%', #{userName}, '%' )
        </if>
        <if test="userRole != null">
            AND userRole = #{userRole}
        </if>
    </where>
</select>

set

<!--
	出现的问题:没有修改的内容都会变成null值
-->
<update id="updateUserByIf">
    UPDATE `smbms`.`smbms_user` SET
    <if test="username != null and username != ''">
        userName = #{username},
    </if>
    <if test="usercode != null and usercode != ''">
        userCode = #{usercode},
    </if>
    <if test="userpassword != null and userpassword != ''">
        userPassword = #{userpassword}
    </if>
    where id = #{id}
</update>

set+if

<!--
    set的用法和where的用法差不多,也是把if包起来,并且作用都是一样的
    1.自动拼接set
    2.自动剔除,
-->
<update id="updateUserByIfAndSet">
    UPDATE `smbms`.`smbms_user`
    <set>
        <if test="username != null and username != ''">
            userName = #{username},
        </if>
        <if test="usercode != null and usercode != ''">
            userCode = #{usercode},
        </if>
        <if test="userpassword != null and userpassword != ''">
            userPassword = #{userpassword},
        </if>
    </set>
    where id = #{id}
</update>

trim

  • 代替where+if
<select id="findUserByNameOrRoleByUseTrim" resultType="entity.User">
    SELECT
    *
    FROM
    `smbms_user`
    <!--trim前面是前缀  trim后面是后缀 -->
    <!--
		prefix="前缀" suffix="后缀" 
		prefixOverrides="忽略前缀" suffixOverrides="忽略后缀"
	-->
    <trim prefix="where" prefixOverrides="and">
        <if test="userName != null and userName != ''">
            AND userName LIKE concat( '%', #{userName}, '%' )
        </if>
        <if test="userRole != null">
            AND userRole = #{userRole}
        </if>
    </trim>
</select>
  • 代替set+if
<update id="updateUserByTrim">
    UPDATE `smbms`.`smbms_user`
    <trim prefix="set" suffixOverrides="," suffix="where id = #{id}">
        <if test="username != null and username != ''">
            userName = #{username},
        </if>
        <if test="usercode != null and usercode != ''">
            userCode = #{usercode},
        </if>
        <if test="userpassword != null and userpassword != ''">
            userPassword = #{userpassword},
        </if>
    </trim>
</update>

foreach

  • 批量删除
<delete id="deleteUsers">
    delete from smbms_user where id in
    <foreach collection="array" open="(" item="id" separator="," close=")">
        #{id}
    </foreach>
</delete>
  • 批量查询
<select id="findByCodeAndPid" resultMap="BaseResultMap">
    SELECT
    *
    FROM
    `smbms_bill`
    WHERE
    billCode LIKE concat( '%', #{billCode}, '%' )
    AND providerId IN
    <!--collection有三个取值  array表示数组  list表示集合  map表示map集合-->
    <!--
            open 是以xx开头  (
            item是循环出来的每一个元素   循环数组pids得到的值pid
            separator 以XX进行分割  ,
            close   以XX结束/关闭
            (6,7,13)
        -->
    <foreach collection="array" open="(" item="pid" separator="," close=")">
        #{pid}
    </foreach>
</select>

choose

<select id="findByChoose" resultType="entity.User">
    select * from smbms_user
    <trim prefix="where" prefixOverrides="and | or">
        <choose>
            <!--if else-if else-->
            <when test="userCode != null and userCode != ''">
                and userCode = #{userCode}
            </when>
            <when test="userName != null and userName != ''">
                and userName = #{userName}
            </when>
            <otherwise>
                and userRole = #{userRole}
            </otherwise>
        </choose>
    </trim>
</select>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值