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>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>8.0.31</version>
</dependency>
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.4.6</version>
</dependency>
第二项,添加mybatis.xml文件
<?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>
        <!--当返回行的所有列都是空时,MyBatis默认返回null-->
        <setting name="returnInstanceForEmptyRow" value="true"/>
	<!--显示sql语句-->
<setting name="logImpl" value="STDOUT_LOGGING"/>

    </settings>

    <environments default="development">

        <environment id="development">
            <!--使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域-->
            <transactionManager type="JDBC"/>
            <!-- mybatis提供了3种数据源类型,分别是:POOLED,UNPOOLED,JNDI -->
            <!-- POOLED 表示支持JDBC数据源连接池 -->
            <!-- UNPOOLED 表示不支持数据源连接池 -->
            <!-- JNDI 表示支持外部数据源连接池 -->
            <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>
        <!-- 映射文件方式1,一个一个的配置
        <mapper resource="cn/thinknovo/pojo/UserMapper.xml"/>-->
        <!-- 映射文件方式2,自动扫描包内的Mapper接口与配置文件 -->
        <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>
        <!-- 映射文件方式1,一个一个的配置
        <mapper resource="cn/thinknovo/pojo/UserMapper.xml"/>-->
        <!-- 映射文件方式2,自动扫描包内的Mapper接口与配置文件 -->
        <package name="cn/thinknovo/pojo"/>
    </mappers>

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

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

<resources>
  <resource>
    <directory>src/main/java</directory>
    <includes>
      <include>**/*.xml</include>
    </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(“内容”)参数中内容

<!-- 当多参数时,不需要写 parameterType -->
<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的路径和文件名,修改为自己想要的,其余不做修改:
<?xml version="1.0" encoding="UTF-8"?>

<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.0</modelVersion>

  <groupId>cn.thinknovo</groupId>
  <artifactId>mybatis002</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>mybatis002 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.46</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.6</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis.generator</groupId>
      <artifactId>mybatis-generator-core</artifactId>
      <version>1.3.6</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>mybatis002</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin><plugin><!--Mybatis-generator插件,用于自动生成Mapper和POJO--><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.6</version><configuration><!--配置文件的位置--><configurationFile>src\main\resources\mybatis-generator-config.xml</configurationFile><verbose>true</verbose><overwrite>true</overwrite></configuration><executions><execution><id>Generate MyBatis Artifacts</id><goals><goal>generate</goal></goals></execution></executions><dependencies><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.3.6</version></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类名

完整配置如下:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE generatorConfiguration PUBLIC
        "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration><!-- 本地数据库驱动程序jar包的全路径 --><classPathEntry location="C:\Users\Administrator\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar"/><!-- 指定mybatis版本 --><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"/><!--指定生成的类型为java类型,避免数据库中number等类型字段 --><javaTypeResolver><property name="forceBigDecimals" value="false"/></javaTypeResolver><!-- 实体类生成的位置  修改targetPackage和targetProject--><javaModelGenerator targetPackage="cn.thinknovo.test" targetProject="src/main/java"><property name="enableSubPackages" value="false"/><property name="trimStrings" value="true"/></javaModelGenerator><!-- *Mapper.xml 文件的位置  修改targetPackage和targetProject--><sqlMapGenerator targetPackage="cn.thinknovo.test" targetProject="src/main/java"><property name="enableSubPackages" value="false"/></sqlMapGenerator><!-- Mapper 接口文件的位置  修改targetPackage和targetProject--><javaClientGenerator targetPackage="cn.thinknovo.test" targetProject="src/main/java"
                             type="XMLMAPPER"><property name="enableSubPackages" value="false"/></javaClientGenerator><!-- 相关表的配置 多表就配置多个  tableName表名  domainObjectName类名 -->
      <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文件

<?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.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文件

<?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.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文件:

<?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.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<Igoumai> list;        // list代表多个购买者

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

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

(3)创建IshangpinMapper.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.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”需要把实体类序列化
<cache readOnly=” true”></ cache >
步骤三:当 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 对象调用同一个<select>时,只有第一次访问数据库,第一次之后把查询结果缓存到SqlSession缓存区(内存)中
3.2 缓存的是 statement 对象.(简单记忆必须是用一个是用一个<select>),在 myabtis 时一个<select>对应一个 statement 对象
3.3 有效范围必须是同一个 SqlSession 对象
缓存流程:
步骤一: 先去缓存区中找是否存在 statement
步骤二:返回结果
步骤三:如果没有缓存 statement 对象,去数据库获取数据
步骤四:数据库返回查询结果
步骤五:把查询结果放到对应的缓存区中

### 二级缓存SqlSessionFactory 缓存

有效范围:同一个 factory 内哪个 SqlSession 都可以获取
什么时候使用二级缓存:当数据频繁被使用,很少被修改
使用二级缓存步骤:
步骤一:在 mapper.xml 中添加
步骤二:如果不写 readOnly=”true”需要把实体类序列化
<cache readOnly=” true”></ cache >
步骤三:当 SqlSession 对象 close()时或 commit()时会把 SqlSession 缓存的数据刷(flush)到 SqlSessionFactory 缓存区中









本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/677108.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Amazon云计算AWS(四)

目录 八、其他Amazon云计算服务&#xff08;一&#xff09;快速应用部署Elastic Beanstalk和服务模板CloudFormation&#xff08;二&#xff09;DNS服务Router 53&#xff08;三&#xff09;虚拟私有云VPC&#xff08;四&#xff09;简单通知服务和简单邮件服务&#xff08;五&…

list(二)和_stack_queue

嗨喽大家好&#xff0c;时隔许久阿鑫又给大家带来了新的博客&#xff0c;list的模拟实现&#xff08;二&#xff09;以及_stack_queue&#xff0c;下面让我们开始今天的学习吧&#xff01; list(二)和_stack_queue 1.list的构造函数 2.设计模式之适配器和迭代器 3.新容器de…

HMI-Board之LVGL应用

移植 使用默认模板工程新建一个RT-Thread项目&#xff0c;BSP版本为1.1.1 打开RT-Thread Settings&#xff0c;点击右侧箭头按钮进入详细页&#xff0c;在硬件栏开启以下几个配置选项&#xff08;LCD、触摸屏、demo&#xff09; 此时&#xff0c;打开board文件夹&#xff0c;发…

OSI协议集

国际标准化组织除了定义osi参考模型之外&#xff0c;还开发了实现7个功能层次的各种协议和服务标准&#xff0c;这些协议和服务统称为osi协议。osi协议是一些已有的协议和iso新开发的协议的混合体&#xff0c;例如&#xff0c;大部分物理层和数据链路层协议是采用现有的协议&am…

Postgre pg_fdw(foreign data wrappers)部署 实现PG到PG之间数据同步

结构&#xff1a; 主机名ip操作系统PG192.168.80.9centos7.9qilin192.168.80.99中标麒麟v7.0 fdw支持同构或异构数据库之间的访问。 部署FDW 需要在客户端部署。 1.编译postgre_fdw cd /usr/local/postgresql-12.4/contrib/postgres_fdwmakemake install 一般这里面会报权限…

雷池WAF-动态防护新功能体验

雷池WAF 雷池WAF&#xff08;Web Application Firewall&#xff0c;网络应用防火墙&#xff09;是由长亭科技开发的一个网络安全产品&#xff0c;它专注于保护Web应用免受黑客攻击。 今天主要讲的是长亭雷池最近新出的功能&#xff1a;动态防护 安装 雷池WAF支持多种安装方式…

【Linux】网络管理

1、查看网络管理程序的状态 systemctl status NetworkManager 2、查看网络子管理程序的状态 systemctl status network 配置网络的工具 1、图形界面网络设置 步骤如下&#xff1a; 还可在命令行输入&#xff1a; nmtui 或者&#xff1a; nm-connection-editor 打开…

Qt_C++ RFID网络读卡器Socket Udp通讯示例源码

本示例使用的设备&#xff1a; WIFI/TCP/UDP/HTTP协议RFID液显网络读卡器可二次开发语音播报POE-淘宝网 (taobao.com) #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QHostInfo> #include <QNetworkInterface> #include <…

[论文笔记]Mistral 7B

引言 今天带来大名鼎鼎的Mistral 7B的论文笔记。 作者推出了Mistral 7B&#xff0c;这是一个70亿参数的语言模型。Mistral 7B在所有评估基准中表现优于最佳的13B开源模型&#xff08;Llama 2&#xff09;&#xff0c;并且在推理、数学和代码生成方面胜过最佳发布的34B模型(Ll…

Patchwork++:基于点云的快速、稳健的地面分割方法

1. 背景 论文发表在2022IROS&#xff0c;是Patchwork的改进版本。算法通过数学方法进行快速而鲁棒性很强的地面分割&#xff0c;在智能机器人上的可操作性非常强。通过微调算法&#xff0c;可以应用于16-beams等多种规格的激光雷达。由于激光雷达点云数据标注的难度非常大&…

苹果CMS:怎么添加2019和2020年份筛选

我们进入搜索的时候看到一个关于年份的搜索&#xff0c;那如果上面没有出现19,20我们该如何处理呢&#xff1f; 我们进入管理后台 -【系统】-【网站参数配置】-【预留参数】 添加下视频年代逗号隔开即可 如果要设置地区&#xff0c;语言也实在这里直接配置即可&#xff01;&am…

新书推荐:1.3 内存管理模式

本节必须掌握的知识点&#xff1a; 4GB虚拟空间 虚拟内存 多任务切换 1.3.1 4GB虚拟空间 ■Win16操作系统 Windows1.0版本为16位操作系统&#xff0c;支持16位处理器实模式&#xff0c;最大寻址空间为1MB。Win16操作系统的内存管理非常简单&#xff0c;采用分段内存管理模式…

企业微信hook接口协议,ipad协议http,发送CDN语音消息

发送CDN语音消息 参数名必选类型说明uuid是String每个实例的唯一标识&#xff0c;根据uuid操作具体企业微信send_userid是long要发送的人或群idisRoom是bool是否是群消息 请求示例 {"uuid":"1753cdff-0501-42fe-bb5a-2a4b9629f7fb","send_userid&q…

树莓派4B 学习笔记3: 系统自动更新时间_测试CSI摄像头_安装OpenCv_4.6(未成功编译源码)_备份树莓派镜像

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本文我只是安装了OpenCv 4.6&#xff0c;但编译源码失败了&#xff01;有关 OpenCv 部分仅做笔记暂存&#xff01; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令…

平板显示LED背光芯片OC6700,输入3.6V~60V,升压型 LED 恒流驱动器

概述 OC6700是一款内置60V功率NMOS高效率、高精度的升压型大功率LED恒流驱动芯片。OC6700采用固定关断时间的控制方式&#xff0c;关断时间可通过外部电容进行调节&#xff0c;工作频率可根据用户要求而改变。OC6700通过调节外置的电流采样电阻&#xff0c;能控制高亮度LED灯的…

汇编:数据定义数据填充

数组的定义 在32位汇编语言中&#xff0c;定义数组时&#xff0c;通常使用定义数据指令&#xff08;如 DB, DW, DD,DQ &#xff09;和标签来指定数组的名称和内容。DB定义字节数组&#xff08;每个元素占1字节&#xff09;、DW定义字数组&#xff08;每个元素占2字节&#xff…

【AI基础】第二步:安装AI运行环境

开局一张图&#xff1a; 接下来按照从下往上的顺序来安装部署。 规则1 注意每个层级的安装版本&#xff0c;上层的版本由下层版本决定 比如CUDA的版本&#xff0c;需要看显卡安装了什么版本的驱动&#xff0c;然后CUDA的版本不能高于这个驱动的版本。 这个比较好理解&#xff…

注意力机制篇 | YOLOv8改进之引入STA(Super Token Attention)超级令牌注意力机制 | CVPR2023

前言:Hello大家好,我是小哥谈。超级令牌注意力机制是一种基于Transformer的模型,用于处理长文本序列的任务。它通过引入超级令牌(Super Token)来减少输入序列中的填充标记,从而提高计算效率和模型性能。🌈 目录 🚀1.基础概念

1.4 Unicode简介

现在的Windows操作系统有许多不同语言版本&#xff0c;可以支持所有国家现有的语言文字。这就涉及到不同字符集的编码规则。 本节必须掌握的知识点&#xff1a; 字符集 C语言款字符 宽字符和Windows 1.4.1 字符集 ■ANSI多字节字符集 ●ASCII码 现代计算机发源于美国&…

一分钟了解香港的场外期权报价

香港的场外期权报价 在香港这个国际金融中心&#xff0c;场外期权交易是金融市场不可或缺的一部分。场外期权&#xff0c;作为一种非标准化的金融衍生品&#xff0c;为投资者提供了在特定时间以约定价格买入或卖出某种资产的机会。对于希望参与这一市场的投资者来说&#xff0…