• MyBatis3.4全集笔记


    MyBatis

    1. 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)

    MyBatis虽然改变了名字,但是实际的内核还是ibatis

    MyBatis以高轻量级闻名于全球,提出以注入SQL的方式来管理持久化,让整个项目在数据库操作这块与SQL语言完全解耦,所以深受开发人员的喜爱

    mybatis是一款高轻量级的基于ORM(对象关系映射)半自动化的持久层框架,它更加关注原生sql的编写,在实际开发过程中能够实现sql语句与业务代码的完全的解耦。它还支持强大的sql查询、存储过程、高级映射、缓存机制。还支持强大的基于OGNL动态sql的编写。

    2. Maven MyBatis搭建

    基础脚手架效果如图:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    需要配置的几项内容:

    (1).pom文件

    (2).mybatis.xml文件

    (3).pojo类

    (4).数据库映射XML

    (5).创建数据库操作对应的接口

    (6).控制器

    第一项,配置pom文件,需要加入两个maven包,一个是数据库连接驱动,一个是mybatis
    <dependency>
       <groupId>mysqlgroupId>
       <artifactId>mysql-connector-javaartifactId>
       <version>8.0.31version>
    dependency>
    <dependency>
      <groupId>org.mybatisgroupId>
      <artifactId>mybatisartifactId>
      <version>3.4.6version>
    dependency>
    
    第二项,添加mybatis.xml文件
    
    DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <settings>
            
            <setting name="returnInstanceForEmptyRow" value="true"/>
    	
    <setting name="logImpl" value="STDOUT_LOGGING"/>
    
        settings>
    
        <environments default="development">
    
            <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/gxa"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                dataSource>
            environment>
        environments>
    
        <mappers>
            
            
            <package name="cn/thinknovo/pojo"/>
        mappers>
    configuration>
    
    
    
    第三项,pojo类,创建一个类名与数据库相同,属性名和数据库字段名相同的pojo对象。
    第四项,数据库映射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">
    <!-- namespace一般定义为 包名+类名 -->
    <mapper namespace="cn.thinknovo.pojo.UserMapper">
        <select id="selectUser" resultType="cn.thinknovo.pojo.User">
          select * from user;
       </select>
    
        <insert id="insertUser" parameterType="cn.thinknovo.pojo.User">
          insert into user values (#{id},#{username},#{password});
       </insert>
    </mapper>
    
    第五项,定义数据库操作接口,这里需要注意的是,mybatis以此接口为调用入口,通过此接口对应的方法来检查并对应mapper.xml文件中的增删改查
    public interface UserMapper {
        // 方法名、参数类型、返回类型要和mapper.xml文件中的id相同
        List<User> selectUser();
        void insertUser(User user);
    }
    
    第六项,创建控制器–测试
    public class MybatisConsole {
        public static void main(String[] args) {
            try {
                Reader reader = Resources.getResourceAsReader("mybatis.xml");
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
                SqlSession session = sqlSessionFactory.openSession();
                UserMapper userMapper = session.getMapper(UserMapper.class);
                List<User> userList = userMapper.selectUser();
                System.out.println(userList);
                session.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    至此,基础脚手架搭建完成

    3. Mapper.xml文件的注册和自动扫描

    在mybatis.xml文件中,可以直接使用package的方式来完成自动扫描,这样以后就不需要一个个的添加mapper.xml文件了

    <mappers>
            
            
            <package name="cn/thinknovo/pojo"/>
        mappers>
    

    4.解决后台提示找不到对应xml文件

    Idea默认找不到对应的xml配置路径,在pom文件的build标签中,加入resource标签如下代码:

    <resources>
      <resource>
        <directory>src/main/javadirectory>
        <includes>
          <include>**/*.xmlinclude>
        includes>
      resource>
    resources>
    
    

    5.两种处理操作数据库的方式

    (1).通过session得到对应的Mapper接口对象,然后由此对象调用对应的操作方法,例如:

    Reader reader = Resources.getResourceAsReader("mybatis.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    SqlSession session = sqlSessionFactory.openSession();
    UserMapper userMapper = session.getMapper(UserMapper.class);
    List<User> userList = userMapper.selectUser();
    System.out.println(userList);
    

    (2).通过session直接调用接口中对应的操作方法

    // 第一个参数对应接口中的方法名
    session.selectList("selectUser");
    

    (PS:注意在这里接口文件和Mapper.xml文件是必须的,缺一不可,可以通过删除对应的文件来测试执行结果。)

    6.关闭自动提交事务

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    这里注意,只有执行增、删、改的时候,才需要提交事务,查询是不需要事务的,在操作完对应的增删改之后,执行session.commit();
    PS:注意,mybatis默认事务就关闭了自动提交,可以通过接口查看

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    7.Xml配置方式的增删改查

    首先配置mapper.xml文件

    <!-- namespace一般定义为 包名+文件名 -->
    <mapper namespace="cn.thinknovo.pojo.UserMapper">
    
    <select id="selectUser" resultType="cn.thinknovo.pojo.User">
      select * from user;
    </select>
    
     <insert id="insertUser" parameterType="cn.thinknovo.pojo.User">
       insert into user values (#{id},#{username},#{password});
    </insert>
    
    <update id="updateUser" parameterType="cn.thinknovo.pojo.User">
       update user set username=#{username},password=#{password} where id=#{id};
    </update>
    
    <delete id="deleteUser" parameterType="java.lang.String">
       delete from user where id=#{id};
    </delete>
    </mapper>
    

    然后在修改接口代码

    public interface UserMapper {
        // 方法名、参数类型、返回类型要和mapper.xml文件中的id相同
        List<User> selectUser();
        void insertUser(User user);
        void updateUser(User user);
        void deleteUser(String id);
    }
    

    在控制器中调用接口中指定的四个方法,就可以完成基本的增删改查

    在控制器中调用接口中指定的四个方法,就可以完成基本的增删改查

    8.多参数传递

    在项目中,多参数传递更多的是基于pojo对象,或者map结构传递,但是也可能有需要多个形式参数传递,比如这样:

    UserMapper.insertUserByPassword("think12345","54321");
    

    这种情况,配置文件需要做对应的处理,改成下面的样子:

    <insert id="insertUserByPassword" parameterType="java.lang.String">
        insert into user values(null,#{param1},#{param2});
    insert>
    

    param1代表获取第一个形式参数,依次类推

    param1代表获取第一个形式参数,依次类推

    也可以这样:

    <insert id="insertUserByPassword" parameterType="java.lang.String">
        insert into user values(null,#{arg0},#{arg1});
    insert>
    

    arg0代表获取第一个形式参数,依次类推

    arg0代表获取第一个形式参数,依次类推

    如果有更多的这样的形式参数,就递增数字,比如第三个就是parma3或者arg2,在动态配置sql的时候,根据需要可以任意调换顺序,比如可以换成下面的效果:

    <insert id="insertUserByPassword" parameterType="java.lang.String">
        insert into user values(null,#{arg1},#{arg0});
    insert>
    

    arg0还是代表第一个参数,arg1还是代表第二个参数,不受影响。

    arg0还是代表第一个参数,arg1还是代表第二个参数,不受影响。

    还可以这样写:
    在接口中声明方法

    /**
    * mybatis  把参数转换为 map 了,其中@Param("key") 参数内
    容就是 map 的 value
    * @param name
    * @param pwd
    * @return
    */
    List<User> selByNamePwd(@Param("name") String
    userName,@Param("pwd") String userPwd);
    

    在 mapper.xml 中添加
    #{} 里面写@Param(“内容”)参数中内容

    
    <select id=" selByNamePwd" resultType="User" >
    select * from User where name=#{name} and  pwd=#{pwd}
    select>
    

    9.Java中的Map结构传递

    如果在项目中需要多参数传递,更建议大家使用java.util.map的结构传递,这也是大部分项目使用的方式,mybatis会根据key来对应获取value值,设置的传递类型还是parameterType,比如这样:

    <insert id="insertUserByUserAndPassword" parameterType="map">
    insert into user values(null,#{username},#{password});
    insert>
    

    10.Map结构传递

    如果要定义为map结构传递,需要在mybatis.xml中定义map的结构方式,比如这样:

    <parameterMap id="userMap" type="cn.thinknovo.pojos.User">
        <parameter property="username" javaType="java.lang.String"/>
        <parameter property="password" javaType="java.lang.String"/>
    parameterMap>
    	
    

    这里的id就是map引入的名字,我们在传递参数类型设定为map以后就可以使用,比如:

    <insert id="insertUserByUserAndPassword2" parameterMap="userMap" >
    insert into user values(null,#{username},#{password});
    insert>
    

    11.注解的使用

    删除mapper.xml文件,然后在接口文件中通过注解的方式添加sql语句

    public interface UserMapper {
    // 方法名、参数类型、返回类型要和mapper.xml文件中的id相同
    @Select("select * from user")
    List<User> selectUser();
    @Insert("insert into user values (#{id},#{username},#{password})")
    void insertUser(User user);
    @Update("update user set username=#{username},password=#{password} where id=#{id}")
    void updateUser(User user);
    @Delete("delete from user where id=#{id}")
    void deleteUser(String id);
    }
    

    注意,我们现在可以删除mybatis.xml中的mapper标签,我们也可以在mybatis.xml文件中添加的mapper标签,不再需要resource属性,而是class属性,如下:

    
     <mappers>
         <mapper class="c.thinknovo.mybatis3.UserMapper"/>
     mappers>
    

    12.动态SQL的if使用 – 非常重要

    根据不同的条件执行不同的结果

    <select id="selectUser" resultType="cn.thinknovo.pojo.User" parameterType="cn.thinknovo.pojo.User">
          select * from user
       <if test="username != null">
          where username=#{username}
       if>
    select>
    

    在配置文件中添加动态的if语句,如果传递过来的user对象中,username不等于null,那么追加条件查询

    13.动态SQL的where使用

    如果我们有多个条件需要添加,但是有可能一个条件都不满足,那么这时候使用上面的方式就会出现问题,所以我们还需要在if外部添加一个where标签

    <select id="selectUser" resultType="cn.thinknovo.pojo.User" parameterType="cn.thinknovo.pojo.User">
          select * from user
       <where>
          <if test="username != null">
             username=#{username}
          if>
          <if test="password != null">
             and password=#{password}
          if>
       where>
    select>
    

    可以看到,where包含了两个if,而第一个if中没有and,where标签会自动检查状态,如果标签返回的第一个匹配内容是以 and或or 开头的,则会自动删除and或者or ,然后再追加where

    14.动态SQL的choose when使用

    <select id="selectUser" resultType="cn.thinknovo.pojo.User" parameterType="cn.thinknovo.pojo.User">
          select * from user where password='888888'
    <where>
       <choose>
          <when test="username != null">
             AND username=#{username}
          when>
          <when test="password != null">
             AND password=#{password}
          when>
          <otherwise>
             AND id=#{id}
          otherwise>
       choose>
    <where>
    select>
    

    Choose when 类似于java中的switch case,任中只会走一个,一般是在有一个条件固定的情况下,需要额外不确定的条件时,使用choose的方式

    15.逆向工程mybatis-generator-maven-plugin

    (1)首先修改pom文件为下面的内容,需要注意configurationFile标签是对应mybatis-generator的路径和文件名,修改为自己想要的,其余不做修改:
    
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0modelVersion>
    
      <groupId>cn.thinknovogroupId>
      <artifactId>mybatis002artifactId>
      <version>1.0-SNAPSHOTversion>
      <packaging>warpackaging>
    
      <name>mybatis002 Maven Webappname>
      
      <url>http://www.example.comurl>
    
      <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <maven.compiler.source>1.7maven.compiler.source>
        <maven.compiler.target>1.7maven.compiler.target>
      properties>
    
      <dependencies>
        <dependency>
          <groupId>junitgroupId>
          <artifactId>junitartifactId>
          <version>4.11version>
          <scope>testscope>
        dependency>
        <dependency>
          <groupId>mysqlgroupId>
          <artifactId>mysql-connector-javaartifactId>
          <version>5.1.46version>
        dependency>
        <dependency>
          <groupId>org.mybatisgroupId>
          <artifactId>mybatisartifactId>
          <version>3.4.6version>
        dependency>
        <dependency>
          <groupId>org.mybatis.generatorgroupId>
          <artifactId>mybatis-generator-coreartifactId>
          <version>1.3.6version>
        dependency>
      dependencies>
    
      <build>
        <finalName>mybatis002finalName>
        <pluginManagement>
          <plugins>
            <plugin>
              <artifactId>maven-clean-pluginartifactId>
              <version>3.0.0version>
            plugin>
            
            <plugin>
              <artifactId>maven-resources-pluginartifactId>
              <version>3.0.2version>
            plugin>
            <plugin>
              <artifactId>maven-compiler-pluginartifactId>
              <version>3.7.0version>
            plugin>
            <plugin>
              <artifactId>maven-surefire-pluginartifactId>
              <version>2.20.1version>
            plugin>
            <plugin>
              <artifactId>maven-war-pluginartifactId>
              <version>3.2.0version>
            plugin>
            <plugin>
              <artifactId>maven-install-pluginartifactId>
              <version>2.5.2version>
            plugin>
            <plugin>
              <artifactId>maven-deploy-pluginartifactId>
              <version>2.8.2version>
            plugin><plugin><groupId>org.mybatis.generatorgroupId><artifactId>mybatis-generator-maven-pluginartifactId><version>1.3.6version><configuration><configurationFile>src\main\resources\mybatis-generator-config.xmlconfigurationFile><verbose>trueverbose><overwrite>trueoverwrite>configuration><executions><execution><id>Generate MyBatis Artifactsid><goals><goal>generategoal>goals>execution>executions><dependencies><dependency><groupId>org.mybatis.generatorgroupId><artifactId>mybatis-generator-coreartifactId><version>1.3.6version>dependency>dependencies>plugin>plugins>pluginManagement>
      build>
    project>
    
    (2)接着添加mybatis-generator-config.xml文件,注意修改
    (1)classPathEntry为自己的数据库连接池jar包物理路径
    (2)jdbcConnection为自己的数据库连接参数
    (3)javaModelGenerator为实体类生成的位置 修改targetPackage和targetProject
    (4)sqlMapGenerator为*Mapper.xml 文件的位置 修改targetPackage和targetProject
    (5)javaClientGenerator为Mapper 接口文件的位置 修改targetPackage和targetProject
    (6)table为表对应内容,多表就配置多个,tableName表名 domainObjectName类名

    完整配置如下:

    
    
    DOCTYPE generatorConfiguration PUBLIC
            "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
            "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
    <generatorConfiguration><classPathEntry location="C:\Users\Administrator\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar"/><context id="context" targetRuntime="MyBatis3"><commentGenerator><property name="suppressAllComments" value="false"/><property name="suppressDate" value="true"/>commentGenerator><jdbcConnection driverClass="com.mysql.jdbc.Driver"
                            connectionURL="jdbc:mysql://localhost:3306/hiber"
                            userId="root"
                            password="thinknovo"/><javaTypeResolver><property name="forceBigDecimals" value="false"/>javaTypeResolver><javaModelGenerator targetPackage="cn.thinknovo.test" targetProject="src/main/java"><property name="enableSubPackages" value="false"/><property name="trimStrings" value="true"/>javaModelGenerator><sqlMapGenerator targetPackage="cn.thinknovo.test" targetProject="src/main/java"><property name="enableSubPackages" value="false"/>sqlMapGenerator><javaClientGenerator targetPackage="cn.thinknovo.test" targetProject="src/main/java"
                                 type="XMLMAPPER"><property name="enableSubPackages" value="false"/>javaClientGenerator>
          <table tableName="user" domainObjectName="User" enableCountByExample="false"
                   enableDeleteByExample="false" enableSelectByExample="false"
                   enableUpdateByExample="false"/>
        context>
    generatorConfiguration>
    
    (3)接着在idea右上角,点击edit

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    (4)开始配置mybatis-generator-maven-plugin运行

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    (5)输入运行命令mybatis-generator:generate -e

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    (6)点击保存,现在可以看到一个运行方式了,点击运行就可以自动得到内容了

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    (7)运行生成对应的文件

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    16.一对一映射

    类似于hibernate中的创建办法,模拟一个人员对应一个学号,创建两个pojo实体类,下面代码省略了set、get方法
    (1)第一个类是Iren人员类

    public class Iren {
      private long id;
      private String renyuanname;
      private long xuehaoid;
      private Ixuehao ixuehao;  //  添加一个学号类的对象
    

    (2)第二个类是Ixuehao学号类

    public class Ixuehao {
      private long id;
      private String xuehao;
    

    (3)创建一个Irenmapper.xml文件

    
    
    DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="cn.thinknovo.mybatis.pojo.IrenMapper">
        <select id="selectIren" resultMap="getOneToOneMap">
            select t1.id,t1.renyuanname,t1.xuehaoid,t2.id,t2.xuehao
            from iren t1,ixuehao t2
            where t1.xuehaoid = t2.id;
        select><resultMap id="getOneToOneMap" type="cn.thinknovo.mybatis.pojo.Iren"><id property="id" column="id"/><result property="renyuanname" column="renyuanname"/><result property="xuehaoid" column="xuehaoid"/><association property="ixuehao" javaType="cn.thinknovo.mybatis.pojo.Ixuehao"><id property="id" column="id"/><result property="xuehao" column="xuehao"/>association>resultMap>
    mapper>
    

    PS:这里使用到了resultMap标签,此标签中创建一对一的映射关系,在其中的id标签代表主键,result标签代表普通字段,association标签代表映射关系类

    PS:这里使用到了resultMap标签,此标签中创建一对一的映射关系,在其中的id标签代表主键,result标签代表普通字段,association标签代表映射关系类

    (4)创建一个Irenmapper接口

    public interface IrenMapper {
        List<Iren> selectIren();
    }
    

    (5)创建一个Console测试

    public static void main(String[] args) {
        try {
            Reader reader = Resources.getResourceAsReader("mybatis.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            SqlSession session = sqlSessionFactory.openSession(false);
            IrenMapper irenMapper = session.getMapper(IrenMapper.class); 
            List<Iren> list = irenMapper.selectIren();
            System.out.println(list.size());
            for(Iren iren : list) {
                System.out.println(iren.getRenyuanname());
                System.out.println(iren.getIxuehao().getXuehao());
            }
            session.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    (6)反向一对一处理
    在Ixuehao类中创建Iren的对象,然后创建对应的Ixuehao的mapper接口和xml文件,在配置resultMap时,把前面配置的两个表的参数互换,就可以实现反向一对一。

    <select id="selectIxuehao" resultMap="getOneToOneMap">
        select t1.id,t1.renyuanname,t1.xuehaoid,t2.id,t2.xuehao
        from iren t1,ixuehao t2
        where t1.xuehaoid = t2.id;
    select>
    <resultMap id="getOneToOneMap" type="cn.thinknovo.mybatis.pojo.Ixuehao">
        <id property="id" column="id"/>
        <result property="xuehao" column="xuehao"/>
        <association property="iren" javaType="cn.thinknovo.mybatis.pojo.Iren">
            <id property="id" column="id"/>
            <result property="renyuanname" column="renyuanname"/>
            <result property="xuehaoid" column="xuehaoid"/>
        association>
    resultMap>
    

    17.一对多映射

    基于班级和学生的关系建立映射,set、get方法省略
    (1)第一个类是Iclass班级类

    public class Iclass {
      private long id;
      private String cname;
      private List<Istudent> list;   // 这个班级中所有的学生
    

    (2)第二个类是Istudent学生类

    public class Istudent {
      private long id;
      private String sname;
      private long cid;
    

    (3)创建IclassMapper.xml文件

    
    
    DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="cn.thinknovo.mybatis.pojo.IclassMapper">
    
        <select id="selectIclass" resultMap="getOneToManyMap">
    	select t1.id,t1.cname,t2.id id2,t2.sname,t2.cid
            from iclass t1,istudent t2
            where t1.id = t2.cid and t1.id=4;
        select><resultMap id="getOneToManyMap" type="cn.thinknovo.mybatis.pojo.Iclass"><id property="id" column="id"/><result property="cname" column="cname"/><collection property="list" ofType="cn.thinknovo.mybatis.pojo.Istudent"><id property="id" column="id2"/><result property="sname" column="sname"/><result property="cid" column="cid"/>collection>resultMap>
    mapper>
    

    PS:这里注意的是,一对多使用的collection标签,并且mybatis自身bug,导致,当两张表的主键同名时,list中只有一个对象,解决这个问题的办法是把其中一个主键id改一个别名

    PS:这里注意的是,一对多使用的collection标签,并且mybatis自身bug,导致,当两张表的主键同名时,list中只有一个对象,解决这个问题的办法是把其中一个主键id改一个别名

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    (4)创建一个Iclassmapper接口

    public interface IclassMapper {
        Iclass selectIclass();
    }
    

    (5)创建一个Console测试

    public static void main(String[] args) {
        try {
            Reader reader = Resources.getResourceAsReader("mybatis.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            SqlSession session = sqlSessionFactory.openSession(false);
            IclassMapper iclassMapper = session.getMapper(IclassMapper.class);
            Iclass iclass = iclassMapper.selectIclass();
            System.out.println(iclass.getCname());
            System.out.println(iclass.getList());
            for(Istudent istudent : iclass.getList()) {
                System.out.println(istudent.getSname());
            }
            session.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    (6)反向多对一处理
    在mybatis里面其实没有多对一的说法,多对一只能看做是一对一,所以我们需要在Istudent中增加Iclass对象:

    public class Istudent {
      private long id;
      private String sname;
      private long cid;
      private Iclass iclass;  // 增加班级对象
    

    创建一个IstudentMapper.xml文件:

    
    
    DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="cn.thinknovo.mybatis.pojo.IstudentMapper">
    
      <select id="selectIstudent" resultMap="getOneToOneMap">
            select t1.id,t1.cname,t2.id id2,t2.sname,t2.cid
            from iclass t1,istudent t2
            where t1.id = t2.cid and t2.id=2;
        select><resultMap id="getOneToOneMap" type="cn.thinknovo.mybatis.pojo.Istudent"><id property="id" column="id2"/><result property="sname" column="sname"/><result property="cid" column="cid"/><association property="iclass" javaType="cn.thinknovo.mybatis.pojo.Iclass"><id property="id" column="id"/><result property="cname" column="cname"/>association>resultMap>
    mapper>
    

    PS:这里使用到的是一对一的处理法则,所以使用的一对一的标签association

    PS:这里使用到的是一对一的处理法则,所以使用的一对一的标签association

    然后创建IstudentMapper接口,编写测试类完成,这里省略…

    18.多对多映射

    还是基于订购商品操作,一个用户可以对应多个商品,一个商品可以对应多个订单,其实在mybatis实现多对多映射操作,类似于一对多映射,只是SQL编写的相对复杂一些,因为涉及到了中间表。
    (1)第一个类是Ishangpin商品的类

    public class Ishangpin {
      private long id;
      private String shangpinname;
      private List list;        // list代表多个购买者
    

    (2)第二个类是Igoumai购买者的类

    public class Igoumai {
      private long id;
      private String goumainame;
    

    (3)创建IshangpinMapper.xml文件

    
    
    DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="cn.thinknovo.mybatis.pojo.IshangpinMapper">
    
        <select id="selectIshangpin" resultMap="getManyToManyMap">
            select
                t1.shangpinid,
                t1.goumaiid,
                t2.id,
                t2.goumainame,
                t3.id id2,
                t3.shangpinname
            from
                idingdan t1,
                igoumai t2,
                ishangpin t3
            where t1.goumaiid=t2.id and t1.shangpinid=t3.id and t1.shangpinid=6;
        select><resultMap id="getManyToManyMap" type="cn.thinknovo.mybatis.pojo.Ishangpin"><id property="id" column="id2"/><result property="shangpinname" column="shangpinname"/><collection property="list" ofType="cn.thinknovo.mybatis.pojo.Igoumai"><id property="id" column="id"/><result property="goumainame" column="goumainame"/>collection>resultMap>
    mapper>
    

    PS:这个配置文件中有多处需要注意的地方,1.查看SQL的编写,三表关联查询;2.resultMap中涉及的还是collection标签;3.两张表的id主键的名字不能相同,必须保证其中一个是别名

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    PS:这个配置文件中有多处需要注意的地方,1.查看SQL的编写,三表关联查询;2.resultMap中涉及的还是collection标签;3.两张表的id主键的名字不能相同,必须保证其中一个是别名

    (4)创建一个IshangpinMapper接口

    public interface IshangpinMapper {
        List<Ishangpin> selectIshangpin();
    }
    

    (5)创建一个Console测试

    IshangpinMapper ishangpinMapper = session.getMapper(IshangpinMapper.class);
    List<Ishangpin> list = ishangpinMapper.selectIshangpin();
    System.out.println(list);
    System.out.println(list.get(0).getShangpinname());
    System.out.println(list.get(0).getList());
    System.out.println(list.get(0).getList().get(0).getGoumainame());
    

    (6)反向多对多处理
    原理和上述一致,只需要在购买者中的增加商品的list,并且配置购买者的mapper接口和XML文件即可。

    19.缓存

    一级缓存SqlSession

    1. 应用程序和数据库交互的过程是一个相对比较耗时的过程
    2. 缓存存在的意义:让应用程序减少对数据库的访问,提升程序运行效率
    3. MyBatis 中默认 SqlSession 缓存开启
      3.1 同一个 SqlSession 对象调用同一个时,只有第一次访问数据库,第一次之后把查询结果缓存到SqlSession缓存区(内存)中
      3.2 缓存的是 statement 对象.(简单记忆必须是用一个是用一个),在 myabtis 时一个对应一个 statement 对象
      3.3 有效范围必须是同一个 SqlSession 对象
      缓存流程:
      步骤一: 先去缓存区中找是否存在 statement
      步骤二:返回结果
      步骤三:如果没有缓存 statement 对象,去数据库获取数据
      步骤四:数据库返回查询结果
      步骤五:把查询结果放到对应的缓存区中

    二级缓存SqlSessionFactory 缓存

    有效范围:同一个 factory 内哪个 SqlSession 都可以获取
    什么时候使用二级缓存:当数据频繁被使用,很少被修改
    使用二级缓存步骤:
    步骤一:在 mapper.xml 中添加
    步骤二:如果不写 readOnly=”true”需要把实体类序列化

    步骤三:当 SqlSession 对象 close()时或 commit()时会把 SqlSession 缓存的数据刷(flush)到 SqlSessionFactory 缓存区中

    ngpin();
    System.out.println(list);
    System.out.println(list.get(0).getShangpinname());
    System.out.println(list.get(0).getList());
    System.out.println(list.get(0).getList().get(0).getGoumainame());

    
    (6)反向多对多处理
    原理和上述一致,只需要在购买者中的增加商品的list,并且配置购买者的mapper接口和XML文件即可。
    
    ## 缓存
    
    ### 一级缓存SqlSession
    
    1. 应用程序和数据库交互的过程是一个相对比较耗时的过程 
    2. 缓存存在的意义:让应用程序减少对数据库的访问,提升程序运行效率
    3. MyBatis 中默认 SqlSession 缓存开启
    3.1 同一个 SqlSession 对象调用同一个),在 myabtis 时一个