快速上手Mybatis

前言

Mybatis是一个以JDBC为基础封装的持久层框架

文档主要目的: 熟悉常用的Mybatis使用方法

扩展阅读还是推荐在线文档: MyBatis3

导包

  <!--替换JDBC技术的Mybatis-->
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.7</version>
  </dependency>

编写配置文件

<?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中的数据,并在整个配置文件中用来替换需要动态配置的属性值-->
    <properties resource="druid.properties"></properties>

    <settings>
        <!--指定 MyBatis 所用日志的具体实现-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!--开启数据库名称和类名驼峰映射-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <!--类型别名配合注解开发:在实体类前加上@Alias("别名") 。name包名指向自己的实体类所在的包路径-->
    <typeAliases>
        <package name="top.itifrd.pojo"/>
    </typeAliases>
    <!--MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中使用相同的 SQL 映射。还有许多类似的使用场景。-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!--使用了Druid连接池整合Mybatis,在高级篇中讲,这里可以使用默认的方式:见: https://mybatis.org/mybatis-3/zh/getting-started.html ,XML的配置-->
            <dataSource type="top.itifrd.config.DruidDataSourceFactory">
                <!--url,username,password将会由druid.properties中设置的相应值来替换-->
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--将包内的映射器接口实现全部注册为映射器-->
    <mappers>
        <package name="top.itifrd.mapper"/>
    </mappers>
</configuration>

Tips : 这里给出db.propertis 文件内容,mybatis-config.xml中读取了该文件

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/chengyunlaidb?useSSL=false&Unicode=true&characterEncoding=utf8
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000

制作工具类得到Session

XML
InputStream
SqlSessionFactoryBuilder.build
sqlSessionFactory.openSession
Session

从XML配置文件中构造SqlSessionFactory,SqlSessionFactory可以得到Session,通过Session就可以操作sql语句

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。

SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。

SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。

Tips : 制作要求

  • 1. SqlSessionFactoryBuilder : 这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。
  • 2. SqlSessionFactory : 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。所以只需要该类的一个对象即可
  • 3. SqlSession : 每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
package top.itifrd.utils;
import jdk.nashorn.internal.objects.annotations.Getter;
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;

/**
 * @ClassName
 * @Description 静态代码块只执行一次的特性,满足1条和2条
 * @Author:chengyunlai
 * @Date
 * @Version 1.0
 **/
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory = null;

    static {
        try {
            InputStream instream = Resources.getResourceAsStream("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(instream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 该类无法被手动new实例化
    private MybatisUtils(){};
   

    /**
     * @Description: 该封装思想有一个问题,无法关闭sqlSession
     * @Param: [clazz]
     * @return: E
     * @Author: chengyunlai
     * @Date: 2022/5/18
     */
    // public static <E> E getSqlSession(Class<E> clazz){
    //     SqlSession sqlSession = sqlSessionFactory.openSession();
    //     E mapper = sqlSession.getMapper(clazz);
    //     return mapper;
    // }

    /**
     * @Description: 调用时暴露一个sqssion即可,用户手动关闭
     * @Param: []
     * @return: org.apache.ibatis.session.SqlSession
     * @Author: chengyunlai
     * @Date: 2022/5/18
     */
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

CURD – 对应实体的Mapper接口和xml配置

安装插件

image.png

  • 功能1:快速定位Mapper接口和对应XML配置文件
  • 功能2:接口方法快速生成对应的xml Sql语句

接口

public interface UserMapper {
    List<User> selectAll();
    // 注解加xml混合开发方式,简单的语句使用注解,复杂的语句使用xml
    @Select("select * from user where id = #{id}")
    User getOneById(@Param("id") Integer id);
    @Select("select count(*) from user where username = #{username}")
    // @Param注解相当于给变量起个标签,在xml中#{},要和@Param("")中的内容一致
    Integer selectUserByUsername(@Param("username") String username);

    // xml用到接收的内容都要user打头
    int updateUser(@Param("user")User user);
    int addUser(@Param("user")User user);
    int deleteUserById(@Param("id") Integer id);
}

映射文件

创建Mapper模板

image.png

<?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="top.itifrd.mapper">

</mapper>
根据上面的模板创建

注意事项:

  • 接口和配置文件包路径相同(方便在mybatis-config中做映射)

image.png
命名规则:如图所示

image.png

使用插件创建模板和语句(推荐)

这个推荐当然是基于 你可以使用插件开发的情况

image.png

image.png


先给出一个单表CURD的内容,然后我们逐句的讲解

<?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="top.itifrd.mapper.UserMapper">
    <insert id="addUser">
        insert into user (username, password, description, age) VALUES (#{user.username},#{user.password},#{user.description},#{user.age})
    </insert>

    <update id="updateUser">
        update user
        <set>
            <if test="user.username != null and user.username != ''">
                username = #{user.username},
            </if>
            <if test="user.password != null and user.password != ''">
                password = #{user.password},
            </if>
            <if test="user.description != null and user.description != ''">
                description = #{user.description},
            </if>
            <if test="user.age != null and user.age != ''">
                age = #{user.age}
            </if>
        </set>
        <where>
            <if test="user.id != null">
                id = #{user.id};
            </if>
        </where>
    </update>

    <delete id="deleteUserById">
        delete from user where id = #{id};
    </delete>
    <!-- 它在命名空间 “top.itifrd.mapper.UserMapper” 中定义了一个名为 “selectAll” 的映射语句-->
    <!--相当于注入sql语句-->
    <select id="selectAll" resultType="user">
        select * from user;
    </select>
</mapper>
命名空间 <mapper namespace="">
<mapper namespace="top.itifrd.mapper.UserMapper">

可以为每个映射文件起一个唯一的命名空间,保证它的唯一性。我们现在常使用全类路径,并且有对应的Mapper接口,所以指向配置文件对应的Mapper接口即可。

插入标签 <insert id=""></insert>
<insert id="addUser"> insert into user (username, password, description, age) VALUES (#{user.username},#{user.password},#{user.description},#{user.age}) </insert>

使用标签<insert></insert>表示这是一个插入语句,id对应着接口中方法名,下面id作用雷同,标签内是正常的sql语句,#{}用于接收参数,#{}内容名称可以在接口中定义@params("")指定名称。

Tips

  • #{}底层使用preparestatement可以防止sql注入
  • ${}底层使用sql拼接,会有sql注入的风险
查询标签 <select id="" resultType=""></select>
<select id="selectAll" resultType="user">
    select * from user;
</select>

Tips

  • resultType 中对应着对应封装的实体类,可以使用别名
  • 还有resultMap 见高级篇更新
修改标签<update id=""></update>
<update id="updateUser">
    update user
    <set>
        <if test="user.username != null and user.username != ''">
            username = #{user.username},
        </if>
        <if test="user.password != null and user.password != ''">
            password = #{user.password},
        </if>
        <if test="user.description != null and user.description != ''">
            description = #{user.description},
        </if>
        <if test="user.age != null and user.age != ''">
            age = #{user.age}
        </if>
    </set>
    <where>
        <if test="user.id != null">
            id = #{user.id};
        </if>
    </where>
</update>

Tips

  • 这里的<set>;<if>使用了动态sql,就是一个逻辑的判断,当参数不为空的时候使用if包裹的语句,详细见高级篇
删除标签 <delete id=""></delete>
<delete id="deleteUserById">
    delete from user where id = #{id};
</delete>

将映射文件在配置文件中注册

观察配置文件中的内容,这里使用:包映射的方式

<mappers>
    <package name="top.itifrd.mapper"/>
</mappers>

Tips :这里有个小坑,一定要注意 resources 中的 映射文件xmljava 中的 Mapper接口 在同一个包下,这个同个包下是指编译后的全类路径: classes 中接口和对应的xml在同个文件夹下

image.png

  • 基础篇结束
  • 下一阶段 : Mybatis高级篇

已经更新:

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值