MyBatis学习笔记总结

Posted ascto

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis学习笔记总结相关的知识,希望对你有一定的参考价值。

MyBatis

一、框架概述

1.1软件开发常用结构

三层架构包含的三层:

界面层、业务逻辑层、数据访问层

三层的职责

1.界面层(表示层,视图层):主要功能是接受用户的数据,显示请求的处理结果。使用web页面和用户交互,手机app也就是表示层的,用户在app中操作,业务逻辑在服务器端处理。

2.业务逻辑层:接收表示传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取数据。

3.数据访问层: 与数据库打交道。主要实现对数据的增、删、改、查。将存储在数据库中的数据提交给业务层,同时将业务层处理的数据保存到数据库。

三层对应的包:

界面层:controller包(servlet类)

业务逻辑层:service包(各种xxxservice类)

数据访问层:dao包(xxDao类)

三层中类的交互

用户使用界面层—>业务逻辑层---->数据访问层(持久层)—>mysql

三层对应的框架

界面层:servlet---->SpringMVC

业务逻辑层:service类----->Spring

数据访问层:Dao----->MyBatis

1.2框架概念

框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种认为,框架是可被应用开发者定制的应用骨架、模板。

简单的说,框架其实是半成品软件,就是一组组件,供你使用完成你自己的系统。从另一个角度来说框架一个舞台, 你在舞台上做表演。在框架基础上加入你要完成的功能。

框架安全的,可复用的,不断升级的软件。

框架是一个舞台,是一个模版

模版:

  1. 已经事先规定好了一些条款和内容
  2. 加入自己的东西

框架是一个模版

  1. 框架中定义好了一些功能,这些功能是可用的。
  2. 可以加入自己项目的功能,这些功能可以利用框架中写好的功能。

框架是一个半成品软件,定义好了一些基础的功能,需要加入你的功能就是完整的。

基础功能是公用的,可重复使用的,可升级的。

框架特点:

  1. 框架一般不是全能的,不可以做所有的事情。
  2. 框架一般针对于某一个领域,特长在某一个方面,比如MyBatis做数据库操作强,但是它不可以做其他的。
  3. 框架是一个软件。

1.3JDBC编程

  1. 代码比较多,开发效率低
  2. 需要关注Connection,Statement,ResultSet创建对象和销毁
  3. 对ResultSet查询结果,需要自己封装为List
  4. 重复的代码比较多
  5. 业务代码和数据库的操作混在一起

1.4MyBatis框架概述

MyBatis框架:
MyBatis本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。2013 年11月迁移到Github。
iBATIS 一词来源于“internet" 和“abatis"的组合,是一个基于Java 的持久层框架。
iBATIS提供的持久层框架包括SQL Maps和Data Access Objects ( DAOs)。当前,最新版本是MyBatis3.5.1,其发布时间是2019年4月8日。

mybatis框架
一个框架,早期叫做ibatis, 代码在github。

mybatis是MyBatis SQL Mapper Framework for Java( sql映射框架)

  1. sql mapper : sql映射
    可以把数据库表中的一行数据映射为一个 java对象。行数据可以看做是一个java对象。操作这个对象,就相当于操作表中的数据
  2. Data Access Objects (dAOs) :数据访问,对数据库执行增删改查。

MyBatis解决的主要问题

  1. 提供了创建Connection,Statement,ResultSet的能力,不用开发人员创建这些对象了。
  2. 提供了执行sql语句的能力,不用你执行sql。
  3. 提供了循环sql,把sql的结果转换为java对象,List集合的能力。
  4. 提供了关闭资源的能力

开发人员需要做的:提供sql语句。

最后:开发人员提供sql语句----MyBatis处理sql语句----开发人员得到List集合或者Java对象

总结:mybatis是一个sql映射框架,提供数据库的操作能力,增强的jdbc,使用mybatis让我们的开发人员集中精神写sql语句就可以了,不必关心connection,statement,resultset的创建、销毁、sql语句的执行。

二、MyBatis框架快速入门

2.1入门案例

2.1.1使用MyBatis的准备

到github上下载对应zip包,地址为:点击这里

2.1.2搭建MyBatis开发环境

实现步骤:
1.新建的students表。
2.加入maven的mybatis坐标、mysql驱动的坐标。
3.创建实体类,Student----用来保存表中的一行数据的。
4.创建持久层的DAO接口,定义操作数据库的方法。
5.创建一个MyBatis使用的配置文件,叫做sql映射文件:写sql语句的,一般是一个表一个sql映射文件。这个文件是xml类型文件
6.创建一个mybatis的主配置文件:一个项目就一个主配置文件。主配置文件提供了数据库的连接信息和sql映射文件的位置信息。
7.创建使用mybatis类,通过mybatis去访问数据库
pom中设置依赖
<!--mybatis依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.1</version>
    </dependency>
    <!--mysql驱动-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.23</version>
    </dependency>

创建studentDao.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="cqutlc.dao.studentDao">

    <!--
    select表示查询操作
    id:你要执行sql语句的唯一标识,mybatis会使用这个id的值,找到要执行的sql语句
    可以自定义,但是要求你使用接口方法中名称
    resultType:表示结果类型,是sql语句执行后得到的ResultSet,遍历这个ResultSet得到Java对象的类型
    值写的是类型的全限定名称
    -->
    <select id="selectStudents" resultType="cqutlc.domain.Students">
        select id,name,email,age from school.students order by id
    </select>
</mapper>

<!--
    sql映射文件:写sql语句的,mybatis会执行这些sql
    1.指定约束文件
    <!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     mybatis-3-mapper.dtd是约束文件的名称,扩展名是dtd的
    约束文件的作用:限制、检查在当前文件中出现的标签、属性必须符合mybatis的要求
    2.mapper 是当前文件的根标签,必须的。
    namespace:叫做命名空间,唯一值的,可以是自定义的字符串
               要求你使用dao的全限定名称
    3.在当前文件中,可以使用特定的标签,表示数据库的特定操作
    <select>:表示执行查询
    <update>:表示更新数据库操作
    <insert>:表示插入
    <delete>:表示删除
    

-->

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>


    <!--环境配置:数据库连接信息-->
    <environments default="mydev">
       <!--environment:一个数据库信息配置,环境
           id:一个唯一值,自定义,表示环境名称
       -->
        <environment id="mydev">
            <!--
            transactionManager:mybatis的事务类型
            type:jdbc(表示jdbc事务处理)
            -->
            <transactionManager type="JDBC"/>
            <!-- 数据源的配置,URL,用户名 密码 数据库 -->
            <!--
            dataSource表示数据源
            type:表示数据源的类型,POOLED表示使用连接数据池
            -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatisTest?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=GMT"/>
                <property name="username" value="root"/>
                <property name="password" value="131138"/>
            </dataSource>
        </environment>
        <!--在线数据库-->
        <environment id="online">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatisTest?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=GMT"/>
                <property name="username" value="root"/>
                <property name="password" value="131138"/>
            </dataSource>
        </environment>
    </environments>
    <!--sql mapper(sql映射文件)的位置-->
    <mappers>
        <!--
        一个mapper标签指定一个文件的位置
        从类路径开始的路径信息。target/class
        -->
        <mapper resource="cqutlc\\dao\\studentDao.xml"/>
    </mappers>
</configuration>
<!--
mybatis的主配置文件:主要定义了数据库的配置信息,sql映射文件的位置
    1.约束文件
        <!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
       mybatis-3-config.dtd 约束文件的名称
    2.
-->
package cqutlc;

import cqutlc.domain.Students;
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;
import java.io.InputStreamReader;
import java.util.List;

public class test {
    public static void main(String[] args) throws IOException {
        //访问mybatis读取student数据
        //1.定义mybatis主配置文件的名称,从类路径的根开始(target/class)
        String config="mybatis.xml";
        //2.读取这个config表示的文件
        InputStream in= Resources.getResourceAsStream(config);
        //3.创建了sqlSessionFactoryBuilder
        SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
        //4.创建SqlSessionFactory对象
        SqlSessionFactory factory=builder.build(in);
        //5.获取sqlSession对象,从sqlSessionFactory中获取sqlSession
        SqlSession sqlSession=factory.openSession();
        //6.【重要】指定要执行的sql语句的标识。sql映射文件中的namespace+“.”+标签的id值
        String sqlId="cqutlc.dao.studentDao"+"."+"selectStudents";
        //7.执行sql语句,通过sqlId找到语句
        List<Students> studentsList=sqlSession.selectList(sqlId);
        //8.输出结果
        studentsList.forEach(System.out::println);
        //9.关闭sqlSession对象
        sqlSession.close();

    }
}

输出:

在这里插入图片描述

2.1.3insert操作

package cqutlc;

import cqutlc.domain.Students;
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;
import java.util.List;

public class testMybatis {
    //测试代码
    @Test
    public void testMybatis() throws IOException {
        //访问mybatis读取student数据
        //1.定义mybatis主配置文件的名称,从类路径的根开始(target/class)
        String config="mybatis.xml";
        //2.读取这个config表示的文件
        InputStream in= Resources.getResourceAsStream(config);
        //3.创建了sqlSessionFactoryBuilder
        SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
        //4.创建SqlSessionFactory对象
        SqlSessionFactory factory=builder.build(in);
        //5.获取sqlSession对象,从sqlSessionFactory中获取sqlSession
        SqlSession sqlSession=factory.openSession();
        //6.【重要】指定要执行的sql语句的标识。sql映射文件中的namespace+“.”+标签的id值
        String sqlId="cqutlc.dao.studentDao"+"."+"insertStudent";
        //7.执行sql语句,通过sqlId找到语句
        Students students=new Students(1003,"张飞","1231@qq.com",19);
        int num=sqlSession.insert(sqlId,students);
        sqlSession.commit();
        //8.输出结果
        System.out.println("执行insert结果:"+num);
        //9.关闭sqlSession对象
        sqlSession.close();
    }

}

2.2MyBatis对象分析

主要类的介绍

1.Resources:mybatis中的一个类,负责读取主配置文件

InputStream in= Resources.getResourceAsStream(config);

2.SqlSessionFactoryBuilder:创建SqlSessionFactory对象

SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder(); SqlSessionFactory factory=builder.build(in);

3.SqlSessionFactory:重量级对象,程序创建一个这样的对象耗时较长,使用资源较多。在整个项目中,有一个就够了。

SqlSessionFactory作用:获取SqlSession对象,SqlSession sqlSession=factory.openSession();

4.SqlSession

SqlSession接口:定义了操作数据的方法,delete(),commit(),update()等

使用要求:SqlSession对象不是线程安全的,需要在方法内部使用,在执行sql语句之前,使用openSession获取SqlSession

在执行完sql语句之后,需要关闭它,执行SqlSession.close(),这样才可以保证它的使用是安全的。

三、MyBatis框架Dao代理

3.1Dao代理实现数据库操作

传统Dao实现select操作

studentDao.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="cqutlc.dao.studentDao">

    <select id="selectStudents" resultType="cqutlc.domain.Student">
    select id,name,email,age from school.students order by id
    </select>

</mapper>

studentDao

package cqutlc.dao;

import cqutlc.domain.Student;

import java.util.List;

public interface studentDao {
    List<Student> selectStudents();

}

studentDaoImpl

package cqutlc.dao.impl;

import cqutlc.MyBatisUtils;
import cqutlc.dao.studentDao;
import cqutlc.domain.Student;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class studentDaoImpl implements studentDao {

    @Override
    public List<Student> selectStudents() {
        //获取sqlSession对象
        SqlSession sqlSession= MyBatisUtils.getSqlSession();
        String sqlId="cqutlc.dao.studentDao.selectStudents";
        //执行sql语句
        List<Student> students= sqlSession.selectList(sqlId);
        students.forEach(student -> System.out.println());
        sqlSession.close();
        return students;
    }
}

测试类

package cqutlc;

import cqutlc.dao.impl.studentDaoImpl;
import cqutlc.dao.studentDao;
import cqutlc.domain.Student;
import org.junit.Test;

import java.util.List;

public class TestMybaits {
    @Test
    public void testStudent(){
        studentDao dao=new studentDaoImpl();
        List<Student> studentList=dao.selectStudents();
        studentList.forEach(student -> System.out.println());
    }

}

利用动态代理实现(重点)

mybatis根据dao的方法调用,获取执行sql语句的信息。mybatis根据你的dao接口,创建出一个dao接口的实现类,并创建这个类的对象,完成sqlSession调用方法,访问数据库。

package cqutlc;
import cqutlc.dao.studentDao;
import cqutlc.domain.Student;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;

public class TestMybaits {
    @Test
    public void testSelectStudent(){
        /*
        * 使用动态代理的机制,使用SqlSession.getMapper(dao接口)
        * getMapper能够获取dao接口对应的实现类对象。
        * */

        SqlSession sqlSession=MyBatisUtils.getSqlSession();//StudentDao.xml生效
        studentDao dao=sqlSession.getMapper(studentDao.class);//studentDao接口与sqlSession语句关联
        //调用dao方法,执行数据库操作
        List<Student> students=dao.selectStudents();//执行xml中selectStudent方法
        students.forEach(student -> System.out.println());
    }
}

3.2深入理解传入参数

传入参数:从Java代码中把数据传入到mapper文件的sql语句中。

parameterType:写在mapper文件中的一个属性,它是表示dao接口中方法的参数的数据类型。(不是强制要写,因为mybatis通过反射机制能够发现接口参数的数据类型)

​ ps:#{}=?(没有sql注入风险)

多个参数

1.@Param

语法:

xxx(@Param("myname") String name,Integer age)

mapper文件对应写法

<select>
	select * from student where name=#{myname}
</select>

2.传入的参数是一个对象类型

语法:#{属性名,javaType=类型名称,jdbcType=数据类型}

简化方式 #{属性名}

3.按位置

语法:#{arg位置}

#和$的区别

#:占位符,告诉mybatis使用实际的参数值代替。(不会存在注入问题,用?替代了)

: 字 符 串 替 换 , 告 诉 m y b a t i s 使 用 :字符串替换,告诉mybatis使用 mybatis使包含的“字符串”替换所在位置。(存在注入风险,因为直接填入了,没有用?代替)

$一般用于替换列名 order by ${xxx}

3.3封装MyBatis输出结果

resultType

结果类型,指sql语句执行完后,数据转为的Java对象(类型任意)。

处理方式:

1.mybatis执行sql语句,然后mybatis调用类的无参构造方法,创建对象

2.mybatis把ResultSet指定列值付给同名的属性。

当然也可以返回简单类型,如:int。(全限定名称或者别名都可以,最好用全限定名称:java.lang.Integer)

定义自定义类型的别名

方法一:

1.在mybatis主配置文件中定义,使用 <typeAlians>

2.可以在resultType中使用自定义别名。

方法二:

<package>name是包名,这个包中的所有类,类名就是别名(类名不区分大小写)

模糊like

<!--第一种like,Java中指定like的内容-->
    <select id="selectLikeOne" resultType="cqutlc.domain.Student">
        select id,name,email,age from school.students where name like  #{name}
    </select>
@Test
    public void testSelectLikeOne(){
        SqlSession sqlSession=MyBatisUtils.getSqlSession();
        studentDao dao=sqlSession.getMapper(studentDao.class);
        String name="%李%";
        List<Student> students=dao.selectLikeOne(name);
        students.forEach(student -> System.out.println());
        sqlSession.close();
    }

四、MyBatis框架动态SQL

动态sql:sql的内容是变化的,可以根据条件获取到不同的sql语句。主要是where的部分发生变化。

动态sql的实现使用的是mybatis提供的各种标签。

4.1动态SQL之 <if>

语法

<if test="判断Java对象的属性值">

部分sql语句

</if>

对于该标签的执行,当test的值为true时,会将其包含的SQL片断拼接到其所在的sql语句中。

<select id="selectStudentIf" resultType="cqutlc.domain.Student">
        select id,name,email,age from school.students
        where
        <if test="name!=null and name!='' ">
            name = #{name}
        </if>
        <if test="age>0">
            and age > #{age}
        </if>
    </select>
@Test
    public void testSelectStudentIf()以上是关于MyBatis学习笔记总结的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis 学习笔记总结

mybatis学习日志二

Mybatis学习笔记:动态SQL

MyBatis学习笔记总结

MyBatis学习笔记总结

mybatis学习笔记(11)-多对多查询