MyBatis —— 初窥门径

前言

        MyBatis作为一款优秀的持久层框架,在Java后端开发中无疑是比较重要一环,在常见的spring整合的SSM框架以及之后的SpringBoot中都可以看到MyBatis大显神威的模样。在这篇文章中,荔枝将会从Maven开启创建一个MyBatis项目并整理MyBatis相应的配置和模板的设定。


文章目录

前言

一、MyBatis概述与环境搭建

1.1 MyBatis与其它持久层技术的对比

1.2 通过Maven开启一个MyBatis项目

1.2.1 构建核心配置文件 

environments标签

typeAliases:设置类型别名

mapper:可以以包为单位来引入映射文件

1.2.2 构建映射文件

1.2.3 mapper层接口

1.2.4 实体类文件

1.3 MyBatis项目测试

1.4 查询功能

1.5 优化:借助properties文件存放数据库连接数据

二、MyBatis核心配置文件模板设置和工具类封装

2.1 设置核心配置文件的模板 

2.2 封装用来获取MyBatis连接数据库时的会话对象的工具类  

三、MyBatis获取参数值

3.1 获取参数值的两种方式

3.2 MyBatis获取五种类型的参数值

3.2.1 单个字面量类型

3.2.2 多个字面量参数

3.2.3 手动将参数存储在一个map集合中

3.2.4 实体类参数

3.2.5 使用@param注解来命名参数

总结


一、MyBatis概述与环境搭建

        我们知道在Java后端项目中通过JDBC的API来执行数据库的操作,JDBC中不仅需要提供访问数据库的API,还需要封装与各种数据库服务器通信的步骤,这个过程无疑会有较多的冗杂的操作,而MyBatis框架的出现无疑很好地解决了这个问题。MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射,避免了几乎所有的JDBC代码和手动设置参数以及获取结果集,它是一个半自动ORM框架。

1.1 MyBatis与其它持久层技术的对比

JDBC

  • SQL夹杂在到ave代码中耦合度高,导致硬编码内伤
  • 维护不易且实际开发需求中SQL有变化,需要频繁修改,代码冗长,开发效率低

Hibernate和JPA

  • 操作简便,开发效率高
  • 内部自动生产的SQL,不容易做特殊优化,程序中的长难复杂SQL需要绕过框架
  • 基于全映射的全自动框架,大量字段的POJO进行部分映射时比较困难。
  • 反射操作太多,导致数据库性能下降

1.2 通过Maven开启一个MyBatis项目

        我们常说的配置文件,其实就是核心配置文件+映射文件,其中核心配置文件主要是有关数据库的整体配置以及响应的映射文件的引入,其中映射文件的名字最好和mapper接口的名称保持一致。

        在之前的Java web中我们通过Dao层来实现后端中有关数据库的操作,其中dao层包含了接口层以及接口所对应的实现类,在springMVC中或者说是mybatis中我们将其分为mapper层和pojo层,mapper层其实就相当于dao接口层。

1.2.1 构建核心配置文件 

<?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://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--引入映射文件-->
    <mappers>
        <mapper resource="mappers/UserMapper.xml"/>
    </mappers>
</configuration>
environments标签

environments:配置多个连接数据库的环境,在使用的时候只会使用一个,default属性值设置默认使用的数据库环境的id

transactionManager:设置事务管理方式,type:JDBC | MANAGE

  • JDBC:表示在执行sql中采用的是JDBC中原生的事务管理方式,事务提交需要手动
  • MANAGE:被管理,比如Spring

dataSource:配置数据源

属性:type:设置数据源的类型

           type="POOLED | UNPOLLED | JNDI"

  • POOLED:使用数据库连接池缓存数据库连接
  • UNPOOLED:不使用数据库连接池
  • JNDI:表示使用上下文的数据源 

MyBatis核心配置文件的顺序

properties -> settings -> typeAliases -> typeHandlers -> objectFactory -> objectwrapperFactory -> refLectorFactory -> plugins -> environments -> databaseIdProvider -> mappers

typeAliases:设置类型别名

类型别名不区分大小写,如果不使用alias声明别名,默认是实体类的类名作为别名。

<!--设置类型别名-->
<typeAliases>
    <typeAlias type="com.crj.pojo.User" alias="User"/>
</typeAliases>

以包为单位设置类型别名

<typeAliases>
    <package name="com.crj.pojo"/>
</typeAliases>
mapper:可以以包为单位来引入映射文件

以包为单位引入映射文件要求:

  • 1.mapper接口所在的包要与映射文件所在的包一致
  • 2.mapper接口要和映射文件的名字一致

<mappers>
    <package name="com.crj.mybatis.xml"/>
</mappers>

1.2.2 构建映射文件

<?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.crj.mapper.UserMapper">
<!--    int insertUser();-->
    <insert id="insertUser">
        insert into t_user values(null,'admin','123456',23,'男','12345@qq.com')
    </insert>
</mapper>

1.2.3 mapper层接口

package com.crj.mapper;

public interface UserMapper {
    /**
     * 添加用户功能
     */
    int insertUser();
}

需要注意的是:这里需要保证MyBatis面向接口编程的两个一致

  1. 映射文件xx.xml中mapper标签下的namespace中的属性值要保证和其对应的mapper接口的全类名一致;
  2. 映射文件中的SQL语句中的id要保证和mapper接口中的方法名一致;

1.2.4 实体类文件

package com.crj.pojo;
//实体类
public class User {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private String sex;
    private String email;
//    有参构造
    public User(Integer id, String username, String password, Integer age, String sex, String email) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.age = age;
        this.sex = sex;
        this.email = email;
    }
//    无参构造
    public User() {

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

    public Integer getId() {
        return id;
    }

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

    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 Integer getAge() {
        return age;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

 根据项目的路径在核心配置文件中引入映射文件:

1.3 MyBatis项目测试

SqlSession:代表Java程序和数据库之间的会话

SqlSessionFactory:是生产SqlSession对象的工厂函数,这是一种工厂模式

package com.crj.mtbatis;

import com.crj.mapper.UserMapper;
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.Test;

import java.io.IOException;
import java.io.InputStream;

public class test {
    @Test
    public void testMyBatis() throws IOException {
        //加载核心配置文件:通过核心配置文件的名字以一个字节输入流的方式
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //获取SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //获取SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
        //获取Mybatis操作数据库的会话对象SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取mapper接口实现类对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        //测试功能,增删改的返回值是受影响的函数
        int result = mapper.insertUser();
        System.out.println("result:"+result);
        
        //提交事务
        sqlSession.commit();
    }
}

sqlSession.getMapper()方法采用代理模式返回一个接口的实例化对象。

开启自动提交仅需要在openSession方法中配置autoCommit为true即可,这样就无需再手动提交事务了。

SqlSession sqlSession = sqlSessionFactory.openSession(true);

1.4 查询功能

mapper接口

/**
* 查询所有的用户信息
*/
List<User> getAllUser();

映射文件

<!--    List<User> getAllUser();-->
    <select id="getAllUser" resultType="com.crj.pojo.User">
        select * from t_user
    </select>

测试类 

 //查询所有的用户信息
    @Test
    public  void testAll() throws IOException {
        //加载核心配置文件:通过核心配置文件的名字以一个字节输入流的方式
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //获取SqlSessionFactoryBuilder对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //获取Mybatis操作数据库的会话对象SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取mapper接口实现类对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<User> list = mapper.getAllUser();
        list.forEach(user-> System.out.println(user));
    }

需要注意的是当查询的时候我们通常在映射文件中配置好resultType的属性值并将相应的实体类的全类名作为属性值,同时在声明接口的时候需要注意采用相应的数据结构。

1.5 优化:借助properties文件存放数据库连接数据

创建一个资源绑定文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456

 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-->
    <properties resource="jdbc.properties"/>
    <!--配置连接数据库的环境-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--引入映射文件-->
    <mappers>
        <mapper resource="mappers/UserMapper.xml"/>
    </mappers>
</configuration>

二、MyBatis核心配置文件模板设置和工具类封装

2.1 设置核心配置文件的模板 

打开IDEA中的setting,找到Editor下的File and Code Templates并新建一个demo模板mybatis-config.xml

 设置模板名和后缀,并将模板配置文件的内容复制在内容框中即可。

之后右键新建一个mybatis核心配置文件的模板试试:

同样的方法可以用来设置一个mybatis的映射文件

2.2 封装用来获取MyBatis连接数据库时的会话对象的工具类  

package com.crj.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;

/**
 * 该工具类封装了获取mybatis操作数据库连接时的会话对象的一个方法
 * 之后通过sqlSession这个数据库会话对象SqlSession的getMapper()方法来获取接口并自动获得该接口的实现类
 * 通过调用mapper接口中声明的方法来实现增删改的操作
 */
public class SqlSessionUtils {
    public static SqlSession getSqlSession(){
        SqlSession sqlSession = null;
        try {
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            sqlSession = sqlSessionFactory.openSession(true);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return sqlSession;
    }
}

三、MyBatis获取参数值

3.1 获取参数值的两种方式

和JDBC类似,MyBatis获取参数值的两种方式:${}和#{}

  • ${ }:本质是字符串拼接,缺点是比较复杂并且容易造成SQL注入
  • #{ }:本质是占位符赋值,推荐的使用方式是这种

3.2 MyBatis获取五种类型的参数值

3.2.1 单个字面量类型

两种方式获取单个字面量类型参数值

<select id="getUserByUserName" resultType="User">
    select * from t_user where username = #{username}
    select * from t_user where username = '${username}'
</select>

3.2.2 多个字面量参数

mapper接口方法在获取到多个参数时,Mybatis会将所有的参数放在一个map集合中并采用两种方式的键值对的形式进行存储。 

<!--    User checkLogin(String username,String password);-->
    <select id="checkLogin" resultType="User">
        select * from t_user where username = #{arg0} and password = #{arg1}
        select * from t_user where username = #{param1} and password = #{param2}
    </select>

3.2.3 手动将参数存储在一个map集合中

<!--    User checkLoginByMap(Map<String,Object> map);-->
    <select id="checkLogin" resultType="User">
        select * from t_user where username = #{username} and password = #{passsword}
    </select>
@Test
public void testCheckLoginByMap(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    Map<String,Object> map = new HashMap<>();
    map.put("username","admin");
    map.put("password","admin");
    User user = mapper.checkLoginByMap(map);
}

3.2.4 实体类参数

<!--    int insertUserByMap(User user);-->
    <insert id="insertUserByMap">
        insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
    </insert>

3.2.5 使用@param注解来命名参数

User checkLoginByParam(@Param("username") String username,@Param("password") String password);

总结

        总结一下,在这篇文章中荔枝主要记录了有关MyBatis项目环境的基本配置以及相应的模板设置,以及有关MyBatis获取参数值两种方式以及五种情况,掌握后我们就算是基本入门了。在接下来的文章中,荔枝将会继续将梳理有关MyBatis的相关知识比如动态SQL以及SpringBoot项目如何整合MyBatis框架进行开发,继续加油吧~~~

今朝已然成为过去,明日依然向往未来!我是小荔枝,在技术成长的路上与你相伴,码文不易,可以举起小爪爪点个赞哈哈哈~~~ 比心心♥~~~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值