介绍

mybatis是基于JDBC的框架,简单来说就是别人把JDBC封装好,你直接导入这个mybatis依赖就可以不用JDBC那一套操作而是换成mybatis规定的操作来操作数据库

教程项目前提概括

以下教程中所用的项目都是在IDEA平台的Maven项目

第一个mybatis项目

  • 首先,项目结构如图所示

在这里插入图片描述

  • mybatis的使用步骤
    1、在maven中导入mybatis需要的依赖,有以下几个(我这里是先建立了一个父maven项目,所以我在父pom中导入依赖后,在子工程中也能用这个依赖,这是maven的知识)
<!--mybatis依赖-->
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>

        <!--(mysql连接类)jdbc依赖,mybatis仍然需要用到jdbc,只是不需要我们手动配置jdbc-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>

主要是两个依赖,mybatis和mysql-connector

2、在resource目录下新建一个mybatis的核心配置文件,我这里即mybatisconfig.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>
<properties resource="my.properties">

</properties>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--注册mapper(映射器)-->
    <mappers>
        <mapper resource="config/Studentconfig.xml"/>
    </mappers>

</configuration>

这边可以看到,environments下的environment标签中,property标签下的value使用的占位符引用的,因为这边我引用了外部的properties,如果新手不会用外部properties可以直接在property的value中直接写,这个外部引用也是后面的一个知识点,这边算是先带着用了

下面是我的properties文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=root

这里的参数写你们自己的,用过JDBC的应该知道这些参数什么意思

3、到这里mybatis的核心配置类已经写完,那有了这个核心配置类,我们就可以去得到sql语句的执行对象,怎么得到我马上讲,接下来的操作可以类比JDBC中的connection和statement

以下这个类用于生成执行sql的对象

package MybatisUtils;

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 GetSqlsession {
    private static InputStream inputStream;

	//这个方法生成一个生产Sqlsession的工厂,即SqlSessionFactory
    public static SqlSessionFactory createfactory() {
		
        {
            try {
                inputStream = Resources.getResourceAsStream("mybatisconfig.xml");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过把这个工厂return出来,以便后续通过这个工厂获得SqlSession对象
        return sqlSessionFactory;
    }

	//这个方法获得SqlSession对象
    public static SqlSession getsqlsession(){
        return createfactory().openSession();
    }


}

到此,SqlSession对象获取完毕,我们后续的所有操作都依靠这个SqlSession,它相当于JDBC中的statement,你们可以这么理解哈

4、接下我们肯定要去使用这个SqlSession,那么我们先来创建一个实体类,
上代码

package pojo;

public class Student {
    private int id;
    private String stname;
    private String sex;
    private String classs;
    private String telphone;

    public Student() {
    }

    public Student(int id, String stname, String sex, String classs, String telphone) {
        this.id = id;
        this.stname = stname;
        this.sex = sex;
        this.classs = classs;
        this.telphone = telphone;
    }

    public int getId() {
        return id;
    }

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

    public String getStname() {
        return stname;
    }

    public void setStname(String stname) {
        this.stname = stname;
    }

    public String getSex() {
        return sex;
    }

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

    public String getClasss() {
        return classs;
    }

    public void setClasss(String classs) {
        this.classs = classs;
    }

    public String getTelphone() {
        return telphone;
    }

    public void setTelphone(String telphone) {
        this.telphone = telphone;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + stname + '\'' +
                ", sex='" + sex + '\'' +
                ", classs='" + classs + '\'' +
                ", telphone='" + telphone + '\'' +
                '}';
    }
}

再来看一下数据库中怎么定义的
在这里插入图片描述
以上是数据库视角

建这个实体类是为了我们等下在写接口的方法的时候,返回类型就是这个实体类,这边再补充以下后面的内容,这个实体类中的get,set,toString等方法,可以使用插件进行注解写入,这个插件是lombok,在IDEA插件中下载,然后再在父pom中导入lombok的依赖即可,用了这个依赖只需要在实体类前面使用以下三个注解

@Data //无参构造,get,set,tostring,hashcode,equals
@NoArgsConstructor//无参构造
@AllArgsConstructor//有参构造,定义后无参会消失,还需要加

这样就不需要写get,set等方法了

5、实体类写完后,我们来写接口,上代码

package Dao;

import pojo.Student;

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

public interface StudentDao {
    //查询全部用户
    List<Student> getstudentinfo();

    //根据id查询用户
    Student getstudentbyid(int id);

    List<Student> getstudentbyid2(HashMap<String, Object> map);



    //增加用户
    int addUser(Student student);

    //万能Map
    int AddStudent2(HashMap<String, Object> map);

    //修改用户
    int updateStudent(Student student);

    //删除用户
    int deleteStudent(int id);


}

可以看见,接口中只要定义简单的方法和返回值类型
这边我定义了好几个方法,新手一开始只要第一个方法即可

6、定义好接口后,接下来开始写接口对应的.xml文件(这里即Studentconfig.xml),mybatis就是通过mapper来调用接口中的方法的,以下是这个接口对应的配置文件

<?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="Dao.StudentDao">
    <select id="getstudentinfo" resultType="pojo.Student">
       select  * from student
    </select>

<!--    <select id="getstudentbyid" resultType="pojo.Student" parameterType="int">-->
<!--        select * from student where id = #{id}-->
<!--    </select>-->

<!--    <insert id="addUser"  parameterType="pojo.Student" >-->
<!--        insert into student values(#{id},#{name},#{sex},#{classs},#{telphone})-->
<!--    </insert>-->

<!--    <update id="updateStudent" parameterType="pojo.Student">-->
<!--        update student set stname  =#{name},classs=#{classs}  where id =#{id};-->
<!--    </update>-->

<!--    <delete id="deleteStudent" parameterType="int">-->
<!--        delete from student where id =#{id}-->
<!--    </delete>-->

<!--    <insert id="AddStudent2" parameterType="map">-->
<!--        insert into student values(#{stid},#{stname},#{stsex},#{stclasss},#{sttelphone})-->
<!--    </insert>-->

<!--    <select id="getstudentbyid2" parameterType="map" resultType="pojo.Student">-->
<!--        select * from student where  stname=#{name}  and  sex=#{sex}-->
<!--    </select>-->

</mapper>

因为我在接口中定义了较多方法,这里讲解部分我先把除第一个方法以外的方法对应的sql语句注释

解释一下这个文件,mapper标签中,命名空间(namespace)需要对应你的接口名,使用.的方法引入,这一步即绑定接口

mapper中有很多子标签,主要用的就是增删改查,对应insert,delete,update,select标签

这里只用了select,select的id需要对应所绑定接口中的方法名,举例来说,我这个select绑定了Dao包下的StudentDao接口,id="getstudentinfo"对应了StudentDao接口中的getstudentinfo()方法

resultType表示返回类型,对应StudentDao接口中的getstudentinfo()方法的返回值类型是一个带泛型的List,那这个resultType就要等于这个泛型,即先前定义的实体类Student,当然,要根据路径写

如果你在接口中定义的方法需要传参数的话,select标签中还需要定义一个
parameterType,即参数类型

到此接口对应的mapper配置完毕

7、接下来要将刚才写的这个mapper注册到mybatis的核心配置文件中
即在mybatisconfig.xml中进行注册

在这里插入图片描述
8、在父pom中配置一下build标签,因为如果不配置,在项目build后接口对应的mapper文件(即上面的Studentconfig.xml)不会被放入target文件夹,那mybatis就扫描不到这个文件就报错了,所以在父pom中加入一下代码

    <!--使打包时能一起打包配置文件-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>

            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>

        </resources>
    </build>

至此,准备工作完毕,接下来开始测试

9、开始测试
建立入口函数
这里你们只要看test函数,因为别的我没配.xml文件,你要调用的话自己配.xml文件

package Main;

import Dao.StudentDao;
import MybatisUtils.GetSqlsession;
import org.apache.ibatis.session.SqlSession;
import pojo.Student;

import java.util.HashMap;
import java.util.List;


public class Main {
    public static void main(String[] args) {
        test();
//        test2();
//        addStudent();
//        updateStudent();
//        delete();
//        addStudent2();
//        select2();
    }


    private static void test(){
     //通过GetSqlsession直接.getsqlsession这个静态方法获得SqlSession对象
        SqlSession sqlsession = GetSqlsession.getsqlsession();
       //通过SqlSession的.getMapper方法,传入你接口的class获得接口,这里是java的反射机制
        StudentDao studentdao = sqlsession.getMapper(StudentDao.class);
        //通过接口类反射得到的接口对象studentdao直接调用其内部的方法
        List<Student> students = studentdao.getstudentinfo();
        //遍历输出这个List
        for (Student student : students) {
            System.out.println(student);
        }
        //切记!!!用完一定要把sqlsession对象关闭,不然会造成资源占用
        sqlsession.close();

    }
    
    //以下不要看,和本讲解无关

    private static void test2(){
        SqlSession sqlSession=GetSqlsession.getsqlsession();
        StudentDao studentdao = sqlSession.getMapper(StudentDao.class);

        Student getstudentbyid = studentdao.getstudentbyid(5);
        System.out.println(getstudentbyid);
        sqlSession.close();
    }

    private static void addStudent(){
        SqlSession sqlSession=GetSqlsession.getsqlsession();
        StudentDao studentdao = sqlSession.getMapper(StudentDao.class);
        studentdao.addUser(new Student(6,"小黑","男","大一","18888888888"));
//        增删改必需要提交事务
        sqlSession.commit();
        sqlSession.close();
    }

    private static void updateStudent(){
        SqlSession sqlSession=GetSqlsession.getsqlsession();
        StudentDao studentdao = sqlSession.getMapper(StudentDao.class);
        studentdao.updateStudent(new Student(6,"我笑了","男","大大大","18888888888"));

        //        增删改必需要提交事务
        sqlSession.commit();
        sqlSession.close();
    }

    private static void delete(){
        SqlSession sqlSession=GetSqlsession.getsqlsession();
        StudentDao studentdao = sqlSession.getMapper(StudentDao.class);
        studentdao.deleteStudent(6);
        //        增删改必需要提交事务
        sqlSession.commit();
        sqlSession.close();
    }

    private static void addStudent2(){
        SqlSession sqlSession=GetSqlsession.getsqlsession();
        StudentDao studentdao = sqlSession.getMapper(StudentDao.class);
        HashMap<String,Object> map=new HashMap<>();
        //传递map的key
        map.put("stid",7);
        map.put("stname","测试");
        map.put("stsex","女");
        map.put("stclasss","小");
        map.put("sttelphone","44444444444");

        studentdao.AddStudent2(map);
//        增删改必需要提交事务
        sqlSession.commit();
        sqlSession.close();
    }

    private static void select2(){
        SqlSession sqlSession=GetSqlsession.getsqlsession();
        StudentDao studentdao = sqlSession.getMapper(StudentDao.class);

        HashMap<String,Object> map=new HashMap<>();
        map.put("sex","男");
        map.put("name","小灰");
        List<Student> list = studentdao.getstudentbyid2(map);
        for (Student student : list) {
            System.out.println(student);
        }
        sqlSession.close();
    }


}

结果:
在这里插入图片描述

以上完成了简单的查询操作

下面讲一些注意点,每个注意点展开其实都是一个大的知识点

  1. 如果实体类的属性和数据库中字段名不对应,那么在定义mapper时需要进行结果集映射

举个例子:
在这里插入图片描述
字段不对应的情况,只要设置resultMap=“map名”
然后在mapper内部再定义一个resultMap,id对应为"map名",返回类型还是实体类,在result内部定义映射方式,property为实体类的属性名,column为数据库中的字段名
不这样设置的话,查出来的值为null
当然我这个例子是外键关联表的查询,拿来讲解一下实体类属性名和数据库字段名不对应的情况

  1. 如果是增删改操作,sqlsession执行完后需要提交事务,commit一下才能更新数据库中字段
  2. 一些sql的操作像是分页查询,模糊查询都是在sql语句中改
  3. 如果要进行日志输出那需要导log4j类似这样的依赖,然后就和安卓里一样log.d,类比一下就是logger.d(ebug)

到此简单使用Mybatis的教程就结束了,非常的新手向,应该能看的懂

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐