mybatis

什么是MyBatis?

MyBatis是持久层框架,也就是javaweb中的DAO层。用来简化使用者对数据库的一系列操作,MyBatis相当于增强版的JDBC,我们不需要关注数据库如何连接,如何查询等操作,只需要将我们需要的SQL语句写到sqlmapper映射文件中,并调用接口即可。大大简化了开发的繁琐任务。

MyBatis的配置

在默认已经学会使用Maven工具的前提下,我们可以将MyBatis的依赖和数据库连接的依赖加入到Maven的pom.xml文件中。

----------MyBatis的jar包依赖---------- 
<dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.1</version>
    </dependency>
----------数据库连接的jar包依赖---------- 
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.9</version>
    </dependency>

加入依赖后,我们在Maven项目下的src/main/resources目录下,创建一个mybatis.xml文件,里面用来存放我们连接数据库的环境配置,在这里我们可以参考MyBatis的官方文档,里面有详细的环境配置信息。

在下面的代码中,我使用了配置文件properties来引入MySQL的配置信息。该配置文件也放到rc/main/resources目录下。

properties数据库连接配置文件↓

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.user=root
jdbc.password=123456

配置信息中的dtd来对我们MyBatis配置信息进行规定。不符合规定语法会报错。

<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

在configuration双标签内部使用properties单标签对配置文件进行引入,使用${key}可以获取key对应的value。

  <properties resource="property.properties"/>

为了能让我们看清楚MyBatis框架的具体操作过程,我们可以加入日志文件,对执行sql语句的过程进行记录。

 <settings>//日志配置信息
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

typeAlies标签可以为我们的sqlmapper文件中的resultType起一个别名。让我们不需要为sql语句的返回值每次都写入返回类型的全限定名称。

​ typeAlias的使用有两种方法:

<typeAliases>
    <!--该种方法会将该包下的所有类直接作为返回值类型-->
        <package name="com.right.pojo"/>
     <!--该方法要指定到具体的一个类,为该类起一个别名-->
      <!--  <typeAlias type="com.right.pojo.MyStudent" alias="MyStudent"/>-->
    </typeAliases>

两种方法只能选择一种使用,推荐使用第一种方法。

在environments 标签内我们可以配置多个数据库信息,并使用default对要使用的数据库进行指定。

transactionManager该标签表示我们处理事务的方式,默认采用JDBC事务的处理方式,我们还可指定用Spring等其他方式处理事务。

 <transactionManager type="JDBC"/>

dataSource表示数据源处理方式,默认使用线程池进行处理,如果不使用线程池的话,使用UNPOOLED的话,在并发量比较大的情况下可能会影响sql操作的效率。

 <dataSource type="POOLED"></dataSource>

mapper文件中指定了我们的MyBatis去何处寻找我们的sqlmapper文件,mapper配置方式也有两种:

<mappers>
        <!--告诉 mybatis 要执行的 sql 语句的位置-->
       <!-- <mapper resource="com/right/dao/StudentDao.xml"/>-->
    <!--该包下的所有sqlmapper.xml-->
        <package name="com.right.dao"/>
    </mappers>

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="property.properties"/>
    <!--日志配置信息-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <typeAliases>
        <package name="com.right.pojo"/>
      <!--  <typeAlias type="com.right.pojo.MyStudent" alias="MyStudent"/>-->
    </typeAliases>
    <!--配置 mybatis 环境-->
    <environments default="mysql">
        <!--id:数据源的名称-->
        <environment id="mysql">
            <!--配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回滚)-->
            <transactionManager type="JDBC"/>
            <!--数据源 dataSource:创建数据库 Connection 对象
            type: POOLED 使用数据库的连接池
            -->
            <dataSource type="POOLED">
                <!--连接数据库的四个要素-->
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--告诉 mybatis 要执行的 sql 语句的位置-->
       <!-- <mapper resource="com/right/dao/StudentDao.xml"/>-->
        <package name="com.right.dao"/>
    </mappers>
</configuration>

sqlmapper配置

在配置sqlmapper之前我们先创建一个接口,接口中放置了我们的sql方法。

之后再在接口同级目录下配置sqlmapper文件,该文件名要与接口名一样,后面反射需要用到该处细节。

namespace命名空间必须有值,且该值必须唯一,我们需要使用该值来找到sqlmapper。

sql标签内的id要与我们接口中的方法名称一致,后期我们测试时可以通过调用接口内部的方法来对应sqlmapper中的id找到对应的sql语句,实现对数据库的操作。

<?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">
<!--
 namespace:必须有值,自定义的唯一字符串
 推荐使用:dao 接口的全限定名称
-->
<mapper namespace="com.right.dao.StudentDao">
    <!--
    <select>: 查询数据, 标签中必须是 select 语句
    id: sql 语句的自定义名称,推荐使用 dao 接口中方法名称,
    使用名称表示要执行的 sql 语句
    resultType: 查询语句的返回结果数据类型,使用全限定类名,如果起了别名可以用别名代替
    -->
    <select id="selectStudents" resultType="com.right.pojo.Student">
        <!--要执行的 sql 语句-->
        select * from student
    </select>
   
</mapper>

具体测试

配置完MyBatis.xml和sqlmapper文件后,我们需要进行测试。

测试需要获取sqlSession对象,该对象提供了测试方法,想要获取该对象则需要先获取sqlSessionFactory对象,sqlSessionFactory对象是一个重量级对象,在整个数据库操作过程中,我们只需要创建一个即可。

我们可以将获取sqlSession对象的代码封装到一个工具类中。

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

public class MybatisUtil {
    private static SqlSessionFactory factory =null;

    static{
        String config = "mybatis.xml";
        try {
            InputStream in = Resources.getResourceAsStream(config);//获取MyBatis配置信息,放入输入流中
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
             factory = builder.build(in);//将输入流读取到SqlSessionFactoryBulider对象中,创建一个sqlSessionFactory对象
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //通过SqlSessionFactory对象的openSession方法创建SqlSession对象
    public static SqlSession getSqlSession(){
        if (factory != null) {//确保只创建一个SqlSessionFactory对象
            SqlSession sqlSession = factory.openSession();
            return sqlSession;
        }
        return null;
    }
}

我们先通过工具类获取到SqlSession对象。

想要访问到sqlmapper文件,我们首先需要获取接口对象。该对象的调用通过反射完成,该反射可以让我们获取接口的全类名。因此为了保证程序的正常运行,接口的全类名和sqlmapper中的namespace值要相同。

调用接口的方法,即可访问到sqlmapper中对应的方法。

当我们完成数据库操作后要关闭SqlSession。

 @Test
    public void selectStudentsTest(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        List<Student> students = studentDao.selectStudents();
        sqlSession.close();
        students.forEach(System.out::println);
    }

当数据库列名和对象属性名不一致时

在sqlmapper文件中,当数据库列名和对象属性名不一致时,我们可以使用resultMap标签为其名称进行对应。其中id标签代表主键,result为普通列名。

将查询结果返回值返回到resultMap即可完成数据库列名和对象属性名的转换。

我们也可直接使用数据库语法as起别名,但是不提倡。

  <resultMap id="selectStudents" type="com.right.pojo.MyStudent">
        <id column="id" property="stuId"/>
        <result column="name" property="stuName"/>
        <result column="email" property="stuEmail"/>
        <result column="age" property="stuAge"/>
    </resultMap>
    <select id="selectStudentsByMapper" resultMap="selectStudents">
        select id,name,email,age from student
    </select>

动态sql

在sqlmapper文件中,常用的动态sql标签为ifwhereforeach

if的用法

​ 在test中放置条件,满足条件的if标签内的sql语句会进行拼接。

<if test="" >sql语句 </if>

但是在使用if时,需要在 where 后手工添加 1=1 的子句。因为,若 where 后的所有if条件均为 false,而 where 后若又没有 1=1 子句,则 SQL 中就会只剩下一个空的 where,SQL出错。所以,在 where 后,需要添加永为真子句 1=1,以防止这种情况的发生。但当数据量很大时,会严重影响查询效率。

这时我们就可以使用where标签对if进行包裹。在有查询条件时,可以自动添加上 where 子句;没有查询条件时,不会添加where 子句。

foreach的用法

如果传入的数据是数组,collection则为array,如果传入数据是集合,collection为list

<foreach collection="集合类型" open="开始的字符" close="结束的字符" 
item="集合中的成员" separator="集合成员之间的分隔符">
 #{item 的值}
</foreach>

sqlmapper中#和$的区别

#代表创建的数据库操作对象为PrepatedStatement类型,该对象编译sql语句方式:先编译sql语句,再将值传入占位符中。可以有效放置sql注入问题,并且效率较高。

$代表创建的数据库操作对象为Statement类型,该对象会将本身的sql语句和要传入的语句进行拼接,可能会造成sql注入问题,并且效率较低。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值