Mybatis笔记总结

MyBatis总结

1.SSM框架介绍(Spring+SpringMVC+MyBatis)
Junit测试、log4j日志
2.MyBatis框架
1)MyBatis框架介绍(ORM对象关系映射)工作在三层架构持久层
2)MyBatis的第一个程序:student插入信息
MyBatis的主配置文件:连接数据库的四要素
映射文件:Sql语句
实现类:SqlSessionFactoryBuilder->SqlSessionFactory->SqlSession->执行sql命令
3)配置文件解析:定义别名、加载属性文件、注册映射文件、配置多个连接环境、使用日志、定义工具类
4)单表的增删改查(CURD)
5)mapper的动态代理实现增删改查
使用动态代理条件:
接口和对应映射文件在同一包下、映射文件的namespace应该是接口的全限定性类名、sqlSession.getMapper(映射文件对应接口.class)
6)动态SQL标签
、、、、sql片段
7)关联关系查询:1:n、n:1、1:1、n:m、自关联
多表连接查询、多表单独查询
的用法
8)字段名和属性名不一致:起别名、resultMap
9)延迟加载:关联关系中关联对象的多表单独查询能使用延迟加载策略
直接加载默认的
侵入式延迟加载
深度延迟加载
延迟加载的开关:主配置文件中
10)缓存
一级缓存和二级缓存(作用范围都是namespace)
一级缓存的生命周期和SQLSession相同
二级缓存的生命周期和整个应用的生命周期相同
一级缓存默认开启,无开关设置
二级缓存默认关闭,可以设置打开或关闭
二级缓存的全局开关在主配置文件中默认为true
映射文件中可以打开在该命名空间的二级缓存
在映射文件中的也可以单独设置使用不使用二级缓存,用useCache
11)MyBatis注解
注解的基本用法:@Insert、@Update、@Delete、@Select
使用动态Sql:@InsertProvider、@UpdateProvider、@DeleteProvider、@SelectProvider
生成动态sql的方法:字符串拼接(StringBuffer)、SQL类(匿名内部类)

一、第一个mybatis程序
  1. 在pow文件中导入mybatis相关包
<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.21</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

2.编写mybatis核心配置文件
在这里插入图片描述
3.创建bean类

package com.wcc.beans;
public class Student {
    private Integer id;
    private String name;
    private int age;
    private double score;

    public Student() {
    }

    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}

4.创建dao接口类

package com.wcc.dao;

import com.wcc.beans.Student;

public interface IStudentDao {
    void insertStudent(Student student);
}

5.创建dao接口实现类

package com.wcc.dao;

import com.wcc.beans.Student;
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;

/*
* 1.SqlSessionFactoryBuilder
* 2.SqlSessionFactory
* 3.SqlSession
* */
public class StudentDaoImpl implements IStudentDao {
    @Override
    public void insertStudent(Student student) {
        SqlSession session = null;
        try {
            //1.创建SqlSessionFactoryBulider对象
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            //2.加载主配置文件为InputStream类型
            InputStream is = Resources.getResourceAsStream("mybatis.xml");
            //3.由builder创建SqlSessionFactory
            SqlSessionFactory factory = builder.build(is);
            //4.由factory创建SqlSession
            session = factory.openSession();
            //5.执行插入命令
            session.insert("insertStu",student);
            //6.提交
            session.commit();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //7.关闭SqlSession
            if (session != null){
                session.close();
            }
        }
    }
}

6.创建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为dao接口层的权限定性接口名
<mapper namespace="com.wcc.dao.IStudentDao">
    //parameterType为POJO的权限定性类名
    <insert id="insertStu" parameterType="com.wcc.beans.Student">
        insert into student (name,age,score) values (#{name},#{age},#{score})
    </insert>
</mapper>

7.创建测试类
*/

public class MyTest
{
    @Test
    public void test()
    {
        IStudentDao studentDao = new StudentDaoImpl();
        Student student = new Student("小明",20,98.5);
        studentDao.insertStudent(student);
    }
}
二、优化dao接口实现类

1.将sqlSessionFactory定义为单例模式,提前将Sqlsession创建出来。这样dao的实现类每次增删改查就不用在创建sqlSession了。

package com.yyf.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 {
    //因为SqlSessionFactory是重量级组件,把它定义为单例的对象
    private static SqlSessionFactory factory = null;
    public static SqlSession getSqlSession() throws IOException {
        if (factory == null){
            factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis.xml"));
        }
        return factory.openSession();
    }
}

2.添加log2j日志,便于调试程序
1)在pow文件中引入log2j的依赖

  <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.12.1</version>
    </dependency>

2)java目录下编写log2j2.xml文件

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

<configuration status="OFF">
	<appenders>
		<Console name="myConsole" target="SYSTEM_OUT">
			<PatternLayout pattern="[%-5p] %m%n" />
		</Console>
	</appenders>
	
	<loggers>
		<logger name="com.yyf.dao.IStudentDao" level="trace" additivity="false">
			<appender-ref ref="myConsole" />
		</logger>
		<!--<root level="debug">
			<appender-ref ref="myConsole" />
		</root>-->
	</loggers>
</configuration>

3.给主配置文件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>
    <!--加载jdbc属性文件-->
    <properties resource="jdbc.properties"/>

    <!--给实体类定义别名-->
    <typeAliases>
        <!--给指定的类定义指定的别名-->
        <!--<typeAlias type="com.yyf.beans.Student" alias="Stu"/>-->
        <!--给指定包下所有的类起别名,默认别名为该类的简单类名-->
        <package name="com.yyf.beans"/>
    </typeAliases>

    <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.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
        <!--<environment id="oracle">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>-->
    </environments>**加粗样式**
    <mappers>
        <!--注册映射文件-->
        <!--
            resource一般加载的是内部资源映射文件
        -->
        <!--<mapper resource="com/yyf/dao/mapper.xml"/>-->
        <!--url一般加载项目的外部资源-->
        <!--<mapper url=""/>-->
        <!--
            1.映射文件和对应的接口在同一个包下
            2.映射文件的名称必须和接口的简单类名相同
            3.映射文件中namespace的值必须是对应接口的全限定性类名
        -->
        <!--<mapper class="com.yyf.dao.IStudentDao"/>-->
        <!--
            1.映射文件和对应的接口在同一个包下
            2.映射文件的名称必须和接口的简单类名相同
            3.映射文件中namespace的值必须是对应接口的全限定性类名
            4.(可以不满足)使用动态mapper
        -->
        <package name="com.yyf.dao"/>

    </mappers>
</configuration>

4.将sqlSessionFactory定义为单例模式后的dao接口实现类

package com.yyf.dao;

import com.yyf.beans.Student;
import com.yyf.utils.MyBatisUtil;
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;
import java.util.List;
/*
* 1.SqlSessionFactoryBuilder
* 2.SqlSessionFactory
* 3.SqlSession
* */
public class StudentDaoImpl implements IStudentDao {
    //插入学生信息
    @Override
    public void insertStudent(Student student) {
        SqlSession session = null;
        try {
            //1.通过工具类获取SqlSession对象
            session = MyBatisUtil.getSqlSession();
            //2.执行插入命令
            session.insert("insertStu",student);
            //3.提交
            session.commit();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //4.关闭SqlSession
            if (session != null){
                session.close();
            }
        }
    }
三、使用mapper代理

使用Mapper的动态代理要求:
* 1.sqlSession.getMapper()中的参数为所要代理接口的类型
* 2.映射文件的namespace属性值必须为所代理接口的全限定性类名
* 3.映射文件中的statement的id必须和代理接口中的相应方法名称相同
1.测试类中直接调用sqlSession

package com.yyf;
import static javafx.scene.input.KeyCode.I;
import static org.junit.Assert.assertTrue;
import com.yyf.beans.Student;
import com.yyf.dao.IStudentDao;
import com.yyf.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MyTest
{
    /**
     * 使用Mapper的动态代理要求:
     * 1.sqlSession.getMapper()中的参数为所要代理接口的类型
     * 2.映射文件的namespace属性值必须为所代理接口的全限定性类名
     * 3.映射文件中的statement的id必须和代理接口中的相应方法名称相同
     */
    SqlSession sqlSession = null;
    IStudentDao studentDao = null;
    @Before
    public void before() throws IOException {
        sqlSession = MyBatisUtil.getSqlSession();
        studentDao = sqlSession.getMapper(IStudentDao.class);
        System.out.print("代理:"+studentDao);
    }

    @After
    public void after(){
        if (sqlSession != null){
            sqlSession.close();
        }
    }
    //学生信息插入
    @Test
    public void test01()
    {
        Student student = new Student("小明3",20,98.5);
        studentDao.insertStudent(student);
        sqlSession.commit();
        System.out.print("插入后:"+student);
    }
  }

1.1小知识点
使用动态代理查询时,会根据所需要的结果默认调用方法selectList或selectOne方法。
如果返回结果为List,则默认调用selectList方法,否则都默认调用selectOne方法
如果需要返回map时,需要在对应的方法接口上添加注解@MapKey(value=“对应字段名”)
dao接口中代码

@MapKey(value = "name")
    Map<String,Student> selectAllStudentMap();

对应xml中代码

  <select id="selectAllStudentMap" resultType="Student">
        select id,name,age,score from student
    </select>

对应测试类中的代码

  //使用动态代理查询时,会根据需要的返回结果默认调用方法selectList或selectOne,
    //如果返回结果为List,则默认调用selectList方法,否则都默认调用selectOne方法
    //如果需要返回map时,需要在对应的接口方法上添加注解@MapKey(value="")
    //查询全部学生信息Map
    @Test
    public void test08()
    {
        Map<String,Student> map = studentDao.selectAllStudentMap();
        System.out.println(map.get("小明"));
    }

1.2小知识点
如果在接口层需要传入2个或者多个参数时,需要使用@Param()注解
1.3小知识点
总结:#{}中间可以填写什么内容
1.传入参数为对象时,中间写对象的属性名
2.传入参数为一个基本数据类型或String类型,中间写任意值,就是一个占位符
3.传入参数为map,map的key对应的值是基本数据类型,中间写map的key
4.传入参数为map,map的key对应的值是对象,中间写map的key.属性

List<Student> selectStudentByCondition3(@Param("name") String name,@Param("age") int age);

注解可以和参数名相同也可以不同,#{}这里填写Param中矫正的参数名

1.4常用查询语句

<?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.yyf.dao.IStudentDao">

    <!--
        1.parameterType可以省略,如果不省略就必须写正确
        2.传入的参数是一个对象,#{对象的属性名},默认调用对象属性的get方法
    -->
    <insert id="insertStudent">
        insert into student (name,age,score) values (#{name},#{age},#{score})
    </insert>

    <delete id="deleteStudentById">
        delete from student where id = #{id}
    </delete>

    <update id="updateStudent">
        update student set name=#{name},age=#{age},score=#{score} where id=#{id}
    </update>

    <insert id="insertStudentCatchId">
        insert into student (name,age,score) values (#{name},#{age},#{score})
        <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
            <!--select @@identity-->
            select last_insert_id()
        </selectKey>
    </insert>

    <!--
        resultType或者resultMap是必须的,并不是集合的类型,而是集合中单个元素的类型
    -->
    <select id="selectAllStudent" resultType="Student">
        select id,name,age,score from student
    </select>

    <select id="selectAllStudentMap" resultType="Student">
        select id,name,age,score from student
    </select>

    <select id="selectStudentById" resultType="Student">
        select id,name,age,score from student where id = #{id}
    </select>

    <select id="selectStudentByName" resultType="Student">
        select id,name,age,score from student where name like '%' #{name} '%'
        <!--select id,name,age,score from student where name like concat('%',#{name},'%')-->
        <!--select id,name,age,score from student where name like '%${value}%'-->
    </select>

    <select id="selectStudentByCondition" resultType="Student">
        select id,name,age,score from student
        where name like '%' #{name} '%' and age &lt; #{age}
    </select>

    <select id="selectStudentByCondition2" resultType="Student">
        <!--select id,name,age,score from student
        where age &gt; #{min} and age &lt; #{max}-->
        select id,name,age,score from student
        where age &gt; #{stu1.age} and age &lt; #{stu2.age}
    </select>

    <select id="selectStudentByCondition3" resultType="Student">
        select id,name,age,score from student
        where name like '%' #{name} '%' and age &lt; #{age}
    </select>
    <!--
        总结:#{}中间可以填写什么内容
        1.传入参数为对象时,中间写对象的属性名
        2.传入参数为一个基本数据类型或String类型,中间写任意值,就是一个占位符
        3.传入参数为map,map的key对应的值是基本数据类型,中间写map的key
        4.传入参数为map,map的key对应的值是对象,中间写map的key.属性
    -->
</mapper>
四、动态sql语句

1.if的使用

 <select id="selectStudentByIf" resultType="Student">
        select id,name,age,score from student where 1=1
        <if test="name != null and name != ''">
            and name like '%' #{name} '%'
        </if>
        <if test="age > 0">
            and age &lt; #{age}
        </if>
    </select>

注意:如果没有写1=1 会报错
2.where的使用

 <select id="selectStudentByWhere" resultType="Student">
        select id,name,age,score from student
        <where>
            <if test="name != null and name != ''">
                name like '%' #{name} '%'
            </if>
            <if test="age > 0">
                and age &lt; #{age}
            </if>
        </where>
    </select>

注意:当where和if搭配时,第一个if标签不要加and,其他的加and
3.choose when otherwise标签

 <!--
        如果输入了name查询条件,不论age有没有输入,都只按照name查询;
        如果没有输入name,只输入了age,按照age条件查询;
        如果两个都没有输入,查询不到任何结果。
    -->
    <select id="selectStudentByChoose" resultType="Student">
        select id,name,age,score from student
        <where>
            <choose>
                <when test="name != null and name != ''">
                    name like '%' #{name} '%'
                </when>
                <when test="age > 0">
                    age &lt; #{age}
                </when>
                <otherwise>
                    1!=1
                </otherwise>
            </choose>
        </where>
    </select>

4.1foreach标签 传入array数组

<select id="selectStudentByForeachArray" resultType="Student">
        select id,name,age,score from student
        <if test="array != null and array.length > 0">
            where id in
            <foreach collection="array" item="id" open="(" close=")" separator=",">
                #{id}
            </foreach>
        </if>
    </select>

4.2foreach标签 传入list集合

<select id="selectStudentByForeachList" resultType="Student">
        select id,name,age,score from student
        <if test="list != null and list.size > 0">
            where id in
            <foreach collection="list" item="id" open="(" close=")" separator=",">
                #{id}
            </foreach>
        </if>
    </select>

4.3foreach标签 传入list《T》集合

<select id="selectStudentByForeachList2" resultType="Student">
        select id,name,age,score from student
        <if test="list != null and list.size > 0">
            where id in
            <foreach collection="list" item="stu" open="(" close=")" separator=",">
                #{stu.id}
            </foreach>
        </if>
    </select>

5.sql标签 include标签 用于替换重复sql语句

<select id="selectStudentByFragment" resultType="Student">
    <include refid="xxx"/>
    <if test="list != null and list.size > 0">
        where id in
        <foreach collection="list" item="stu" open="(" close=")" separator=",">
            #{stu.id}
        </foreach>
    </if>
</select>
<sql id="xxx">
    select id,name,age,score from student
</sql>

6.if+set标签
修改用户信息时有时候不会修改全部,就使用set标签

<update id="modify" parameterType="User">
update user 
  <set>
      <if test="name!=null">
        name=#{name}
     </if>
     </set>
         where id = #{id}
   </update>

7.if+trim

<update id="modify" parameterType="User">
update user 
  <trim prefix="set" suffixOverrides="," suffix="where id = #{id}">
      <if test="name!=null">
        name=#{name}
     </if>
     </trim>
   </update>
五,关联关系查询

1.一对多(多表连接查询)
1.1实体类的定义(只展示重要部分)

//一方为主查询,关联属性定义在一方
public class Country {
    private Integer cid;
    private String cname;
    //关联属性
    private Set<Minister> ministers;
public class Minister {
    private Integer mid;
    private String mname;

1.2.dao接口

public interface ICountryDao {
    Country selectCountryById(int id);
}

1.3.映射文件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="com.yyf.dao.ICountryDao">
    <!--多表链接查询-->
    <resultMap id="countryMap" type="Country">
        <id column="cid" property="cid"/>
        <result column="cname" property="cname"/>
        <collection property="ministers" ofType="Minister">
            <id column="mid" property="mid"/>
            <result column="mname" property="mname"/>
        </collection>
    </resultMap>
    <select id="selectCountryById" resultMap="countryMap">
        select cid,cname,mid,mname from country,minister
        where cid=#{id} and countryId=cid
    </select>
</mapper>

注意:属性类型为集合类型时 用collection标签 类型用ofType

<collection property="ministers" ofType="Minister">

属性类型为普通类型时用association 标签 类型用javaType

 <association property="ministers" javaType="Minister"> </association>

2.一对多(多表单独查询)

<!--多表单独查询-->
<select id="selectMinisterByCountryId" resultType="Minister">
    select mid,mname from minister where countryId=#{cid}
</select>
<resultMap id="countryMap" type="Country">
    <id column="cid" property="cid"/>
    <result column="cname" property="cname"/>
    <collection property="ministers"
                ofType="Minister"
                select="selectMinisterByCountryId"
                column="cid">
    </collection>
</resultMap>
<select id="selectCountryById" resultMap="countryMap">
    select cid,cname from country
    where cid=#{id}
</select>

3.多对一(多表连接查询)
3.1实体类

//一方为主查询,关联属性定义在一方
public class Country {
    private Integer cid;
    private String cname;
//以多方为主查询,关联属性定义在多方
public class Minister {
    private Integer mid;
    private String mname;
    //关联属性,多对一关联属性是一个对象
    private Country country;

3.2dao接口

public interface IMinisterDao {
    Minister selectMinisterById(int id);
}

3.3映射文件xml

<resultMap id="ministerMap" type="Minister">
    <id column="mid" property="mid"/>
    <result column="mname" property="mname"/>
    <association property="country" javaType="Country">
        <id column="cid" property="cid"/>
        <result column="cname" property="cname"/>
    </association>
</resultMap>
<select id="selectMinisterById" resultMap="ministerMap">
    select mid,mname,cid,cname from minister,country
    where mid=#{id} and cid =countryId
</select>

4.多对一(多表单独查询)

<!--多表单独查询-->
<select id="selectCountryById" resultType="Country">
    select cid,cname from country where cid = #{countryId}
</select>
<resultMap id="ministerMap" type="Minister">
    <id column="mid" property="mid"/>
    <result column="mname" property="mname"/>
    <association property="country"
                 javaType="Country"
                 select="selectCountryById"
                 column="countryId"/>
</resultMap>
<select id="selectMinisterById" resultMap="ministerMap">
    select mid,mname,countryId from minister where mid = #{id}
</select>

5.一对一(多表连接查询)
5.1实体类

public class Husband {
    private Integer hid;
    private String hname;
    //关联属性
    private Wife wife;
public class Wife {
    private Integer wid;
    private String wname;

5.2dao接口

public interface IHusbandDao {
    Husband selectHusbandById(int id);
}

5.3映射文件xml

    <!--1:1多表连接查询-->
<resultMap id="husbandMap" type="Husband">
    <id column="hid" property="hid"/>
    <result column="hname" property="hname"/>
    <association property="wife" javaType="Wife">
        <id column="wid" property="wid"/>
        <result column="wname" property="wname"/>
    </association>
</resultMap>
<select id="selectHusbandById" resultMap="husbandMap">
    select hid,hname,wid,wname from husband,wife
    where hid = #{id} and wid = wifeId
</select>

6.一对一(多表单独查询)

    <!--1:1多表单独查询-->
<select id="selectWifeById" resultType="Wife">
    select wid,wname from wife where wid = #{wifeId}
</select>
<resultMap id="husbandMap" type="Husband">
    <id column="hid" property="hid"/>
    <result column="hname" property="hname"/>
    <association property="wife"
                 javaType="Wife"
                 select="selectWifeById"
                 column="wifeId">
    </association>
</resultMap>
<select id="selectHusbandById" resultMap="husbandMap">
    select hid,hname,wifeId from husband
    where hid = #{id}
</select>

6.1一对一共享主键连接查询

  <!--1:1共享主键多表连接查询-->
    <resultMap id="husbandMap" type="Husband">
        <id column="hid" property="hid"/>
        <result column="hname" property="hname"/>
        <association property="wife" javaType="Wife">
            <id column="wid" property="wid"/>
            <result column="wname" property="wname"/>
        </association>
    </resultMap>
    <select id="selectHusbandById" resultMap="husbandMap">
        select hid,hname,wid,wname from husband,wife
        where hid = #{id} and wid = hid
    </select>

6.2一对一共享主键单独查询

  <!--1:1共享主键多表单独查询-->
    <select id="selectWifeById" resultType="Wife">
        select wid,wname from wife where wid = #{wifeId}
    </select>
    <resultMap id="husbandMap" type="Husband">
        <id column="hid" property="hid"/>
        <result column="hname" property="hname"/>
        <association property="wife"
                     javaType="Wife"
                     select="selectWifeById"
                     column="hid">
        </association>
    </resultMap>
    <select id="selectHusbandById" resultMap="husbandMap">
        select hid,hname from husband
        where hid = #{id}
    </select>

7.自关联一对多(多表连接)
7.1.1实体类

//作为一方
public class Newslabel {
    private Integer id;
    private String name;
    //关联属性
    private Set<Newslabel> children;

7.1.2dao接口

public interface INewslabelDao {
    Newslabel selectNewslabelById(int id);
}

7.1.3映射文件xml

<!--自关联1:n的多表连接查询,查询栏目及其子栏目的信息(不能查到其孙栏目信息)-->
<resultMap id="newslabelMap" type="Newslabel">
    <id column="ptid" property="id"/>
    <result column="ptname" property="name"/>
    <collection property="children" ofType="Newslabel">
        <id column="cdid" property="id"/>
        <result column="cdname" property="name"/>
    </collection>
</resultMap>
<select id="selectNewslabelById" resultMap="newslabelMap">
    select pt.id ptid,pt.name ptname,cd.id cdid,cd.name cdname
    from newslabel pt,newslabel cd
    where pt.id=#{id} and cd.pid=pt.id
</select>
7.1自关联一对多(多表单独)
    <!--自关联1:n的多表单独查询,查询栏目及其子孙栏目的信息-->
<select id="selectNewslabelByParent" resultMap="newslabelMap">
    select id,name from newslabel where pid = #{id}
</select>
<resultMap id="newslabelMap" type="Newslabel">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    <collection property="children"
                ofType="Newslabel"
                select="selectNewslabelByParent"
                column="id"/>
</resultMap>
<select id="selectNewslabelById" resultMap="newslabelMap">
    select id,name from newslabel
    where id = #{id}
</select>

7.3自关联一对多(多表单独查询栏目的子孙栏目)

<!--自关联1:n的多表单独查询,查询栏目的子孙栏目的信息-->
<select id="selectNewslabelByParent" resultMap="newslabelMap">
    select id,name from newslabel where pid = #{id}
</select>
<resultMap id="newslabelMap" type="Newslabel">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    <collection property="children"
                ofType="Newslabel"
                select="selectNewslabelByParent"
                column="id"/>
</resultMap>

7.4自关联一对多(多表单独查询栏目及其父辈栏目)

    <!--自关联1:n的多表单独查询,查询栏目及其父辈栏目的信息-->
    <resultMap id="newslabelMap" type="Newslabel">
        <id column="id" property="id"/>
    <result column="name" property="name"/>
    <association property="parent"
                 javaType="Newslabel"
                 select="selectNewslabelById"
                 column="pid"/>
</resultMap>
    <select id="selectNewslabelById" resultMap="newslabelMap">
        select id,name,pid from newslabel
        where id = #{id}
    </select>

8.多对多多表连接查询
8.1实体类

//以student为主查询
public class Student {
    private Integer sid;
    private String sname;
    //关联属性
    private Set<Course> courses;
public class Course {
    private Integer cid;
    private String cname;

8.2dao接口

public interface IStudentDao {
    Student selectStudentById(int id);
}

8.3映射文件xml


```java
```java
  <!--n:m多表连接查询-->
    <resultMap id="studentMap" type="Student">
        <id column="sid" property="sid"/>
        <result column="sname" property="sname"/>
        <collection property="courses" ofType="Course">
            <id column="cid" property="cid"/>
            <result column="cname" property="cname"/>
        </collection>
    </resultMap>
    <select id="selectStudentById" resultMap="studentMap">
        select sid,sname,cid,cname from student,course,middle
        where sid = #{id} and studentId = sid and cid = courseId
    </select>

9.多对多的多表单独查询

<!--n:m多单独接查询-->
<select id="selectCourseById" resultType="Course">
    select cid,cname from course where cid = #{courseId}
</select>
<resultMap id="middleMap" type="Middle">
    <id column="mid" property="mid"/>
    <association property="course"
                 javaType="Course"
                 select="selectCourseById"
                 column="courseId"/>
</resultMap>
<select id="selectMiddleByStudent" resultMap="middleMap">
    select mid,studentId,courseId from middle where studentId = #{sid}
</select>
<resultMap id="studentMap" type="Student">
    <id column="sid" property="sid"/>
    <result column="sname" property="sname"/>
    <collection property="courses"
                ofType="Course"
                select="selectMiddleByStudent"
                column="sid"/>
</resultMap>
<select id="selectStudentById" resultMap="studentMap">
    select sid,sname from student
    where sid = #{id}
</select>

10.n:m多表连接+单独查询

  <!--n:m多表连接+单独查询-->
    <select id="selectCourseById" resultType="Course">
        select cid,cname from course where cid = #{courseId}
    </select>
    <resultMap id="studentMap" type="Student">
        <id column="sid" property="sid"/>
        <result column="sname" property="sname"/>
        <collection property="courses"
                    ofType="Course"
                    select="selectCourseById"
                    column="courseId"/>
    </resultMap>
    <select id="selectStudentById" resultMap="studentMap">
        select sid,sname,courseId from student,middle
        where sid = #{id} and studentId = sid
    </select>

小知识点
1.如果数剧库中的字段名和实体类中的属性名不一致
解决方案1:使用resultMap进行手动映射

<!--字段名和属性名不一致:使用resultMap手动映射-->
<resultMap id="studentMap" type="Student">
    <id column="sid" property="id"/>
    <result column="sname" property="name"/>
</resultMap>
<select id="selectStudentById" resultMap="studentMap">
    select sid,sname from student where sid = #{id}
</select>

解决方案2:给字段起别名,让别名和属性名相同
例:select sid id,sname name from student ( 数剧库中字段名为sid,实体类中为id)

   <!--字段名和属性名不一致:给字段起别名,让别名和属性名相同-->
    <select id="selectStudentById" resultType="Student">
        select sid id,sname name from student where sid = #{id}
    </select>
六,延迟加载

延迟加载只在多表单独查询时起作用
在这里插入图片描述
在这里插入图片描述
6.1延迟加载策略默认是关闭的,默认为直接加载。

6.1.1当想使用延迟加载时,可以在mybaits主配置文件中设置settings标签的lazyLoadingEnabled属性设置为ture进行打开,settings标签放置有顺序,需要要在properties标签后放置。

6.1.2打开延迟加载后,默认是深度延迟加载,当用户查询主表详情时,关联表不会被查找,只有当查找到关联表的详情后关联表才被查询。
6.2主配置文件

<?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>

    <!--加载jdbc属性文件-->
    <properties resource="jdbc.properties"/>

    <settings>
        <!--打开延迟加载的总开关,默认使用的是深度延迟加载策略-->
        <setting name="lazyLoadingEnabled" value="true"/>
//        <!--总开关打开,该配置才起作用,侵入式延迟加载的开关-->
  //      <setting name="aggressiveLazyLoading" value="true"/>
    </settings>

    <!--给实体类定义别名-->
    <typeAliases>
        <package name="com.yyf.beans"/>
    </typeAliases>

6.3测试类

 @Test
    public void test()
    {
        Country country = countryDao.selectCountryById(2);
        System.out.println("国家的名称:" + country.getCname());//关联表没有被查找
//        System.out.println("国家对应部长的个数:" + country.getMinisters().size());此时关联表才被查询。
    }

6.2.1 如果想使用侵入式延迟加载,在settings中设置aggressiveLazyLoading属性为true,同时总开关要开着,不然不起作用

<?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>

    <!--加载jdbc属性文件-->
    <properties resource="jdbc.properties"/>

    <settings>
        <!--打开延迟加载的总开关,默认使用的是深度延迟加载策略-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--总开关打开,该配置才起作用,侵入式延迟加载的开关-->
       <setting name="aggressiveLazyLoading" value="true"/>
    </settings>

    <!--给实体类定义别名-->
    <typeAliases>
        <package name="com.yyf.beans"/>
    </typeAliases>

6.3.1测试类中当查询到主表的详情时就会查找关联表

 @Test
    public void test()
    {
        Country country = countryDao.selectCountryById(2);
        System.out.println("国家的名称:" + country.getCname());
    }
七,缓存管理

在这里插入图片描述
在这里插入图片描述

7.1一级缓存默认开启,无法关闭
一级缓存中存放的结果不是查询结果本身,而是一个map
一级缓存底层实现是一个Map
key:hashCode + statementId + SQL语句
value:查询结果本身

7.1.1两次查询相同的student的只进行了一次对数剧库的查询
7.1.2如果使用不同的方法,即使查找的是相同的id也会对数据库进行两次查找
7.1.3不管增删改是否提交,都会清空一级缓存

 //证明:一级缓存是存在的
    @Test
    public void test01()
    {
        //第一次查询
        Student student = studentDao.selectStudentById(2);
        System.out.println("第一次查询:" + student);

        //第二次查询
        Student student2 = studentDao.selectStudentById(2);
        System.out.println("第二次查询:" + student2);
        //两次查询相同的student的只进行了一次对数剧库的查询
    }
    // 证明:一级缓存中存放的结果不是查询结果本身,而是一个map
    // 一级缓存底层实现是一个Map
    // key:hashCode + statementId + SQL语句
    // value:查询结果本身
    @Test
    public void test02()
    {
        //第一次查询
        Student student = studentDao.selectStudentById(2);
        System.out.println("第一次查询:" + student);

        //第二次查询
        Student student2 = studentDao.selectStudentById2(2);
        System.out.println("第二次查询:" + student2);
        /如果使用不同的方法,即使查找的是相同的id也会对数据库进行两次查找
    }

    // 证明:增删改操作刷新一级缓存(清空一级缓存)
    @Test
    public void test03()
    {
        //第一次查询
        Student student = studentDao.selectStudentById(2);
        System.out.println("第一次查询:" + student);

        // 插入一个对象
        studentDao.insertStudent(new Student());

        //第二次查询
        Student student2 = studentDao.selectStudentById(2);
        System.out.println("第二次查询:" + student2);
        //不管增删改是否提交,都会清空一级缓存
    }

7.2二级缓存
全局开关 是默认打开的,单个mapper.xml是默认关闭的,如果要使用则需要
1)对应查询的实体类实现 Serializable接口

public class Student implements Serializable {
    private Integer id;
    private String name;
    private int age;
    private double score;
    public Student() {
    }

2)mapper.xml文件中创建标签

<mapper namespace="com.yyf.dao.IStudentDao">

    <!--
        在该命名空间下打开二级缓存,
        size可以设置二级缓存的大小,
        eviction可以设置二级缓存的逐出策略,
        flushInterval可以设置二级缓存的刷新间隔
    -->
    <cache size="512" eviction="LRU" flushInterval="10000"/>

    <!--
        flushCache设置该操作是否刷新二级缓存
    -->
        <insert id="insertStudent" flushCache="false">
        insert into student (name,age,score) values (#{name},#{age},#{score})
    </insert>

   <!--useCache设置该查询方法是否使用缓存-->
    <select id="selectStudentById" resultType="Student" useCache="false">
        select id,name,age,score from student where id = #{id}
    </select>
 //证明:二级缓存是存在的
    @Test
    public void test01() throws IOException {
        // 第一次查询

        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        studentDao = sqlSession.getMapper(IStudentDao.class);
        Student student = studentDao.selectStudentById2(6);
        System.out.println("第一次查询:" + student);
        //关闭SqlSession,清空一级缓存
        sqlSession.close();

        SqlSession sqlSession2 = MyBatisUtil.getSqlSession();
        studentDao = sqlSession2.getMapper(IStudentDao.class);
        // 第二次查询
        Student student2 = studentDao.selectStudentById2(6);
        System.out.println("第二次查询:" + student2);
        sqlSession2.close();

        SqlSession sqlSession3 = MyBatisUtil.getSqlSession();
        studentDao = sqlSession3.getMapper(IStudentDao.class);
        // 第三次查询
        Student student3 = studentDao.selectStudentById2(6);
        System.out.println("第三次查询:" + student3);
        sqlSession3.close();
    }

    // 证明:增删改操作对二级缓存的影响
    // 增删改操作会刷新(清空)二级缓存
    // 1.刷新二级缓存到底执行了那些???
    // 二级缓存的底层也是Map
    // key:hashCode + statemengId + SQL语句
    // value:查询结果
    // 刷新二级缓存实际上是将二级缓存中的所有Entry对象的value置为null
    // 并没有彻底删除整个Entry对象,即key仍保留
    // 2.到底何时可以到DB执行select查询?
    // 有两种情况可以到DB执行查询
    // 1>Map中根本就不存在要查找的Entry,即key未找到
    // 2>Map中存在要查找的key,但value值为null
    // 3.增删改默认可以影响二级缓存,但也可以让其不影响二级缓存
    // 只需要在增删改的statement中添加属性flushCache="false"即可

7.3使用第三方二级缓存
7.3.1在pow文件中引入第三方缓存所需要的依赖

 <!-- https://mvnrepository.com/artifact/org.ehcache/ehcache -->
    <dependency>
      <groupId>org.ehcache</groupId>
      <artifactId>ehcache</artifactId>
      <version>3.8.1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache -->
    <dependency>
      <groupId>org.mybatis.caches</groupId>
      <artifactId>mybatis-ehcache</artifactId>
      <version>1.2.1</version>
    </dependency>

7.3.2mybatis主配置文件

<configuration>
    <!--加载jdbc属性文件-->
    <properties resource="jdbc.properties"/>
    
    <settings>
        <!--使用log4j2的日志-->
        <setting name="logImpl" value="LOG4J2"/>
        <!--二级缓存的总开关,默认是打开的-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

7.3.3mapper映射文件

<mapper namespace="com.yyf.dao.IStudentDao">

    <!--使用DHCache第三方缓存,把type类型设置为第三方缓存类型-->
    <cache type="org.mybatis.caches.ehcache.EhcacheCache">
        <property name="timeToLiveSeconds" value="1000"/>
    </cache>

    <!--
        flushCache设置该操作是否刷新二级缓存
    -->
    <insert id="insertStudent" flushCache="false">
        insert into student (name,age,score) values (#{name},#{age},#{score})
    </insert>
    <!--useCache设置该查询方法是否使用缓存-->
    <select id="selectStudentById" resultType="Student" useCache="false">
        select id,name,age,score from student where id = #{id}
    </select>

小结:

 1.二级缓存可以全局性关闭
 当前应用中所有查询均不能使用二级缓存,在mybatis的主配置文件
 2.二级缓存可以局部性关闭
 可以指定在某一个映射文件中是否使用二级缓存,在映射文件中使用<cache/>
 3.二级缓存可以进行对某个查询方法是否使用二级缓存进行设置
 在对应查询标签<select>中天健属性useCahce=“false”即可关闭
八,mybatis注解
package com.yyf.dao;
import com.yyf.beans.Student;
import org.apache.ibatis.annotations.*;
import java.util.List;
import java.util.Map;
public interface IStudentDao {
    // 1.注解是以@开头,首字母大写的,因为注解是类层级的成员,类层级的成员:类、接口、注解、枚举
    // 2.对注解中数组类型的属性赋值,使用{元素1,元素2,.....}
    // 3.如果数组类型的属性只有一个元素,那么{}可以省略
    // 4.若果注解只使用到了一个属性,并且属性名为value,那么这个value名称可以省略

    @Insert(value = {"insert into student (name,age,score) values(#{name},#{age},#{score})"})
    void insertStudent(Student student);

    @Delete(value = "delete from student where id = #{xx}")
    void deleteStudentById(int id);

    @Update("update student set name=#{name},age=#{age},score=#{score} where id = #{id}")
    void updateStudent(Student student);
  //当我们向主键是自增型的数据库表中(如 user 表)插入一条记录时,我们期望获取刚刚写入这条记录
  //的id,(因为某些场景下需要获得这个id去做其他的操作),此时我们需要使用SELECT LAST_INSERT_ID()
  //这个语句来获取插入记录后返回的自增id的值;
    @Insert("insert into student (name,age,score) values(#{name},#{age},#{score})")
    @SelectKey(statement = "select last_insert_id()",keyProperty = "id",before = false,resultType = int.class)
    void insertStudentCatchId(Student student);

    @Select("select id,name,age,score from student")
    List<Student> selectAllStudent();

    @MapKey(value = "name")
    @Select("select id,name,age,score from student")
    Map<String,Student> selectAllStudentMap();

    @Select("select id,name,age,score from student where id = #{xx}")
    Student selectStudentById(int id);

    @Select("select id,name,age,score from student where name like '%' #{name} '%'")
    List<Student> selectStudentByName(String name);

    @Select("select id,name,age,score from student where name like '%' #{name} '%' and age < #{age}")
    List<Student> selectStudentByCondition(Student student);

    //@Select("select id,name,age,score from student where age < #{max} and age > #{min}")
    @Select("select id,name,age,score from student where age < #{stu2.age} and age > #{stu1.age}")
    List<Student> selectStudentByCondition2(Map map);

    @Select("select id,name,age,score from student where name like '%' #{name} '%' and age < #{age}")
    List<Student> selectStudentByCondition3(@Param("name") String name,@Param("age") int age);

}

九,mybatis注解动态sql
9.1dao接口

public interface IStudentDao {

    @InsertProvider(type = MySqlProvider.class, method = "getInsertSql")
    void insertStudent(Student student);

    @DeleteProvider(type = MySqlProvider.class, method = "getDeleteSql")
    void deleteStudentById(int id);

    //@UpdateProvider(type = MySqlProvider.class, method = "getUpdateSql")
    //@UpdateProvider(type = MySqlProvider.class, method = "getUpdateSql2")
    @UpdateProvider(type = MySqlProvider.class, method = "getUpdateSql3")
    void updateStudent(Student student);

    @InsertProvider(type = MySqlProvider.class, method = "getInsertSql")
    @SelectKey(statement = "select last_insert_id()",keyProperty = "id",before = false,resultType = int.class)
    void insertStudentCatchId(Student student);

    @SelectProvider(type = MySqlProvider.class, method = "getSelectSql")
    List<Student> selectAllStudent();

    @SelectProvider(type = MySqlProvider.class, method = "getSelectSql")
    Student selectStudentById(Integer id);

    @SelectProvider(type = MySqlProvider.class, method = "getSelectSql2")
    List<Student> selectStudentByName(String name);

    @MapKey(value = "name")
    @SelectProvider(type = MySqlProvider.class,method = "getSelectSql")
    Map<String,Student> selectAllStudentMap();

    @SelectProvider(type = MySqlProvider.class, method = "getSelectSql3")
    List<Student> selectStudentByCondition(Student student);

    @SelectProvider(type = MySqlProvider.class, method = "getSelectSql4")
    List<Student> selectStudentByCondition2(Map map);

    //@SelectProvider(type = MySqlProvider.class, method = "getSelectSql5")
    @SelectProvider(type = MySqlProvider.class, method = "getSelectSql6")
    List<Student> selectStudentByCondition3(@Param("name") String name,@Param("age") int age);

}

9.2MySqlProvider类

package com.yyf.dao;

import com.yyf.beans.Student;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.jdbc.SQL;

import java.util.Map;

/**
 * company: www.abc.com
 * Author: Administrator
 * Create Data: 2020/10/26 0026
 */
public class MySqlProvider {
    public String getInsertSql(){
        return "insert into student (name,age,score) values(#{name},#{age},#{score})";
    }

    public String getDeleteSql(){
        return "delete from student where id = #{id}";
    }

    public String getUpdateSql(){
        return "update student set name=#{name},age=#{age},score=#{score} where id = #{id}";
    }

    public String getSelectSql(Integer id){
        if (id != null){
            return "select id,name,age,score from student where id = #{id}";
        }else {
            return "select id,name,age,score from student";
        }
    }
    public String getSelectSql2(){
        return "select id,name,age,score from student where name like '%' #{name} '%'";
    }

    public String getSelectSql3(Student student){
        StringBuffer sql = new StringBuffer();
        sql.append("select id,name,age,score from student where 1=1");
        if (student.getName() != null && !"".equals(student.getName())){
            sql.append(" and name like '%' #{name} '%'");
        }
        if (student.getAge() > 0){
            sql.append(" and age < #{age}");
        }
        return sql.toString();
    }

    public String getSelectSql4(Map map){
        StringBuffer sql = new StringBuffer();
        sql.append("select id,name,age,score from student where 1=1");
        if ((Integer)map.get("min") > 0){
            sql.append(" and age > #{min}");
        }
        if ((Integer)map.get("max") > 0){
            sql.append(" and age < #{max}");
        }
        return sql.toString();
    }

    public String getSelectSql5(@Param("name") String name, @Param("age") int age){
        StringBuffer sql = new StringBuffer();
        sql.append("select id,name,age,score from student where 1=1");
        if (name != null && !"".equals(name)){
            sql.append(" and name like '%' #{name} '%'");
        }
        if (age > 0){
            sql.append(" and age < #{age}");
        }
        return sql.toString();
    }

    public String getSelectSql6(Map map){
        StringBuffer sql = new StringBuffer();
        sql.append("select id,name,age,score from student where 1=1");
        if (map.get("name") != null && !"".equals(map.get("name"))){
            sql.append(" and name like '%' #{name} '%'");
        }
        if ((Integer)map.get("age") > 0){
            sql.append(" and age < #{age}");
        }
        return sql.toString();
    }
    public String getUpdateSql2(Student student){
        StringBuffer sql = new StringBuffer();
        //update student set name=#{name},age=#{age},score=#{score} where id = #{id}
        sql.append("update student set id = #{id}");
        if (student.getName() != null && !"".equals(student.getName())){
            sql.append(",name = #{name}");
        }
        if (student.getAge() > 0){
            sql.append(",age = #{age}");
        }
        if (student.getScore() > 0){
            sql.append(",score = #{score}");
        }
        sql.append(" where id = #{id}");
        return sql.toString();
    }

    public String getUpdateSql3(final Student student){
        // new SQL(){}表示创建一个SQL类的子类的对象,只不过这个子类叫什么名称不知道,也没有指定
        // 所以,这种写法叫做匿名内部类
        return new SQL(){
            // 下面的代码在何时被执行?
            // 当当前类(SQL类的子类)的无参构造器被调用时,会自动执行这段代码
            // 在类中的{}称为实例代码块
            {
                this.UPDATE("student");
                this.SET("id = #{id}");
                if (student.getName() != null && !"".equals(student.getName())){
                    this.SET("name = #{name}");
                }
                if (student.getAge() > 0){
                    this.SET("age = #{age}");
                }
                if (student.getScore() > 0){
                    this.SET("score = #{score}");
                }
                this.WHERE("id = #{id}");
            }
        }.toString();
    }
}

9.3测试类

public class MyTest
{
    SqlSession sqlSession = null;
    IStudentDao studentDao = null;
    @Before
    public void before() throws IOException {
        sqlSession = MyBatisUtil.getSqlSession();
        studentDao = sqlSession.getMapper(IStudentDao.class);
        //System.out.print("代理:"+studentDao);
    }

    @After
    public void after(){
        if (sqlSession != null){
            sqlSession.close();
        }
    }
    //学生信息插入
    @Test
    public void test01()
    {
        Student student = new Student("小明3",20,98.5);
        studentDao.insertStudent(student);
        sqlSession.commit();
        System.out.print("插入后:"+student);
    }
    //删除学生信息按id
    @Test
    public void test02()
    {
        studentDao.deleteStudentById(18);
        sqlSession.commit();
    }
    //修改学生信息按id
    @Test
    public void test03()
    {
        Student student = new Student("小绿",0,0);
        student.setId(10);
        studentDao.updateStudent(student);
        sqlSession.commit();
    }
    //获取最新插入的学生id
    @Test
    public void test04()
    {
        Student student = new Student("小小1",18,88);
        studentDao.insertStudentCatchId(student);
        sqlSession.commit();
        System.out.print("插入后:"+student);
    }
    //查询全部学生信息List
    @Test
    public void test05()
    {
        List<Student> students = studentDao.selectAllStudent();
        for (Student s:students){
            System.out.println(s);
        }
    }
    //按照id查询学生信息
    @Test
    public void test06()
    {
        Student student = studentDao.selectStudentById(6);
            System.out.println(student);
    }
    //按照name查询学生信息
    @Test
    public void test07()
    {
        List<Student> students = studentDao.selectStudentByName("明");
        for (Student s:students){
            System.out.println(s);
        }
    }
    //使用动态代理查询时,会根据需要的返回结果默认调用方法selectList或selectOne,
    //如果返回结果为List,则默认调用selectList方法,否则都默认调用selectOne方法
    //如果需要返回map时,需要在对应的接口方法上添加注解@MapKey(value="")
    //查询全部学生信息Map
    @Test
    public void test08()
    {
        Map<String,Student> map = studentDao.selectAllStudentMap();
        System.out.println(map.get("小明3"));
    }
    //复合条件查询学生信息
    @Test
    public void test09()
    {
        //Student student = new Student("明",20,-1);
        //Student student = new Student("明",0,-1);
        //Student student = new Student(null,20,-1);
        Student student = new Student(null,0,-1);
        List<Student> students = studentDao.selectStudentByCondition(student);
        for (Student s:students){
            System.out.println(s);
        }
    }
    //复合条件查询学生信息2
    @Test
    public void test10()
    {
        Map map = new HashMap();
        /*Student stu1 = new Student(null,16,-1);
        Student stu2 = new Student(null,20,-1);
        map.put("stu1",stu1);
        map.put("stu2",stu2);*/
        map.put("min",16);
        map.put("max",20);
        List<Student> students = studentDao.selectStudentByCondition2(map);
        for (Student s:students){
            System.out.println(s);
        }
    }

    //复合条件查询学生信息3
    @Test
    public void test11()
    {
        List<Student> students = studentDao.selectStudentByCondition3("明",20);
        for (Student s:students){
            System.out.println(s);
        }
    }
 }

完结…

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值