Mybatis学习一

一.Mybatis与其他持久层框架的对比:

从最基本的数据库连接框架JDBC说起,JDBC大致五步:编写sql、预编译、设置参数、执行sql、封装结果。JDBC的特点就是功能简单,但sql语句编写在java代码里,是一种硬编码高耦合的方式。
对于Hibernte来说,相当于把这5步进行了自动化,消除sql,对于开发者来说相当于黑箱操作,不需要学会JDBC以及Sql操作,只需要把javaBean对象和数据库表的关系处理好就行,但是省心的同时,所有大型项目最后都要牵扯定制Sql,优化Sql,最终要把Sql交给开发人员来写,不要让框架自动生成Sql
所以综合起来,你希望尽可能手动的去实现Sql的部分,又可以利用框架自动化的特点实现其他部分,Mybatis就是这样,将编写Sql这一步提取出来以XML配置文件的形式让开发者自己配置,其他的4步自动完成。特点:Sql与Java代码分离,Sql是开发人员控制,感觉算个半自动框架吧。

二.Mybatis创建步骤:

1.通过maven选择quickstart模板直接创建一个模板,会自带一个pom.xml文件
2.在pom.xml文件中引入两个依赖,一个MySql的,一个Mybatis的

<dependency>    
  <groupId>mysql</groupId>    
  <artifactId>mysql-connector-java</artifactId>    
  <version>5.1.32</version>    
</dependency> 
<!--mybatis配置-->    
<dependency>    
     <groupId>org.mybatis</groupId>    
     <artifactId>mybatis</artifactId>    
     <version>3.4.1</version>    
</dependency>  

3.创建全局配置文件:在main包下创建一个resources包,并且右键选择Mark Directory as选项中的Resources Root选项,设置好后在此包下创建一个Mybatis-config.xml文件
4.配置全局配置文件:

<?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"/> //mysql中的存储引擎
                <property name="url" value="jdbc:mysql://localhost:3306/test"/> //mysql中的url
                <property name="username" value="root"/> //用户名
                <property name="password" value="123456"/> //密码
            </dataSource>
        </environment>
    </environments>

</configuration>

官网上的示例标签
补充一个知识点:XML文件为可扩展性标记语言,XML是数据交换的公共语言,不同软件,不同操作系统都可以通过加载XML来进行数据的交换,在我们用到的Mybatis框架中,XML文件是通过识别各种各样的标签来进行的,但是前提是标签头你得先指定好,它才能去寻找相应的标签,你可以从Mybatis官网的示例文件中找到这个标签即mybatis-3-config.dtd
5.创建POJO类(即普通的java对象里面包含一些get和set方法),在com包的最底层即与maven加载的APP类在同一层创建此pojo实体类,里面包含数据库字段(此时字段声明均用其包装类类型),以及get和set方法,有必要的话还要包含toString和其他方法
6.定义mapper接口文件,在此层次上创建刚才POJO类的mapper接口,命名就为XxxMapper,里面写你的业务需求方法,比如通过学号来查询学生

public interface StudentMapper {
    /**
     * 通过SID查询数据实体
     * @param sid
     * @return
     */
    public Student selectStudentByID(int sid);
}

7.配置Mapper文件:在刚才第三步的Resources包下创建一个mapper包,其下再创建一个StudentMapper.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 namespace="com.tulun.MybatisDemo.StudentMapper">
    <!--查询标签:select-->
    <select id="selectStudentByID" resultType="com.tulun.MybatisDemo.Student">
        select * from Student where SID = #{sid}
    </select>
</mapper>

这里的重点在于此XML的文件名必须和第6步中的POJO类的接口名保持一致,select id后面跟的字段必须跟POJO类的接口中的方法名保持一致,返回类型resultType即为POJO的实体类,这里用路径代替,然后就可以把你的查询SQl语句写在这个select标签中了,这里的SQL语句要使用占位符的形式
8.将Mapper配置文件引入到全局配置文件中,即修改全局配置文件Mybatis-config.xml
增加一个标签,引入其路径

 <!--配置映射-->
    <mappers>
        <mapper resource="mapper/StudentMapper.xml"/>
    </mappers>

9.创建执行类去执行操作

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 MybatisTLDemo {
    public static void main(String[] args) throws IOException {
        //mybatis配置文件
        String resource = "mybatis-config.xml";
        //通过mybatis提供的Resources类来得到配置文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //创建会话工厂,传输mybatis配置文件信息
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过工厂得到SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //通过反射机制来获取对应mapper实例
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        //调用mapper实例下方法
        Student student = mapper.selectStudentByID(1);
        System.out.println(student);
    }
}

三.日志引入

1.先引入日志的依赖,当然是在最初始的通过maven快速加载出的pom.xml文件中

<!--log4j日志文件-->  
<dependency>  
    <groupId>log4j</groupId>  
    <artifactId>log4j</artifactId>  
    <version>1.2.17</version>  
</dependency>  

2.创建resources包下创建名为log4j.properties的普通文件(非XML)

## debug 级别  
log4j.rootLogger=DEBUG,Console  
log4j.appender.Console=org.apache.log4j.ConsoleAppender  
log4j.appender.Console.Target=System.out  
log4j.appender.Console.layout = org.apache.log4j.PatternLayout  
log4j.appender.Console.layout.ConversionPattern=%d{yyyy-MM-dd-HH\:mm\:ss,SSS} [%t]  [%c] [%p] - %m%n  
log4j.logger.com.mybatis=DEBUG  /  
  
##输出sql 语句  
log4j.logger.java.sql.Connection=DEBUG  
log4j.logger.java.sql.Statement=DEBUG  
log4j.logger.java.sql.PreparedStatement=DEBUG 

这里的示例是debug级别的,当然还有其他级别的,这样的话再运行执行操作就会打印出相关的时间,哪个类用到了哪些配置文件等等
eg:

2020-05-10-09:18:42,188 [main]  [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@6adede5]
2020-05-10-09:18:42,191 [main]  [com.tulun.MybatisDemo.StudentMapper.selectStudentByID] [DEBUG] - ==>  Preparing: select * from Student where SID = ? 
2020-05-10-09:18:42,351 [main]  [com.tulun.MybatisDemo.StudentMapper.selectStudentByID] [DEBUG] - ==> Parameters: 1(Integer)
2020-05-10-09:18:42,372 [main]  [com.tulun.MybatisDemo.StudentMapper.selectStudentByID] [DEBUG] - <==      Total: 1

四.全局配置文件:mybatis-config.xml详解

所有介绍的标签都得写在根标签内

1.properties:读取外部资源,即用来存放数据的源信息

    <properties resource="db.properties">
        <property name="passwd" value="root"/>
    </properties>

其中有两个属性,resource和name,resource为类路径下的的资源,url为网络路径或者磁盘路径下的资源,类似于数据库的url,数据库的用户名密码等等都是可变的,这里的db,properties是在resources包下的这个文件,里面按行写上:
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/test"
jdbc.username = root
jdbc.passwd = 123456 都直接写就行,不用以字符串的形式
但是原本的这些选项就不能再固定写死了,以${ }里面写参数的形式给出

<!--数据源配置-->
    <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.usename}"/>
                <property name="password" value="${jdbc.passwd}"/>
            </dataSource>
        </environment>
    </environments>

在这里插入图片描述
在执行函数中这样写也可以读取到配置信息:
在这里插入图片描述
如果属性不至一个地方进行配置,mybatis将按照以下的顺序来加载:
• 首先读取在properties元素中指定的属性
• 然后根据properties元素中的resource/url属性指定的文件内容,并覆盖之前读取的同名的属性
• 最后读取作为方法参数传递的属性,并覆盖之前读取的同名属性
通过方法参数传递的属性具有最高优先级,resource或URL加载的属性次之,最低级的是properties元素体内的属性

2.setting:全局的参数配置

用的比较多的三个,还有很多,可以在官方文档上查看:
在这里插入图片描述
cacheEnable是二级缓存开关
LazeLoadingEnable和aggressiveLazyLoading配置懒加载的开关配置(延时加载)

    <!--全局参数配置-->
    <settings>
        <!--开启二级缓存的开关-->
        <setting name="cacheEnable" value="true"/>
        <setting name="lazyLoadingEnable" value="true"/>
    </settings>

3.typeAliases:类型别名:其实就是取别名,主要是针对xml配置文件的

  <!--类型别名-->
    <typeAliases>
        <!--单个别名定义 type:pojo类的路径(全限定名) alias:别名的名称-->
        <typeAlias type="com.tulun.MybatisDemo.Student" alias="student"/>

        <!--批量的别名定义 name:指定的包名,将包下边的所有pojo类取别名,别名为类名(首字母大小写都行)-->
        <package name="com.tulun.pojo"/>
    </typeAliases>

即类似于select标签中的resultType就可以去替换而不用去引很长的路径
在mapper.xml 文件中,定义了很多的Statement,Statement需要parameterType指定输入参数类型,需要resultType指定输出参数类型,如果指定类型为全路径,开发不方便,可以针对parameterType和resultType指定的类型取别名,别名在配置文件(mybatis-config.xml)中配置typeAliases没在mapper.xml文件中使用

4.typeHandlers:类型处理器

数据库中的字符为varchar,Java代码中的字符为String,当然也有可能数据库中有int对应Java代码中的int,但当涉及到类型需要转换时,必须重写类型处理器
在这里插入图片描述

5.plugins:插件

可以对某一节点进行拦截调用,Spring AOC中会用到,再探讨底层原理

6.environments:环境配置

(因为当跟Spring整合后,环境配置可能最终是放在Spring中的,所以Mybatis大部分情况不需要去配置环境)
代码需要在不同的环境上跑,比如开发的时候在某台机子上跑,测试的时候又在其他机子上跑进行测试,线上又是其他环境,这些都需要不同的配置,你可以自己配置多个环境(不同的环境id,url,用户名密码都不同),SQLSessionFactory实例会去选取其中一种环境去运行

<!--数据源配置-->
    <environments default="test">
        <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/test"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${passwd}"/>
            </dataSource>
        </environment>

        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${passwd}"/>
            </dataSource>
        </environment>

        <environment id="online">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${passwd}"/>
            </dataSource>
        </environment>
    </environments>

默认使用的环境 ID(比如:default=“development”)。
每个 environment 元素定义的环境 ID(比如:id=“development”)。
事务管理器的配置(比如:type=“JDBC”)。
数据源的配置(比如:type=“POOLED”)。

7.Mappers:映射器

定义的Sql都在XML文件中,此标签可以告诉Mybatis要去哪里寻找Sql语句,一共又三种映射方式

    <!--配置映射 三种映射方式-->
    <mappers>
        <!--resource方式:单个mapper映射,xml和接口可以不再一个目录下
        在StudentMapper.xml中定义namespace为mapper接口的地址,映射文件通过
        namespace来找到mapper接口文件-->
        <mapper resource="mapper/StudentMapper.xml"/>
        <mapper resource="mapper/UsertMapper.xml"/>

        <!--class方式:单个mapper映射,指定mapper接口的地址遵循规则
        将mapper.xml和mapper.java放在同一个目录下,且文件名相同
        -->
        <mapper class="com.tulun.MybatisDemo.StudentMapper"/>
        <mapper class="com.tulun.MybatisDemo.UserMapper"/>
        
        <!--package方式:批量的mapper映射遵循的规则:将mapper.xml和mapper.java 放在
        同一个目录下,且文件名相同-->
        <package name="com.tulun.MybatisDemo"/>
    </mappers>

五.Mapper XML 文件详解

即POJO实体类对应的Mapper.xml文件
首先先补充一下在XML文件中都是以标签的形式编码的,在最外层的标签一个代表开始,一个以斜杠结尾的表示结束,倘若你这个标签本身就很简单那你可以直接写成写成比如这种形式:
Mapper文件最外层的根标签为mapper,其中有一个属性为namespace,一般为其全限定名(即路径写法),因为resources包下对应的mapper包可能不止一个POJO实体对应的mapper配置文件,通过命名空间的全限定路径可以分别找到各自对应的接口,Mapper XML文件主要用的就是其增删改查标签:

1.select标签

查询数据
其中有两个必须具有的属性,一个是id,一个是resultType
id为当前命名空间下Statement的唯一标识,而Statement即JDBC中的执行SQL语句的对象//这里先放下等搞清楚各个类与XML文件的执行顺序后回来写清楚这里是怎么样对应的
resultType:将结果集映射为Java的对象,该属性值为映射对象的全限定名或者是别名(和resultMap二选一)
resultType和resultMap的区别:
这两个只能二选一使用,不能全部一起使用,当POJO实体类中声明的属性和对应数据库表中的属性字段不一致时,如果用resultType就会映射失败,就要用resultMap进行显性映射,感觉上会很麻烦

<resultMap id="studentMap" type=com.tulun.MybatisDemo.Student>
<!--
colum为数据库表的属性字段
property为POJO实体类对应的属性名
除了第一行写为id,其他都写为result
-->
    <id column="SID" property="SID"/>
    <result column="Sname" property="name"/>
    <result column="Ssex" property="Ssex"/>
    <result column="Sage" property="Sage"/>
    </resultMap>
    <!--查询标签:select-->
    <select id="selectStudentByID" resultType="studentMap">
        select * from Student where SID = #{sid}
    </select>

2.insert 标签

添加数据
属性:
id属性(必须),唯一标识
parameterType(可以忽略)传入参数类型(入参还有parameterMap)
useGeneratedKeys(可以忽略)开启主键回写

<insert id="insertStudent" useGeneratedKeys="true" parameterType="com.tulun.Mubatis.Demostudent">
        insert into Student(SID,Sname,Sage,Ssex) values(#{SID},#{Sname},#{Sage},#{Ssex})
    </insert>

3.update 标签

修改数据
update的常用属性:
id属性(必须) 唯一标识
resultType和parameterType(可以忽略)

4.delete标签

删除数据
常用属性:
id属性(必须) 唯一标识
resultType和parameterType(可以忽略)

六.Jnuit测试介绍(为XML配置做铺垫)

Junit是用于编写和运行可重复的自动化测试的开源框架

Junit的依赖:

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

1.生成测试类

在Idea下,在需要测试类的当前的窗口,直接快捷点:ctrl+shfit+t ,选择create New Test
在这里插入图片描述

2.选择要测试的类

在这里插入图片描述

3.生成测试类

在这里插入图片描述

 private SqlSessionFactory sqlSessionFactory;

    @Before
    public void before() {
        //mybatis配置文件
        String resource = "mybatis-config.xml";
        //通过mybatis提供的Resources类来得到配置文件流
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //创建会话工厂,传输mybatis配置文件信息
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

    }


    @Test
    public void selectStudentByID() {
       //通过工厂得到SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //通过反射机制来获取对应mapper实例
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        //调用mapper实例下方法
        Student student = mapper.selectStudentByID(1);

        System.out.println(student);
        sqlSession.close();

    }

    @Test
    public void insertStudent() {
       //通过工厂得到SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //通过反射机制来获取对应mapper实例
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);


        //插入数据
        Student student1 = new Student();
        student1.setSID(10);
        student1.setname("tulun1");
        student1.setSage(11);
        student1.setSsex("nan");
        mapper.insertStudent(student1);

        //事务提交
        sqlSession.commit();

        //关闭资源

        sqlSession.close();
    }

在这里插入图片描述

4.常用的注解

@Before

当在测试方法之前需要执行一些操作可以放在@Before注解中
读取配置信息

@Test

@Test注解的会被当做测试用例,Junit每一次会创建一个新的测试实例,调用@Test注解方法

@After

After 注解是在Test注解调用之后才会进行执行,一般是进行资源的回收
虽说是注解但用法跟重写方法是一样的,只是最后先执行Before方法,其次Test方法,最后After方法
说到底,Junit还是用来测试我们所写的Sql语句的,我们不必运行整个程序,让所有对象都生成,只需要提取出来单个模块放到Test中去测试
在这里插入图片描述
main包中放我们自己的代码,所有的测试代码放到test中

Mybatis的使用方法

mybatis主要有两种使用方式,一种XML配置的形式,就是上面之前的笔记。另外一种是注解的形式,注解的形式使用起来会更简单,但不便于理解其底层原理。
以具体的业务需求场景为例:通过学号查询学生信息
首先我们需要在pojo下做好实体类,也就是与数据库表对应的实体,里面有set和get方法,在dao下做好该实体类的接口,里面声明好我们的业务方法

public interface StudentMapper1 {
    /**
     * 通过SID查询用户信息
     * @param sid
     * @return
     */
    public Student getStudentByID(int sid);
}

接下来把我们的业务sql: select * from Student where SID = ? 封装到XML文件中
创建mapper.xml文件(在resources包下的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="com.tulun.dao.StudentMapper1">
    <!--select * from Student where SID = ?-->
    <!--
    select查询操作标签
    id属性:对应接口中的方法名,必填项,且在同一个namespace下,id不能重复
    #{XXX}:占位符,里面添加的是方法中的参数名
    parameterType属性:指定入参类型
    resultType:执行返回参数类型,指定全路径名
    resultMap属性:指定返回参数类型
    -->
    <select id="getStudentByID" parameterType="java.lang.Integer" resultType="com.tulun.pojo.Student">
        select * from Student where SID = #{sid}
    </select>
</mapper

XML文件外层要有约束,内层要有命名空间,把sql放入select标签中,id即对应的业务方法名,paramterType对应参数类型,不过这里要以路径形式给出包装类型,resultType即返回类型Student同样以路径形式给出。
之后在全局配置文件中给出此配置文件的路径(即最下面的以config结尾的那个XML文件)

    <mappers>
        <mapper resource="mapper/StudentMapper1.xml"/>
    </mappers>

用Junit测试我们的业务接口,直接在Test包下的dao包下面创建Test测试类,将会话工厂之类的放在Before标签下,

public class StudentMapper1Test {
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void before() {
        //mybatis配置文件
        String resource = "mybatis-config.xml";
        //通过mybatis提供的Resources类来得到配置文件流
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //创建会话工厂,传输mybatis配置文件信息
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

    }

    @Test
    public void getStudentByID() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //通过接口产生代理类
        StudentMapper1 mapper = sqlSession.getMapper(StudentMapper1.class);
        Student student = mapper.getStudentByID(2);
        System.out.println(student);
    }
}

在这里插入图片描述
mapper.XML文件属性详解:
在这里插入图片描述
比如我们再需要去插入一个学生信息:
首先一样在之前的接口中声明好业务方法,再把业务sql insert into Student(SID,Sname,Ssex,Sage ) values(?,?,?,?); 封装到刚才的XML文件中

    /**
     * 插入单个学生信息
     * @param student
     * @return
     */
    public int  insertStudent(Student student);

直接写在刚才select标签下面

    <!--插入单个学生信息-->
    <!--
    insert标签:插入操作
    id属性:在当前的namespace中唯一标识
    parameterType:传入参数的类型,是参数类型的全限定名,可选操作
    flushCache属性:和一级二级缓存有关,true和false值,默认值true:在调用该语句是,会清空缓存
    timeout:等待数据返回的超时时间
    useGeneratedKeys属性:使用数据内部产生的主键 默认为false 
    keyColumn:指定数据库中的生成键
    -->
    <insert id="insertStudent" parameterType="com.tulun.pojo.Student" >
        insert into Student(SID,Sname,Sage, Ssex) values (#{SID},#{name},#{Sage},#{Ssex})
    </insert>

在这里插入图片描述
在这里插入图片描述
在编写Mapper的文件是需要遵循的开发规范,mybatis才能自动的生成接口的代理对象

开发规范

在编写Mapper的文件是需要遵循的开发规范,mybatis才能自动的生成接口的代理对象:
1、在mapper.xml文件中namespace和Mapper的接口文件的接口名保持一致

2、Mapper.java接口中的方法名和Mapper.xml中的Statement的ID保持一致
3、Mapper.java接口中方法的输入参数和mapper.xml文件中Statement的parameterType指定的类型一致
4、mapper.java接口中方法的返回值类型和mapper.xml文件中Statement的resultType指定的类型一致

注解形式的用法

注解的形式SQL语句直接写在接口上
优点:比较简单
缺点:当SQL发生改变,需要重新编译代码

select

public interface StudentMapper2 {
    /**
     * 通过SID查询学生信息
     */
    @Select("select * from Student where SID=#{sid}")
    public Student getStudentBySID(int sid);
}

只需再在全局配置文件中配置一条扫描包路径(给出该接口的包目录即可)的标签代码即可:

<package name="com.tulun.dao"/>

在这里插入图片描述
如果数据库字段和Java类属性不一致,使用@Results
在这里插入图片描述
在这里插入图片描述
其实跟resultMap标签是一样的:
在这里插入图片描述
再例如插入学生信息,直接写接口:

    /**
     * 插入学生信息
     */
    @Insert("insert into Student(SID,Sname,Sage,Ssex) values(#{SID},#{name},#{Sage},#{Ssex})")
    public int insertStudent(Student student);

在这里插入图片描述
使用mybatis自增主键在这里插入图片描述
其实和XML还是一样的

强调:

Java进行Mybatis调用时:
sqlSessionFactorybuilder:mybbatis提供的创建sqlSessionFactory实例的类,通过读取配置文件来创建sqlSessionFactory
sqlSessionFactory:会话工厂,一般是用单例模式创建,用来创建sqlSession会话的
sqlSession:会话,是操作数据库的CRUD等,sqlSession不安全的,一般进行一次操作就使用一个新的会话

多个参数的传递

当传递多个参数时,需要注意的问题:
例如通过学生年龄和性别来查询学生信息
select * from Student where Sage=? and Ssex=?
mybattis配置如下:
在这里插入图片描述
执行会抛出异常:在这里插入图片描述
XML可用的参数只有0,1,param1和Param2,Mybatis根据位置自定义的名字,可以将#{sex}改为#{0}或者#{param1},但这样是没有意义的
多参数传递是给参数配置@Param注解

@Select("select * from Student where Ssex=#{sex} and Sage = #{age}")
    public Student getStudentByAgeAndSex(@Param("sex") String sex,@Param("age") int age);

配置注解后,mybatis自动的将参数封装成Map类型,@Param注解值作为Map中的key,参数值作为Map中的value,通过这种形式可以识别多参数的对应关系

{}和${}区别:

#{}占位符在执行过程中将#{}替换重"?"占位符,将参数值和SQL分开传递到服务器
#{}使用类似于JDBC编程中prepareStatment
SQL注入问题:
#{}不存在SQL注入问题,采用预编译机制,将SQL和参数分别传递给SQL服务器
${}存在SQL注入问题

动态SQL

Mybatis强大特征之一自安于他的动态SQL,采用是OGNL表达式来处理SQL,根据表达式的不同能够将SQL进行拼接和组装
主要动态SQL的标签if标签,where标签,trim(where,set)标签,foreach标签
以场景为例:
场景1:根据SID查询学生
场景2:根据年龄查询学生
场景3:根据性别查询学生
场景4:更加年龄和性别查询学生
四个场景对应方法,对应四个XML文件里的配置,是否可以根据传入参数的不同可以动态的处理Sql

if标签

    <select id="getStudentBySexAndAge" resultType="com.tulun.pojo.Student">
       select * from Student where 1=1

       <if test="Sage != 0">
           and Sage = #{Sage}
       </if>
        <if test="Ssex != null">
           and Ssex = #{Ssex}
        </if>
    </select>
if表达式
一般使用是放在where条件后面
判断参数是否传递使用if test属性(必填)为true或者false
test使用OGNL表达式处理,返回true则进入到if标签的SQL,返回为false则不会进入if标签

参数处理:
假如不存Sage,Ssex: select * from Student where 1=1
假如传Sage,Ssex :select * from Student where 1=1 and Sage = #{Sage} and Ssex = #{Ssex}
假如传Sage:select * from Student where 1=1 and Sage = #{Sage}
假如传Ssex:select * from Student where 1=1 and Ssex = #{Ssex}

其实if标签里的语句相当于原本select语句后面差的部分,只是这时根据参数给的不一样哪个标签为true拼接哪个,假如我们给的是根据性别查,那Sage !=0 返回的肯定是true,Ssex返回的是false肯定就会把Sage那个if标签的语句拼接到原本select语句的后面
测试:
两个参数都传:
在这里插入图片描述
在这里插入图片描述
传递一个参数Ssex:
在这里插入图片描述
在这里插入图片描述
传递一个参数Sage:
在这里插入图片描述
在这里插入图片描述
不传参数:
在这里插入图片描述
在这里插入图片描述

where标签

一般和if标签一块使用,如果标签包含的元素有返回值就插入where,将紧随where后面的And或OR开头的,将他们剔除

 <select id="getStudentBySexAndAge" resultType="com.tulun.pojo.Student">
        select * from Student
        <where>
            <if test="Sage != null">
                and Sage = #{Sage}
            </if>
            <if test="Ssex != null">
                and Ssex = #{Ssex}
            </if>
        </where>
    </select>

值传递Sage:select * from Student where Sage = #{Sage};
不传递:select * from Student
两个都传递:select * from Student where Sage = #{Sage} and Ssex = #{Ssex}
跟if类似,直接在sql语句后面拼接where关键字和if标签成立的语句
测试:
无参:
在这里插入图片描述
在这里插入图片描述
传递一个参数Sage:
在这里插入图片描述
在这里插入图片描述
传递多个参数:
在这里插入图片描述
在这里插入图片描述

trim标签用于取出SQL中多余And关键字,逗号,使用在where或者set中

属性描述
prefix给sql拼接的前缀
suffix给sql拼接的后缀
prefixOverrides提出sql前面的关键字或者字符
suffixOverrides去除sql后面的关键字或者字符
    <!--trim标签(where)-->
    <select id="getStudentBySexAndAge" resultType="com.tulun.pojo.Student">
        select * from Student
        <trim prefix="where" prefixOverrides="and">
            <if test="Sage != null">
                and Sage = #{Sage}
            </if>
            <if test="Ssex != null">
                and Ssex = #{Ssex}
            </if>
        </trim>
    </select>

这个测试样例prefix=“where” prefixOverrides=“and” 相当于在sql后面拼接一个where关键字并且剔除and关键字即小面if标签中前面的and会被删掉
测试:
两个参数都传:
在这里插入图片描述
在这里插入图片描述
类似于更新标签可以这样写:
在这里插入图片描述
在这里插入图片描述
并且可以用trim去掉后面的逗号

foreach标签

批量处理
场景:通过一批SID查询用户信息
select * from Student where SID in(1,2,3);
insert into Student (SID,Sname) values (1,“zhansan”), (2,“zhansan”), (2,“zhansan”);
接口文件中的方法:

/**
     * 批量查询
     */
    public List<Student> batchSelectStudentByIds(List<Integer> ids);

Mapper.XML文件:

    <!--批量查询SQL-->
    <!--
    foreach表达式
    collection属性(必填)指定输入参数类型
      list:列表
      array:数组
      map:map集合

     item属性:取名称,给集合中单个元素的名称
     open属性:开始的字符串
     close属性:结束的字符串
     separator属性:数据之间的分割符
    -->
    <select id="batchSelectStudentByIds" resultType="com.tulun.pojo.Student">
     -- select * from Student where SID in(1,2,3);
        select * from Student where SID in
        <foreach collection="list" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </select>

测试:
在这里插入图片描述
在这里插入图片描述
模糊匹配(其实就是sql中的通配符)
需求:查询Student表,表中含有"L”的所有用户
SQL:select * from Student where Sname like “%L%”;
方式1:直接在参数上拼接通配符
mapper.getStudentsByName("%L%");
mapper.xml文件
在这里插入图片描述
测试用例:在这里插入图片描述
在这里插入图片描述
方法2:Mysql中的concat(,)
concat(par1,par2) :进行字符串拼接
Mapper.xml配置
在这里插入图片描述
测试用例:在这里插入图片描述
在这里插入图片描述

方法3:bind表达式处理

Mybatis提供的bind表达式
mapper.xml文件配置
在这里插入图片描述
在这里插入图片描述
接口方法:
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值