MyBatis

MyBatis作为解决JDBC缺点的框架,主要任务包括注册驱动、创建数据库连接、执行SQL语句和处理结果集。它通过XML配置文件和接口实现解耦,简化了数据库操作。使用MyBatis时,需要创建实体类、Dao接口和对应的XML映射文件。在主配置文件中配置数据源和mapper文件位置,并通过SqlSessionFactory创建SqlSession,执行SQL并处理结果。MyBatis支持自动提交和手动提交事务,提供动态SQL功能,如if、where、foreach标签,适用于不同条件的SQL构建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为了解决JDBC缺点:业务代码和sql语句混在一起----解耦合、用起来太麻烦---专注sql语句编写

MyBatis可以:1)注册驱动 2)创建JDBC中使用的Connection、Statement、ResultSet 3)执行sql语句 4)处理ResultSet,把记录集中的数据转为Java对象,把该对象放入List集合

使用MyBatis:

  1. 使用 Maven 来构建普通Java项目,则需将MyBatis依赖、mysql驱动的依赖、maven插件放到pom.xml 文件中      
    拷贝路径XML的插件
    <build>
        <resources>
            <resource>
            <directory>src/main/java</ 所在的目录 ---->
            < 包括目录下的 .properties,.xml 文件都会扫描到 ---->
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
            </resource>
        </resources>
    </plugins>

  2. 创建实体类(与表对应),属性名和数据库表的列名保持一致,生成属性对应的set、get方法
  3. 创建操作数据库的Dao接口,定义操作数据库的方法
    1. 创建接口:XxxDao
    2. 定义方法:定义操作----数据库表对应的对象(根据实体类创建的对象)的接口方法
  4. 在接口同目录下创建XML文件(mapper文件,写XML语句的),文件名和接口名保持一致。在文件里写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">       <!--.dtd约束文件:定义和显示当前文件可以使用的标签、属性等-->   
    <mapper namespace="Dao接口的全名">     <!--mapper根标签,必须有值namespace命名空间:值推荐是Dao接口的全名,是参与识别sql语句的-->
      
    
      <!--写insert语句-->
      <insert> 
      <!--写update语句-->
      <update> 
      <!--写delete语句-->
      <delete>                       
      <!--写select语句-->
      <select> 
    
          
    
      <!--执行SQL语句,把结果转成resultType对应的类型的对象(由框架通过反射机制创建resultType对应的类型的对象,把数据库中表的列赋值给与对象对象同名的属性)-->
      <select id="要执行的sql语句的唯一标识,推荐dao接口的方法名" parameterType="指定参数类型" resultType="告诉MyBatis执行语句后把数据赋值给哪个类型的Java对象(即步骤2的实体类),推荐用Java全类名">
        <!--SQL语句,  #{变量}是--执行sql语句是传入的实参-->
        select * from Blog where id = #{id}             
      </select>
    
    
       <resultMap id="唯一值" type="执行SQL返回的Java类型全限定名称">
           <!--自定义列名和属性名的对应-->
           <!--主键类型使用id标签-->
           <id column="表的列名" property="返回对象的属性值"/>
           <!--非主键类型使用result标签-->
           <result column="表的列名" property="返回对象的属性值"/>
           <!--属性名和列名一致不用定义-->
       </resultMap>
       <select id="" resultMap="resultMap标签的id">
           select * from Blog where id = #{id}             
       </select>
    </mapper>
    
    

  5. 创建MyBatis的主配置文件XML,只有一个,放到resources目录下:
    1. 获取数据库连接实例的数据源
    2. 指定其他mapper文件的位置
      <?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>
      
        <!--设置日志功能-->
        <settings>
          ...
          <!--设置日志方式:SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING-->
          <setting name="logImpl" value="日志方式"/>     
          ...
        </settings>
      
        <!--声明别名-->
        <typeAliases>
          <!--定义一个别名,方式一      type属性:Java全限定名称 alias属性:自定义别名-->
          <typeAlias type="全限定名" alias="别名">
          <!--定义一个别名,方式二   (不区分大小写)  该包的下的类名就是别名-->
          <package name="包名" >
        </typeAliases>
      
      
        <environments default="development">
          <environment id="development">
            <transactionManager type="JDBC"/>
      
            <!--配置数据源:依赖创建连接对象Connection的-->
            <dataSource type="POOLED">  
              <!--driver:驱动类   相当于注册驱动-->
              <property name="driver" value="com.mysql.jdbc.Driver"/>
              <!--连接数据库的url-->
              <property name="url" value="jdbc:mysql://localhost:3306/数据库?useUnicode=true&amp;characterEncoding=utf-8"/>
              <!--账号、密码-->
              <property name="username" value="账号"/>
              <property name="password" value="密码"/>
            </dataSource>
      
          </environment>
        </environments>
      
      
        <!--指定其他mapper文件的位置:为了找到其他文件中的sql语句-->
        <mappers>
          <!--一个mapper文件一个mapper标签-->
          <mapper resource="mapper文件的路径,从类路径target/classes路径开始"/>
        </mappers>
      </configuration>
  6. 使用:实现Dao接口,在实现方法中操作
    1. 定义mybatis主配置文件的文件 :         String resource = "从类路径开始";

    2. 读取主配置文件:                                 InputStream inputStream = Resources.getResourceAsStream(resource);
                                                                     //Resources:MyBatis框架中的对象。作用:读取主配置文件信息

    3. 使用SqlSessionFactoryBuilder创建SqlSessionFactory对象

      1. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        
                                                                                   //SqlSessionFactoryBuilder对象:负责创建SqlSessionFactory对象

      2. 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。
          //  SqlSessionFactory对象:是一个重量级对象:创建该对象需要更多的资源和时间,在项目中有1个就可以
         //SqlSessionFactory是一个接口:是SqlSession的工厂,作用是创建SqlSession对象 //实现类:DefaultSqlSessionFactory
                     方法:openSession():获取默认的SqlSession对象,默认是需要自动提交事务的
                                openSession(布尔值):true--->创建自动提交事务的SqlSession对象,flase等同于没有参数的SqlSession对象

    4. 从 SqlSessionFactory 中获取 SqlSession实例,SqlSession实例提供了执行SQL语句的方法

      1. 获取:SqlSession session = sqlSessionFactory.openSession()
                //SqlSession:是一个接口,提供大量执行sql语句的方法      //  实现类:DefaultSqlSession,创建的对象不是线程安全的:使用步骤
                                                                                                                                 1)在在方法内部执行sql语句之前先拿到SqlSession对象
                                                                                                                                 2)调用SqlSession方法执行sql语句
                                                                                                                                 3)关闭SqlSession对象
                           方法:selectOne():执行的sql语句最多得到一行记录,多于一个报错
                                      selectList():执行sql语句,可以得到0或多行记录
                                      selectMap():执行sql语句,返回一个Map结果
                                      insert():执行insert语句
                                      update():执行update语句
                                      delete():执行delete语句
                                      commit():提交事务
                                      rollback():回顾事务
                                      close(): 5关闭SqlSession对象
                                      getMapper(dao接口.class):mybatis实现代理

      2. 指定要执行的SQL语句:String sqlId = namespace值+"."+SQL语句的id值

      3. 通过SqlSession实例执行SQL语句:  实体类型  对象 = (实体类型) session.selectOne(sqlId,传给占位符的实参值);//返回之前mapper配置的对象类型,用实体类去接受
        MyBatis默认执行sql语句是手工提交事务模式,所以做insert、update、delete时需要提交事务:session.commit();
        //对于insert语句:session.selectOne(sqlId,实体类型对象);       //在实体类型对象中设置值,在SQL语句中用 #{属性名} 的方式来获取该值,即占位符中使用属性名

      4. 关闭SqlSession对象:session.close()

自动提交事务:当sql语句执行完毕后,提交事务。      //数据库更新的操作就保存到数据库了

手动提交事务:在你需要提交事务的位置,执行方法,提交事务或回顾事务

代理: 

 每次在Dao的方法里都需要固定的步骤,可以使用工具类封装操作

Dao的实现类其实并没有干什么实质性的工作,它仅仅就是通过 SqlSession的相关 API定位到映射文件 mapper中相应 id的 SQL语句,真正对 DB进行操作的工作其实是由框架通过 mapper中的 SQL完成的。

mybatis框架在执行期间,根据Dao接口,创建一个内存中的接口实现类对象,mybitis把这个技术叫做dao技术(dao的动态代理) //不用写dao接口的实现类了
dao技术:由mybatis创建Dao接口的实现类,使用框架创建的Dao实现类代替手工的dao实现类的功能(要求:mapper的namespace是接口的全限定名称、id是dao接口的方法名)
使用dao技术:SqlSession对象.getMapper(dao接口.class),返回该接口对应的dao对象     //即dao接口类型对象,等同于new出dao接口实现类

理解参数

如何通过Java程序把参数传入mapper文件中的SQL语句 :           //参数:主要是指dao接口方法的形参
        接口方法的参数:只有1个简单类型时 --------------->在SQL语句中使用: #{任意字符}      //简单类型:Java基本类型、字符串
        接口方法的参数:多个简单类型时------->@Param:命名参数,该注解由MyBatis提供,在接口方法的形参定义之前,定义参数名。该名可用在mapper文件SQL语句中 :#{别名}
                                                                                                         例:         返回值   方法名(@Param(value = "别名")形参类型 形参名,@Param(value = "别名")形参类型 形参名)
                                                                                                                                                     形参一                                                           形参二
        接口方法的参数:1个对象(有属性、set、get)作为参数-------->在SQL语句中使用 :#{属性名}          //mybatis是调用该属性的get、set方法去获取值
                                                                                                                               #{属性名}是简写 ------->    #{ 属性名,javaType=java中数据类型全名 ,jdbcType=数据类型名称 }
        接口方法的参数:多个简单类型参数         ------->按位置      #{agr0}代表参数1     #{arg1}代表参数2    #{arg2}代表参数3  ……                //不推荐,可读性不好
        接口方法的参数:1一个Map作为参数 ---------->在SQL语句中 通过key获取value值     #{key}            //不推荐使用:参数个数、类型不清晰,可读性不好
        
        

parameterType:指定参数类型--->表示指定dao接口方法形参类型,给mybatis使用。 //可以使用Java类型的全限定名称  或   mybatis定义的别名
                                                                                        //mybatis通过反射机制可以获取接口方法的类型,所以也可以不写该属性
                全限定名称<select id=" " resultType=" " parameterType="java.lang.Integer">
                别名<select id=" " resultType=" " parameterType="别名">
                                     

占位符:#{字符}              //使用jdbc对象是PrepareStatement对象,效率高,可以避免sql注入 。        //常作为列值使用,位于等号右侧,${ }位置的值和数据类型有关
              ${字符}              使用jdbc对象是Statement对象,效率低,字符串连接方式,有注入风险。     //${}位置的数据是原样使用的,不会区分数据类型,常用作表明、列名

封装MyBatis输出结果

封装输出: MyBatis执行SQL语句,得到ResultSet,转为Java对象
 

resultType属性:执行select时使用,作为<select>标签的属性出现

resultType:表示3种类型:
1)表示自定义对象           2)返回简单类型:执行SQL返回单个值           3)得到Map结构:列名key,列值value。推荐使用 Map<Object,Object>接受
resultType:表示结果类型,mybatis执行sql语句,得到的Java对象类型、简单类型、Map        它的值有2种表示方法,用来表示执行sql得到的值
        //mybatis会调用该类型的无参构造创建对象,数据库表同名的列赋值给对象同名属性,得到Java对象。如果接口方法返回List集合,mybatis会把该对象放入List集合

  1. Java类型的全限定名称             
  2. mybatis别名


 

resultMap:结果映射。自定义列名和Java对象属性的对应关系。(常用在列名和属性名不同时)
用法:

  1. 定义<resultMap id="唯一值" type="执行SQL返回的Java类型全限定名称">标签,指定列名和属性名的对应关系
          自定义列名和属性名的对应(属性名和列名一致不用定义): 
           <id column="表的列名" property="返回对象的属性值"/>              //主键类型使用id标签
           <result column="表的列名" property="返回对象的属性值"/>           //非主键类型使用result标签
  2. 在<select>标签使用resultMap属性指定:上面定义的<resultMap>标签的id值:
           <select id="" resultMap="resultMap标签的id">

自定义别名:mybatis提供的对Java类型定义的好记的名字        
        步骤:

  1. 主配置文件:使用<typeAlias>标签声明别名
  2. 在mapper文件:resultType="别名"

列名和属性名不太一致问题:

  1. 使用resultMap
  2. 使用 resultType,让SQL的列名使用SQL别名,让SQL别名和属性名一致


like:模糊查询
       方式一:在Java程序中,把SQL语句中的like内容(即like的条件)组装好,传入sql语句        //推荐
        法式二:直接在SQL语句组装
 


动态SQL:同一个dao的方法,根据不同的条件可以表示不同的SQL语句,主要是where的变化
mybatis通过提供的标签,来实现动态SQL:if、where、foreach、sql
使用动态sql,dao方法的形参使用Java对象
 


if标签语法                  //问题:若所有if条件都不满足,则SQL语句会发生什么问题,怎样解决----WHERE关键字的问题
<if text="boolean判断结果,使用Java对象的属性">
        SQL语句
</if>

 mapper文件中:

<select id="selectStudentIf" resultType="com.bjpowernode.domain.Student"> 
    select id,name,email,age from student 
    where 1=1        
    <if test="name != null and name !='' "> 
        and name = #{name} 
    </if> 
    <if test="age > 0 ">
        and age &gt; #{age} 
    </if> 
</select>

 where标签语法:里面有一个或多个if标签,当有一个if判断为true,where会转为WHRTR关键字附加到SQL后,若所有if都不为true,则忽略where和if
<where>
        <if></if>
</where>

<select id="selectStudentWhere" resultType="com.bjpowernode.domain.Student"> 
    select id,name,email,age from student
    <where> 
        <if test="name != null and name !='' ">
            and name = #{name} 
        </if> 
        <if test="age > 0 "> 
            and age &gt; #{age} 
        </if> 
    </where> 
</select>

foreach标签:循环,可以循环数组、list集合,一般在in语句中
<foreach         collection="表示要遍历对象类型"                         //表示要遍历对象类型,却决于形参类型             数组-->array       集合--->list
                       open="遍历开始之前添加的字符"
                       close="遍历结束之后添加的字符"
                       item="集合中的成员,自定义的变量"
                       separator="集合成员之间添加的分隔符
">
        #{item属性的值}
</foreach> 

方式一:遍历 List  --->简单类型 
<select id="selectStudentForList" resultType="com.bjpowernode.domain.Student"> 
    select id,name,email,age from student 
    <if test="list !=null and list.size > 0 ">     //传入的集合不为空且长度大于0
        where id in 
        <foreach collection="list" open="(" close=")" item="stuid" separator=","> 
            #{stuid}         
        </foreach> 
    </if> 
</select>


方式二:遍历 List  --->对象类型 
<select id="selectStudentForList2" resultType="com.bjpowernode.domain.Student"> 
    select id,name,email,age from student 
    <if test="list !=null and list.size > 0 ">
        where id in 
        <foreach collection="list" open="(" close=")" item="stuobject" separator=","> 
            #{stuobject.id} 
        </foreach> 
    </if> 
</select>

sql标签:表示一段代码片段             表名、字段、where条件都可以,可以在其他地方复用sql标签的内容
1)在mapper文件中定义sql标签的代码片段
<sql id="片段的自定义名称,唯一性">
        sql语句片段
<sql>

2)在要用的位置使用include标签引用代码片段     //可以在任意SQL语句位置中使用片段
 <include refid="sql片段的id"/> 

 

<sql id="studentSql"> 
    select id,name,email,age from student 
</sql>

<select id="selectStudentSqlFragment" resultType="com.bjpowernode.domain.Student"> 
    <!-- 引用sql片段 --> 
    <include refid="studentSql"/> 
    <if test="list !=null and list.size > 0 "> 
        where id in 
        <foreach collection="list" open="(" close=")" item="stuobject" separator=","> 
            #{stuobject.id} 
        </foreach> 
    </if> 
</select>

配置文件:
        1)主配置文件:提供全局设置-----日志、数据源、mapper文件的位置
        2)mapper文件:写sql语句的

主配置文件:
        <propertys resource="类路径下的配置文件">                                使用外部数据库配置文件   //这样<property>就可以使用外部的数据了
        <settings>                                全局设置,影响整个mybatis运行     
        <typeAliases>                          别名设置   
        <environments default=“某个环境的id值”>              配置环境        //环境标签,里面可以配置多个<environment>          default表示默认连接的数据库
                        <environment id="id 定义环境的标识">                每个表示一个数据库的连接信息
                                <transactionManager type="表示事务管理器类型">       事务管理器     
                                                                                        type属性值:JDBC--表示使用Connection对象,由mybatis自己完成事务处理
                                                                                                              MANAGED---把事务的管理交给容器来做(由其他软件完成事务的提交回滚)
                                <dataSource type="数据源类型">                数据源,用来创建Connection对象,连接数据库
                                           type属性值:POOLED---mybatis会在内存中创建PooledDataSource类,管理多个Connection连接对象,使用连接池     //基本都是用这个
                                                     UNPOOLED---不使用连接池,MyBatis 会创建 UnpooledDataSource类,每次执行sql语句先创建Connection对象,执行完sql在关闭Connection对象
                                                    JNDI---Java的命名和目录服务    MyBatis会从 JNDI服务上查找 DataSource 实例,然后返回使用  //很老了,不会有
                                        <property name="driver" value="com.mysql.jdbc.Driver"/>
                                        <property name="url" value="jdbc:mysql://localhost:3306/数据库?useUnicode=true&amp;characterEncoding=utf-8"/>
                                        <property name="username" value="账号"/>
                                        <property name="password" value="密码"/>
                                        或   引用外部文件---使用外部文件的值,前提是要配置好<propertys>
                                         <property name="driver" value="${对应的key值}"/>                /
                                        <property name="url" value="${key值}"/>
                                        <property name="username" value="${key值}"/>
                                        <property name="password" value="${key值}"/>
        <mappers>               
                <mapper resource="mapper路径文件">                指定其他mapper文件位置
                <package name="mapper文件所在的包名" />      该包下所有mapper文件一次加载                 //需要mapper文件和dao接口在同一目录、mapper文件和dao接口名称一致                           

有可能<dataSource>内的的数据库配置信息太长,为了方便管理,另外放一个独立文件去:
1.在resources目录中,创建xxx.properties文件,key=value            //例如:jdbc.url=xxxxxxx     .是为了看起来更有层次,每别的意思
2.在主配置文件使用:<property name="driver" value="${key值}"/>

                                                       
                                        
                                
        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值