Mybatis入门

mybatis入门

第1章:mybatis概述

1-1 对比

原生JDBC:

image-20220610112824060

image-20220610113024839

Hibernate框架的优缺点:

image-20220610113509207

mybatis:将操作数据库的核心sql语句抽取出来:

image-20220610114004640

image-20220610135338556

1-2 mybatis简介

image-20220610135603656

image-20220610135630259

项目下载:

image-20220610141100224

image-20220610141318755

1-3 HelloWorld--mybatis导包

3个包:数据库驱动包,mybatis包,log4j日志包

<?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">
    <parent>
        <artifactId>mybatisProject</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>mybatis-01-HelloWorld</artifactId>
    <dependencies>
<!--        数据库厂商提供的数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.32</version>
        </dependency>
<!--        导入使用mybatis所需的依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
<!--        导入日志包,使项目具有打印日志的功能-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

</project>

1-4 HelloWorld基础环境搭建

image-20220610144622335

1-5 HelloWorld写配置

第1个配置:mybatis-config.xml(全局配置文件,知道mybatis如何正确运行,比如连接向那个数据库)

image-20220610150232597

<?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>
    <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/mybatis_0325"/>
                <property name="username" value="root"/>
                <property name="password" value="draf19"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    </mappers>
</configuration>

第2个配置:EmployeeDao.xml(编写每一个方法都是如何向数据库发送sql语句,如何执行。。。相当于接口的实现类)

步骤:(该配置文件相当于对EmployeeDao接口的实现类,而里面的查询相当于对接口中方法的实现。)

1.将mapper的namespace属性改为接口的全类名

2.配置细节

<?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:名称空间;写接口的全类名,相当于告诉Mybatis这个配置文件是实现了那个接口-->
<mapper namespace="com.xu1.dao.EmployeeDao">
<!--
public Employee getEmployeeById(Integer id);
select:用来定义查询操作 id:方法名,相当于这个配置是对于某个方法的实现
resultType:指定方法运行后的返回值类型;(查询操作必须指定)
#{属性值}:代表取出传递过来的某个参数的值
-->
    <select id="getEmployeeById" resultType="com.xu1.bean.Employee">
        select * from t_employee where id = #{id}
    </select>
</mapper>

第3个配置:全局配置文件告诉我们编写的每一个接口的实现文件

image-20220610152528079

1-6 HelloWorld测试

报错:

image-20220610161810155

解决:

image-20220610162033639

步骤:

//1.根据全局配置文件创建处一个SqlSessionFactory
//SqlSessionFactory:是SqlSession工厂,负责创建SqlSession对象
//SqlSession:sql会话(代表和数据库的一次会话);
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

//2.获取和数据库的一次会话:getConnection();
SqlSession sqlSession = sqlSessionFactory.openSession();

//3.使用SqlSession操作数据库,获取dao接口的实现
EmployeeDao employeeDao = sqlSession.getMapper(EmployeeDao.class);

//4.调用相应方法即可
Employee employee = employeeDao.getEmployeeById(1);
System.out.println(employee);

完善后的代码参考:

import com.xu1.bean.Employee;
import com.xu1.dao.EmployeeDao;
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 org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Target;

/**
 * @auther xu
 * @Description
 * @date 2022/6/10 - 16:00
 * @Modified By:
 */
public class MybatisTest {

    @Test
    public void test() throws IOException {
        //1.根据全局配置文件创建处一个SqlSessionFactory
        //SqlSessionFactory:是SqlSession工厂,负责创建SqlSession对象
        //SqlSession:sql会话(代表和数据库的一次会话);
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession sqlSession = null;
        Employee employee = null;
        try {
            //2.获取和数据库的一次会话:getConnection();
            sqlSession = sqlSessionFactory.openSession();

            //3.使用SqlSession操作数据库,获取dao接口的实现
            EmployeeDao employeeDao = sqlSession.getMapper(EmployeeDao.class);

            //4.调用相应方法即可
            employee = employeeDao.getEmployeeById(1);

        } finally {
            sqlSession.close();
        }
        System.out.println(employee);
    }
}

输出结果:

com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 MybatisTest,test
2022-06-10 16:59:12,205 0      [           main] DEBUG ache.ibatis.logging.LogFactory  - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
2022-06-10 16:59:12,301 96     [           main] DEBUG source.pooled.PooledDataSource  - PooledDataSource forcefully closed/removed all connections.
2022-06-10 16:59:12,301 96     [           main] DEBUG source.pooled.PooledDataSource  - PooledDataSource forcefully closed/removed all connections.
2022-06-10 16:59:12,301 96     [           main] DEBUG source.pooled.PooledDataSource  - PooledDataSource forcefully closed/removed all connections.
2022-06-10 16:59:12,301 96     [           main] DEBUG source.pooled.PooledDataSource  - PooledDataSource forcefully closed/removed all connections.
2022-06-10 16:59:12,373 168    [           main] DEBUG ansaction.jdbc.JdbcTransaction  - Opening JDBC Connection
2022-06-10 16:59:12,583 378    [           main] DEBUG source.pooled.PooledDataSource  - Created connection 1282811396.
2022-06-10 16:59:12,583 378    [           main] DEBUG ansaction.jdbc.JdbcTransaction  - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4c762604]
2022-06-10 16:59:12,585 380    [           main] DEBUG ao.EmployeeDao.getEmployeeById  - ==>  Preparing: select * from t_employee where id=? 
2022-06-10 16:59:12,611 406    [           main] DEBUG ao.EmployeeDao.getEmployeeById  - ==> Parameters: 1(Integer)
2022-06-10 16:59:12,628 423    [           main] DEBUG ao.EmployeeDao.getEmployeeById  - <==      Total: 1
2022-06-10 16:59:12,628 423    [           main] DEBUG ansaction.jdbc.JdbcTransaction  - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4c762604]
2022-06-10 16:59:12,629 424    [           main] DEBUG ansaction.jdbc.JdbcTransaction  - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4c762604]
2022-06-10 16:59:12,629 424    [           main] DEBUG source.pooled.PooledDataSource  - Returned connection 1282811396 to pool.
Employee{id=1, empname='admin', email='admin@qq.com', gender='0'}

Process finished with exit code 0

1-6 导入dtd写xml有提示

image-20220611154342636

idea绑定:

image-20220611154810740

1-7探索mybatis中的事务提交

image-20220611162248518

事务提交导致数据库插入不成功:

image-20220611173305739

解决:

image-20220611173502735

结果:

image-20220611173649915

代码参考:

MybatisTest02.java

import com.xu1.bean.Employee;
import com.xu1.dao.EmployeeDao;
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 org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;

/**
 * @auther xu
 * @Description
 * @date 2022/6/10 - 16:00
 * @Modified By:
 */
public class MybatisTest02 {

    SqlSessionFactory sqlSessionFactory = null;

    @Before
    public void initSqlSessionFactory() throws IOException {
        //1.根据全局配置文件创建处一个SqlSessionFactory
        //SqlSessionFactory:是SqlSession工厂,负责创建SqlSession对象
        //SqlSession:sql会话(代表和数据库的一次会话);
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void testGetEmployee() throws IOException {

//        initSqlSessionFactory();

        SqlSession sqlSession = null;
        Employee employee = null;
        try {
            //2.获取和数据库的一次会话:getConnection();
            sqlSession = sqlSessionFactory.openSession();

            //3.使用SqlSession操作数据库,获取dao接口的实现(映射器)
            EmployeeDao employeeDao = sqlSession.getMapper(EmployeeDao.class);

            //4.调用相应方法即可
            employee = employeeDao.getEmployeeById(1);

        } finally {
            sqlSession.close();
        }
        System.out.println(employee);
    }

    /**
     *
     * @Description
     * 测试插入
     * @Date 2022/6/11 17:18
     *
     */
    @Test
    public void testInsertEmployee() {
        //1.获取与数据库的一次会话
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            //2获取employeeDao接口的映射器
            EmployeeDao employeeDao = sqlSession.getMapper(EmployeeDao.class);
            //3.映射器(接口的实现类)调用接口的实现方法
            int count = employeeDao.insertEmployee(new Employee(null, "lixingting", "li@qq.com", "1"));
            System.out.println("成功执行"+count+"行");
        } finally {
            //对数据库事务进行手动提交
            sqlSession.commit();
            sqlSession.close();
        }
    }
}

EmployeeDao.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:名称空间;写接口的全类名,相当于告诉Mybatis这个配置文件是实现了那个接口-->
<mapper namespace="com.xu1.dao.EmployeeDao">
<!--
public Employee getEmployeeById(Integer id);
select:用来定义查询操作 id:方法名,相当于这个配置是对于某个方法的实现
resultType:指定方法运行后的返回值类型;(查询操作必须指定)
#{属性值}:代表取出传递过来的某个参数的值
-->

<!--
    public Employee getEmployeeById(Integer id);
    public int updateEmployee(Employee employee);
    public int deleteEmployee(Integer id);
    public int insertEmployee(Employee employee);

-->
    <select id="getEmployeeById" resultType="com.xu1.bean.Employee">
        <!-- sql语句不要写分号-->
        select * from t_employee where id=#{id}
    </select>

<!--
    增删改不需要写返回值类型,增删改影响的是行数,mybatis自动判断,如果是数字(int,long),如果是boolean(影响0行自动封装为false,否则true)
-->
    <update id="updateEmployee" >
        update t_employee set empname=#{empname} where id=#{id}
    </update>
    <delete id="deleteEmployee">
        delete from t_employee where id=#{id}
    </delete>
    <insert id="insertEmployee">
        insert into t_employee(empname,gender,email) value (#{empname},#{gender},#{email})
    </insert>
</mapper>

mybatis-config.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>
    <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/mybatis_0325"/>
                <property name="username" value="root"/>
                <property name="password" value="draf19"/>
            </dataSource>
        </environment>
    </environments>

<!--    引入我们编写的每一个接口的实现文件-->
    <mappers>
        <mapper resource="EmployeeDao.xml"/>
    </mappers>
</configuration>

1-8 细节及其总结

细节:

image-20220611214024260

image-20220611211541944

1-9 全局配置文件--mybatis-config.xml

1-9-1 全局配置文件之--properties

image-20220611214255312

<!--    1.和Spring的context:property-placeholder;引用外部配置文件类似-->
<!--
resource:从类路径下开始引用
url:引用磁盘路径或者网络路径的资源
-->
    <properties resource="dbconfig.properties"></properties>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${driverclass}"/>
                <property name="url" value="${jdbccurl}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

1-9-2 全局配置文件之---settings(重要)

image-20220611221311390

使用settings-setting-mapUnderscoreToCamelCase解决

<!--    2.这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。-->
    <settings>
<!--        mapUnderscoreToCamelCase:是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

结果:

image-20220611221640717

image-20220611221701746

1-9-3 全局配置文件之---typeAliases--起别名

image-20220611222431691

对第4种情况简单说明:

image-20220611223301376

代码参考:

<!--3.起别名:为javaBean其别名-->
    <typeAliases>
    <!--        1.该种方式起别名:默认别名是类名-->
<!--        <typeAlias type="com.xu1.bean.Employee"/>-->
    <!--       2.该种方式起别名:默认别名是alias的值 -->
<!--        <typeAlias type="com.xu1.bean.Employee" alias="emp"/>-->

<!--        3.批量起别名:默认别名就是类名-->
    <!--        <package name="com.xu1.bean"/>-->
<!--       4.批量起别名:如果不适用默认类名,需要到相应的类上使用@Alias("emp")为其起别名 -->
        <package name="com.xu1.bean"/>

    </typeAliases>

总结:推荐不要使用别名,直接使用全类名,因为这便于查看相应的类。

注意:

image-20220612060248681

1-9-4 全局配置文件之---类型处理器(typeHandlers)

image-20220612062255826

image-20220612062737752

image-20220612062559967

image-20220612080832625

总结:一般不需要我们管处理器,当要实现自定义类型处理器时,可参考文档如何实现自定义处理器。

1-9-5 全局配置文件之--plugins插件

image-20220612081222081

1-9-10 全局配置文件之---环境配置(environments)

image-20220612082141556

code:

<!--   default="development":默认使用哪一种环境-->
    <environments default="development">
<!--        id="development":当前环境的唯一标识-->
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${driverclass}"/>
                <property name="url" value="${jdbccurl}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

1-9-11 全局配置文件之--数据库厂商标识(databaseIdProvider)

image-20220612082441329

image-20220612083918894

code:

<!--    4.用来考虑数据库的移植性的-->
    <databaseIdProvider type="DB_VENDOR">
<!--
name="":数据库厂商标识 value:给这个标识起一个好用的名字
MySQL,Oracle,SQL Server
-->
        <property name="MySQL" value="mysql"/>
        <property name="Oracle" value="oracle"/>
        <property name="SQL Server" value="sqlServer"/>
    </databaseIdProvider>

1-9-12 全局配置文件之--映射器(mappers)

1.使用class

image-20220612093926849

image-20220612094659888

输出结果:

image-20220612094905462

2.使用注解开发

EmployeeDaoAnnotation.java

package com.xu1.dao;

import com.xu1.bean.Employee;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

/**
 * @auther xu
 * @Description
 * @date 2022/6/12 - 9:51
 * @Modified By:
 */
public interface EmployeeDaoAnnotation {

    @Select("select * from t_employee where id=#{id}")
    public Employee getEmployeeById(Integer id);
    @Update("update t_employee set " +
            "empname=#{empname} where id=#{id}")
    public int updateEmployee(Employee employee);
    @Delete("delete from t_employee where id=#{id}")
    public int deleteEmployee(Integer id);
    @Insert("insert into t_employee(empname,gender,email) " +
            "value (#{empname},#{gender},#{email})")
    public int insertEmployee(Employee employee);
}

image-20220612100101412

test代码:

/**
 *
 * @Description
 * 使用注解开发test
 * @Date 2022/6/12 9:56
 *
 */
@Test
public void testAnnotation() {
    SqlSession sqlSession = null;
    try {
        sqlSession = sqlSessionFactory.openSession();
        EmployeeDaoAnnotation mapper = sqlSession.getMapper(EmployeeDaoAnnotation.class);
        Employee employee = mapper.getEmployeeById(7);
        System.out.println(employee);
    } finally {
        sqlSession.close();
    }
}

输出结果:

image-20220612100201155

注意:

image-20220612100417763

image-20220612100818151

3.使用package进行批量注册

mybatis报错之--package覆盖mapper注册导致的报错:

image-20220612103448917

image-20220612103912275

image-20220612105400547

代码参考:

  <mappers>
        <!--
         url:可以从磁盘或者网络路径引用
         resource:在类路径下找sql映射文件
         class:直接引用接口的全类名
         -->
<!--            <mapper resource="EmployeeDao.xml"/>-->
<!--            <mapper class="com.xu1.dao.EmployeeDao"></mapper>-->


<!--            如果是使用注解开发,没有对应的接口实现类的xml文件,所以需要用class注册路径-->
            <mapper class="com.xu1.EmployeeDaoAnnotation"></mapper>
            <package name="com.xu1.dao"/>
        </mappers>

第2章--SQL映射文件

注意:

image-20220612140619672

image-20220612141210731

2-1 SQL映射文件---获取自增主键的值

image-20220612141418981

注意:mybatis没有方法重载。

获取自增主键的值:

image-20220612143046648

image-20220612143547157

结果:

image-20220612143704541

代码参考:

<!--
让mybatis自动的将自增的id赋值给传入的employee对象的id属性
useGeneratedKeys="true":底层调用原生JDBC获取主键的方法————getGeneratedKeys() 

keyProperty="id":将刚才自增的id封装给Employee中哪一个属性(eg:id)
-->
    <insert id="insertEmployee" useGeneratedKeys="true" keyProperty="id">
        insert into t_employee(empname,gender,email) value (#{empname},#{gender},#{email})
    </insert>
@Test
public void insert() {
    SqlSession sqlSession = null;
    try {
        sqlSession = sqlSessionFactory.openSession();
        EmployeeDao mapper = sqlSession.getMapper(EmployeeDao.class);
        Employee lidan = new Employee(null, "lidan", "lidan@136.com", "1");
        int count = mapper.insertEmployee(lidan);
        sqlSession.commit();
        System.out.println("该自增主键id的值为:"+lidan.getId());
    } finally {
        sqlSession.close();
    }
}

底层原理:

image-20220612144515571

2-2 SQL映射文件--获取非自增主键的值

image-20220612152639069

结果:

image-20220612152758406

代码参考:

<insert id="insertEmployee2">

<!--查询主键
order="BRFORE":
    在核心sql语句之前先运行一个查询sql查到的id,然后将查到的id赋值给javaBean的像对应的属性

-->
    <selectKey order="BEFORE" resultType="Integer" keyProperty="id">
        select max(id)+1 from t_employee;
    </selectKey>

    insert into t_employee(id,empname,gender,email) value (#{id},#{empname},#{gender},#{email})
</insert>
@Test
public void insert02() {
    SqlSession sqlSession = null;
    try {
        sqlSession = sqlSessionFactory.openSession();
        EmployeeDao mapper = sqlSession.getMapper(EmployeeDao.class);
        Employee lidan = new Employee(null, "lidan", "lidan@136.com", "1");
        int count = mapper.insertEmployee2(lidan);
        sqlSession.commit();
        System.out.println("该自增主键id的值为:"+lidan.getId());
    } finally {
        sqlSession.close();
    }
}

2-3 SQL映射文件--参数的各种取值

image-20220612153811779

解决:

image-20220612154213116

image-20220612154343197

2-3-1 现象:

image-20220612154840058

image-20220612155011431

2-3-2 命名参数优化:参考上述多个参数的原理,将参数封装到map中,我们使用命名参数指定key

image-20220612162220635

image-20220612161632098

更正:empname=#{empname}

image-20220612161947217

code reference:

EmployeeDao.java

package com.xu1.dao;

import com.xu1.bean.Employee;
import org.apache.ibatis.annotations.Param;

/**
 * @auther xu
 * @Description
 * @date 2022/6/10 - 14:38
 * @Modified By:
 */
public interface EmployeeDao {
    public Employee getEmployeeById(Integer id);
    public Employee getEmployeeByIdAndName(@Param("id") Integer id,
                                           @Param("empname") String empname);

    public int updateEmployee(Employee employee);
    public int deleteEmployee(Integer id);
    public int insertEmployee(Employee employee);
    public int insertEmployee2(Employee employee);
}
<select id="getEmployeeByIdAndName" resultType="com.xu1.bean.Employee">
    <!--select * from t_employee where id=#{arg0} and empname=#{arg1}-->
        select * from t_employee where id=#{id} and empname=#{empname}
</select>

2-3-3 使用map封装查询时,sql语句所需要用到的参数值

image-20220612163243814

image-20220612163451308

code reference:

package com.xu1.dao;

import com.xu1.bean.Employee;
import org.apache.ibatis.annotations.Param;

import java.util.Map;

/**
 * @auther xu
 * @Description
 * @date 2022/6/10 - 14:38
 * @Modified By:
 */
public interface EmployeeDao {
    public Employee getEmployeeById(Integer id);
    public Employee getEmployeeByIdAndName(@Param("id") Integer id,
                                           @Param("empname") String empname);
    public Employee getEmployeeByIdAndNameMap(Map<String,Object> map);

    public int updateEmployee(Employee employee);
    public int deleteEmployee(Integer id);
    public int insertEmployee(Employee employee);
    public int insertEmployee2(Employee employee);
}

EmployeeDao.xml中的查询操作:

<select id="getEmployeeByIdAndNameMap" resultType="com.xu1.bean.Employee">
    select * from t_employee where id=#{id} and empname=#{empname}
</select>

test类:

/**
 *
 * @Description
 * 将查询所需要使用的参数封装到一个map,便于sql语句的取值的测试类
 * @Date 2022/6/12 16:36
 *
 */
@Test
public void test03() {
    SqlSession sqlSession = null;
    try {
        //2.与数据库建立连接
        sqlSession = sqlSessionFactory.openSession();
        //3.获取dao接口的实现(映射器)--通过反射生产的一个EmployeeDao接口的实现类
        EmployeeDao employeeDao = sqlSession.getMapper(EmployeeDao.class);

       //将查询所需要使用的参数封装到一个map,便于sql语句的取值
        Map<String,Object> map = new HashMap<>();
        map.put("id",7);
        map.put("empname","lixingting");
        //4.调用实现类的方法
        Employee employee = employeeDao.getEmployeeByIdAndNameMap(map);

        System.out.println(employee);
    } finally {
        sqlSession.close();
    }
}

2-3-4 拓展--取出参数是自定义类型中的某一个属性值

image-20220612163942005

2-4 SQL映射文件--Oracle数据库情况下jdbcType需要被指定

image-20220612203612768

2-5 SQL映射文件---#{属性名}与${属性名}区别

image-20220612204657332

image-20220612205152564

2-6 SQL映射文件---查询所有的员工

image-20220612210126372

2-7 将查询的记录封装为map

2-7-1 查询单条记录封装为Map

image-20220612214713809

image-20220612214838023

image-20220612215107470

2-7-2 查询多条记录封装为Map

前提:

image-20220612220333350

image-20220612220540512

但是有一个问题:调用的不是toString:

image-20220612221232773

改进:

image-20220612221449747

代码参考:

Employee.java

package com.xu1.bean;


/**
 * @auther xu
 * @Description
 * @date 2022/6/10 - 14:35
 * @Modified By:
 */
public class Employee {
    private Integer id;
    private String empname;
    private String email;
    private String gender;
    private String loginAccount;


    public Employee() {
    }

    public Employee(Integer id, String empname, String email, String gender) {
        this.id = id;
        this.empname = empname;
        this.email = email;
        this.gender = gender;
    }
    public String getLoginAccount() {
        return loginAccount;
    }

    public void setLoginAccount(String loginAccount) {
        this.loginAccount = loginAccount;
    }

    public Integer getId() {
        return id;
    }

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

    public String getEmpname() {
        return empname;
    }

    public void setEmpname(String empname) {
        this.empname = empname;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", empname='" + empname + '\'' +
                ", email='" + email + '\'' +
                ", gender='" + gender + '\'' +
                ", loginAccount='" + loginAccount + '\'' +
                '}';
    }
}

EmployeeDao.java:

package com.xu1.dao;

import com.xu1.bean.Employee;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

/**
 * @auther xu
 * @Description
 * @date 2022/6/10 - 14:38
 * @Modified By:
 */
public interface EmployeeDao {
    public Employee getEmployeeById(Integer id);
    public Employee getEmployeeByIdAndName(@Param("id") Integer id,
                                           @Param("empname") String empname);
    public Employee getEmployeeByIdAndNameMap(Map<String,Object> map);

    public int updateEmployee(Employee employee);
    public int deleteEmployee(Integer id);
    public int insertEmployee(Employee employee);
    public int insertEmployee2(Employee employee);

    //查询所有员工
    public List<Employee> getAllEmps();

    //查询所有员工,返回一个Map,将id作为key,实体对象Employee作为value
    @MapKey("id")
    public Map<Integer,Employee> getAllEmpsReturnMap();

    //返回值是一个map
    public Map<String,Object> getEmployeeByIdReturnMap(Integer id);

}

EmployeeDao.xml中的查询所有员工:

<!--
     查询所有员工,返回一个Map,将id作为key,实体对象Employee作为value
     public Map<Integer,Employee> getAllEmpsReturnMap();
-->

      <select id="getAllEmpsReturnMap" resultType="com.xu1.bean.Employee">
        select * from t_employee
    </select>

test:

/**
 *
 * @Description
 * 查询所有员工,返回一个Map,将id作为key,实体对象Employee作为value
 * @Date 2022/6/12 21:57
 *
 */
@Test
public void queryAllEmpsReturnMap() {
    SqlSession sqlSession = null;
    try {
        sqlSession = sqlSessionFactory.openSession();
        EmployeeDao employeeDao = sqlSession.getMapper(EmployeeDao.class);
        Map<Integer, Employee> allEmpsReturnMap = employeeDao.getAllEmpsReturnMap();
        System.out.println(allEmpsReturnMap);
    } finally {
        sqlSession.close();
    }
}

2-8 Sql映射文件---resultMap自定义封装规则

解决的问题:解决数据库表的属性名与其所对应的实体属性名不一致

问题引出:

image-20220613075756766

解决:

方式1:在全局配置文件中引入以下标签,要求属性名与数据库类名符合驼峰命名规则

<!--    2.这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。-->
    <settings>
<!--        mapUnderscoreToCamelCase:是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

方式2:起别名

image-20220613080256510

方式3:自定义结果集(resultMap):自己定义每一列数据和javaBean的映射规则

CatDao.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:名称空间;写接口的全类名,相当于告诉Mybatis这个配置文件是实现了那个接口-->
<mapper namespace="com.xu1.dao.CatDao">

<!--
  resultType="com.xu1.bean.Cat":使用的是默认的封装规则,默认规则中实体属性名与数据库中表属性名一致
  resultMap="mycat":使用自定义的规则对数据封装
  -->
    <select id="getCatById" resultMap="mycat">
        select * from t_cat where id=#{id}
    </select>
    <!--
      自定义结果集(resultMap):自己定义每一列数据和javaBean的映射规则
      type="":指定为哪一个javaBean自定义封装规则(写全类名)
      id="":唯一标识;别名在后面引用
    -->
    <resultMap id="mycat" type="com.xu1.bean.Cat">
        <!--  指定主键类的对应规则:
        property:对应的实体类中的属性名
        column:对应数据库中的列名
        -->
        <id property="id" column="id"/>
        <!--  普通列    -->
        <result property="name" column="cName"/>
        <result property="age" column="cAge"/>
        <result property="gender" column="cgender"/>
    </resultMap>
</mapper>

Cat.java:

package com.xu1.bean;

/**
 * @auther xu
 * @Description
 * @date 2022/6/13 - 7:33
 * @Modified By:
 */
public class Cat {

    private Integer id;
    private String name;
    private String age;
    private String gender;

    public Cat() {
    }

    public Cat(Integer id, String name, String age, String gender) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    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 String getAge() {
        return age;
    }

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

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

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

输出:

image-20220613082727860

2-9 Sql映射文件---联合查询1--级联属性的方式封装查出的数据

image-20220703135758719

mysql中创建两个表:

image-20220703145608766

image-20220703145637742

外键关联主键:

image-20220703145801656

KeyDao.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:名称空间;写接口的全类名,相当于告诉Mybatis这个配置文件是实现了那个接口-->
<mapper namespace="com.xu1.dao.KeyDao">
    <select id="getKeyById" resultMap="myKey">
        SELECT k.`keyId` ,k.`keyName`,k.`locakId`,l.` lockId`,l.`lockName` FROM t_key k
            LEFT JOIN t_lock l ON k.`locakId`=l.` lockId`
            WHERE k.`keyId`=#{id}
    </select>
    <resultMap id="myKey" type="com.xu1.bean.Key">
        <!--
            实体中的属性:
                private Integer id;
                private String keyName;
                private Lock lock;
            数据库表中的属性:
              keyId  keyName     locakId   lockId  lockName
                  1  1号钥匙         1         1       1号锁
         -->
        <id property="id" column="keyId"/>
        <result property="keyName" column="keyName"/>
        <result property="lock.id" column=" lockId"/>
        <result property="lock.lockName" column="lockName"/>
    </resultMap>
</mapper>

注意:

image-20220704051452387

输出结果:

image-20220704051554728

代码参考:

Key.java:

package com.xu1.bean;

/**
 * @auther xu
 * @Description
 * @date 2022/07/03 - 12:57:38
 * @Modified By:
 */
public class Key {
    private Integer id;
    private String keyName;
    private Lock lock;

    public Key() {
    }

    public Key(Integer id, String keyName, Lock lock) {
        this.id = id;
        this.keyName = keyName;
        this.lock = lock;
    }

    public Integer getId() {
        return id;
    }

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

    public String getKeyName() {
        return keyName;
    }

    public void setKeyName(String keyName) {
        this.keyName = keyName;
    }

    public Lock getLock() {
        return lock;
    }

    public void setLock(Lock lock) {
        this.lock = lock;
    }

    @Override
    public String toString() {
        return "Key{" +
                "id=" + id +
                ", keyName='" + keyName + '\'' +
                ", lock=" + lock +
                '}';
    }
}

Lock.java:

package com.xu1.bean;

/**
 * @auther xu
 * @Description
 * @date 2022/07/03 - 12:59:06
 * @Modified By:
 */
public class Lock {
    private Integer id;
    private String lockName;
    public Lock() {
    }

    public Lock(Integer id, String lockName) {
        this.id = id;
        this.lockName = lockName;
    }

    public Integer getId() {
        return id;
    }

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

    public String getLockName() {
        return lockName;
    }

    public void setLockName(String lockName) {
        this.lockName = lockName;
    }

    @Override
    public String toString() {
        return "Lock{" +
                "id=" + id +
                ", lockName='" + lockName + '\'' +
                '}';
    }
}

KeyDao.java:

package com.xu1.dao;

import com.xu1.bean.Key;

/**
 * @auther xu
 * @Description
 * @date 2022/07/03 - 14:04:29
 * @Modified By:
 */
public interface KeyDao {
    public Key getKeyById(Integer id);

}

2-10 Sql映射文件--联合查询2,使用association定义联合查询对象的封装规则(mybatis推荐使用)

解决的问题:对于实体中级联属性的数据封装(eg:Key类中的Lock属性)

image-20220704051954113

KeyDao.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:名称空间;写接口的全类名,相当于告诉Mybatis这个配置文件是实现了那个接口-->
<mapper namespace="com.xu1.dao.KeyDao">
    <select id="getKeyById" resultMap="myKey">
        SELECT k.`keyId` ,k.`keyName`,k.`locakId`,l.` lockId`,l.`lockName` FROM t_key k
            LEFT JOIN t_lock l ON k.`locakId`=l.` lockId`
            WHERE k.`keyId`=#{id}
    </select>
<!--    <resultMap id="myKey" type="com.xu1.bean.Key">-->
<!--        &lt;!&ndash;-->
<!--            实体中的属性:-->
<!--                private Integer id;-->
<!--                private String keyName;-->
<!--                private Lock lock;-->
<!--            数据库表中的属性:-->
<!--              keyId  keyName     locakId   lockId  lockName-->
<!--                  1  1号钥匙         1         1       1号锁-->
<!--         &ndash;&gt;-->
<!--        <id property="id" column="keyId"/>-->
<!--        <result property="keyName" column="keyName"/>-->
<!--        <result property="lock.id" column=" lockId"/>-->
<!--        <result property="lock.lockName" column="lockName"/>-->
<!--    </resultMap>-->

    <resultMap id="myKey" type="com.xu1.bean.Key">
        <!--
            实体中的属性:
                private Integer id;
                private String keyName;
                private Lock lock;
            数据库表中的属性:
              keyId  keyName     locakId   lockId  lockName
                  1  1号钥匙         1         1       1号锁
         -->
        <id property="id" column="keyId"/>
        <result property="keyName" column="keyName"/>

        <!--  使用association完成对级联属性的封装  -->
        <!--  接下来的属性是一个对象,自定义这个对象的封装规则,使用association表示联合了一个对象 -->
        <!-- javaType:指定这个属性的类型 -->
        <association property="lock" javaType="com.xu1.bean.Lock">
            <!-- 定义lock属性对应的这个Lock对象如何封装 -->
            <id property="id" column=" lockId"/>
            <result property="lockName" column="lockName"/>
        </association>
    </resultMap>
</mapper>

结果:

image-20220704053210319

2-11 Sql映射文件-联合查询3---一对多,多对一,多对多说明

2-11-1 对于一对多(1-n)与多对一(n-1)使用外键说明:

image-20220704055625288

image-20220704055657014

说明:

站在学生的角度,一个学生可能被多个老师教,是一对多的关系;站在老师的角度,一个老师可能教多个学生,也是一对多的关系;

此时,外键应该放到一对多,所对应的“多”的那个表里面。

2-11-2 对于n-n关系说明:

image-20220704060618836

2-12 Sql映射文件--联合查询4--collection定义集合类型属性的封装规则

解决的问题:处理类中的集合属性

示例:一把锁可能对应多把钥匙(1-n关系),对于处理Lock类中钥匙的集合属性

LockDao.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.xu1.dao.LockDao">
    <select id="getLockById" resultMap="myLock">
        SELECT l.` lockId`,l.`lockName`, k.`keyId`,k.`keyName`,k.`locakId` FROM t_lock l
            LEFT JOIN t_key k ON k.`locakId`=l.` lockId`
            WHERE  l.` lockId`=#{id}
    </select>


    <resultMap id="myLock" type="com.xu1.bean.Lock">
        <!--
         实体属性:
                private Integer id;
                private String lockName;

                //查询锁的时候,把所对应的钥匙也查询出来
                private List<Key> keylist;

         数据库中列表属性:
                lockId  lockName    keyId  keyName     locakId
                  3      303办公室的锁  3  303钥匙1          3
                  3      303办公室的锁  4  303钥匙2          3
                  3      303办公室的锁  5  303钥匙3          3
         -->
        <id property="id" column=" lockId"/>
        <result property="lockName" column="lockName"/>

        <!--
            collection:定义集合元素的封装
            property:指定哪一个属性是集合属性
            ofType:指定集合里面元素的类型
         -->
        <collection property="keylist" ofType="com.xu1.bean.Key">
            <id property="id" column="keyId"/>
            <result property="keyName" column="keyName"/>
            <!--  因为本来就是对Lock类中属性封装,对于Key类中的Lock属性可以不写(也可以写)  -->
        </collection>
    </resultMap>
</mapper>

结果:

image-20220704092419845

代码参考:

Lock.java:

package com.xu1.bean;

import java.util.List;

/**
 * @auther xu
 * @Description
 * @date 2022/07/03 - 12:59:06
 * @Modified By:
 */
public class Lock {
    private Integer id;
    private String lockName;

    //查询锁的时候,把所对应的钥匙也查询出来
    private List<Key> keylist;

    public Lock() {
    }

    public Lock(Integer id, String lockName) {
        this.id = id;
        this.lockName = lockName;
    }

    public Integer getId() {
        return id;
    }

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

    public String getLockName() {
        return lockName;
    }

    public void setLockName(String lockName) {
        this.lockName = lockName;
    }

    public List<Key> getKeylist() {
        return keylist;
    }

    public void setKeylist(List<Key> keylist) {
        this.keylist = keylist;
    }

    @Override
    public String toString() {
        return "Lock{" +
                "id=" + id +
                ", lockName='" + lockName + '\'' +
                ", keylist=" + keylist +
                '}';
    }
}

LockDao.java

package com.xu1.dao;

import com.xu1.bean.Lock;

/**
 * @auther xu
 * @Description
 * @date 2022/07/04 - 8:01:54
 * @Modified By:
 */
public interface LockDao {

    //查锁的时候将钥匙也查出来
    public Lock getLockById(Integer id);
}

Key.java:

package com.xu1.bean;

/**
 * @auther xu
 * @Description
 * @date 2022/07/03 - 12:57:38
 * @Modified By:
 */
public class Key {
    private Integer id;
    private String keyName;
    private Lock lock;

    public Key() {
    }

    public Key(Integer id, String keyName, Lock lock) {
        this.id = id;
        this.keyName = keyName;
        this.lock = lock;
    }

    public Integer getId() {
        return id;
    }

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

    public String getKeyName() {
        return keyName;
    }

    public void setKeyName(String keyName) {
        this.keyName = keyName;
    }

    public Lock getLock() {
        return lock;
    }

    public void setLock(Lock lock) {
        this.lock = lock;
    }

    @Override
    public String toString() {
        return "Key{" +
                "id=" + id +
                ", keyName='" + keyName + '\'' +
                ", lock=" + lock +
                '}';
    }
}

2-13 Sql映射文件--联合查询5--使用select属性指定分步查询

解决的问题:使用分步查询取代联合查询

分步查询:先id查询满足要求的所以key,然后再查询所对应的锁

第一步在dao中定义方法:

image-20220704174324401

第二步:对于接口中方法的实现,以及将查询的结果封装

Key.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:名称空间;写接口的全类名,相当于告诉Mybatis这个配置文件是实现了那个接口-->
<mapper namespace="com.xu1.dao.KeyDao">
    <!--
        public Key getKeyByIdSimple(Integer id);
    -->
    <select id="getKeyByIdSimple" resultMap="myKey02">
        select * from t_key k where k.`keyId`=#{id}
    </select>
    <!--  对结果集的自定义封装  -->
    <resultMap id="myKey02" type="com.xu1.bean.Key">
    <!--
        实体属性:
                private Integer id;
                private String keyName;
                private Lock lock;
         数据库所对应的属性:
                keyId  keyName     locakId

                 1      1号钥匙         1
                 2      2号钥匙         2
                 3      303钥匙1        3
                 4      303钥匙2        3
                 5      303钥匙3        3
    -->
        <id property="id" column="keyId"/>
        <result property="keyName" column="keyName"/>
        <!--
            告诉mybatis自己去调用一个查询锁的方法
            select="",指定一个查询sql的方法,mybatis调用该方法将查出的Lock封装进来
            public Lock getLockByIdSimple(Integer id);查询锁时需要传入的id
            column:告诉mybatis把数据库中那一列的属性值传递过去
        -->
        <association property="lock" select="com.xu1.dao.LockDao.getLockByIdSimple"
                     column="locakId"/>
    </resultMap>
</mapper>

Lock.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.xu1.dao.LockDao">

    <!--
      public Lock getLockByIdSimple(Integer id);
    -->
    <select id="getLockByIdSimple" resultMap="myLock02">
        select l.` lockId`,l.`lockName` from t_lock l where l.` lockId`=#{id}
    </select>
    <resultMap id="myLock02" type="com.xu1.bean.Lock">
        <id property="id" column=" lockId"/>
        <result property="lockName" column="lockName"/>
    </resultMap>
</mapper>

第3步:查询结果

image-20220704175458061

总结:

使用分步查询可以取代联合查询:

以上过程实际上分为以下两步:

image-20220704175944792

image-20220704180327555

2-14 sql映射文件---联合查询---按需查询和延迟查询

image-20220705083807006

image-20220705084346675

image-20220705084718914

2-15 sql映射文件--联合查询--collection分布查询延迟(不推荐使用:使用联合查询只涉及对数据库一次操作一条sql语句,而使用分布查询涉及多次数据库查询操作,增加开销)

解决的问题:eg:一把锁对应多把钥匙,当只需要查询锁的名字的时候,只需要查询一次sql即可;但是当要查询锁所对应的钥匙集合时,还需要进行一次查询,也就是所谓的延迟查询

代码:

image-20220706085831541

Lock.xml:

<select id="getLockByIdByStep" resultMap="myLockStep">
    select l.` lockId`,l.`lockName` from t_lock l where l.` lockId`=#{id}
</select>
<resultMap id="myLockStep" type="com.xu1.bean.Lock">
    <!--
         public Lock getLockByIdByStep(Integer id);
         Lock类的属性:
                   private Integer id;
                   private String lockName;
                   //查询锁的时候,把所对应的钥匙也查询出来
                   private List<Key> keylist;
         数据库被映射的属性:
                lockId  lockName

                  1      1号锁
                  2      2号锁
                  3      303办公室的锁

    -->
    <id property="id" column=" lockId"/>
    <result property="lockName" column="lockName"/>
    <!--
        一把锁可能对应多把钥匙,传入锁的id查找出其所对应的钥匙的集合
    -->
    <collection property="keylist" column=" lockId"
                select="com.xu1.dao.KeyDao.getKeyByLockId"/>
</resultMap>

image-20220706085940848

image-20220706090033259

结果:

image-20220706084929132

image-20220706085328156

第3章--动态sql

3-1 动态sql---if标签

OGNL表达式:

image-20220706145439285

补充:

image-20220706151425983

TeacherDao.xml:其中包含动态sql--if标签

<?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.xu1.dao.TeacherDao">

    <!--
    映射实体类属性:
        private Integer id;
        private String name;
        private String course;
        private String address;
        private Date date;

    数据库表属性值:
        id  teacherName  class_name  address  birth_date
         1  admin        math        芙蓉区      2022-07-06
         2  tomcat       Chinese     海淀区      2022-07-22
         3  Tom          English     福田区      2022-07-19
    -->

    <resultMap id="myTeacher" type="com.xu1.bean.Teacher">
        <id property="id" column="id"/>
        <result property="name" column="teacherName"/>
        <result property="course" column="class_name"/>
        <result property="address" column="address"/>
        <result property="date" column="birth_date"/>
    </resultMap>
<!--
     //直接传入对象,根据动态条件进行查询
      public List<Teacher> getTeacherByCondition(Teacher teacher);
-->
    <select id="getTeacherByCondition" resultMap="myTeacher">
        select * from t_teacher where
            <!--
                test="":编写判断条件
                id!=null,取出传入的javaBean属性中的id值,判断其是否为空
            -->
            <if test="id!=null">
                id > #{id} and
            </if>
            <!--
                空串""
                and:&&
                or:||
                if():传入非常强大的判断条件;OGNL表达式
            -->
            <if test="name!=null &amp;&amp; !name.equals(  &quot; &quot;)">
                teacherName like #{name} and
            </if>
            <if test="date!=null">
                birth_date &lt; #{date}
            </if>
    </select>
</mapper>

查询结果:

image-20220706151131602

代码参考:

Teacher.java:

package com.xu1.bean;

import java.util.Date;

/**
 * @auther xu
 * @Description
 * @date 2022/07/06 - 9:50:25
 * @Modified By:
 */
public class Teacher {
    private Integer id;
    private String name;
    private String course;
    private String address;
    private Date date;

    public Teacher() {
    }

    public Teacher(Integer id, String name, String course, String address, Date date) {
        this.id = id;
        this.name = name;
        this.course = course;
        this.address = address;
        this.date = date;
    }

    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 String getCourse() {
        return course;
    }

    public void setCourse(String course) {
        this.course = course;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", course='" + course + '\'' +
                ", address='" + address + '\'' +
                ", date=" + date +
                '}';
    }
}

TeacherDao.java:

package com.xu1.dao;

import com.xu1.bean.Teacher;

import java.util.List;

/**
 * @auther xu
 * @Description
 * @date 2022/07/06 - 9:55:03
 * @Modified By:
 */
public interface TeacherDao {
    public Teacher getTeacherById(int i);

    //直接传入对象,根据动态条件进程查询
    public List<Teacher> getTeacherByCondition(Teacher teacher);
}

测试方法:

@Test
public void dy_sqlTest02() {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    TeacherDao mapper = sqlSession.getMapper(TeacherDao.class);

    Teacher teacher = new Teacher();
    teacher.setId(1);
    teacher.setName("%a%");
    teacher.setDate(new Date());
    
    List<Teacher> teacherByCondition = mapper.getTeacherByCondition(teacher);
    //遍历list
    teacherByCondition.forEach(System.out::println);
}

3-2 动态sql--where标签(开发中推荐使用,注意and)

以上动态sql--if查询有一个缺点:eg:如果最后一个判断date的if条件不成立,拼串会多一个and

TeacherDao.xml:也就是将where查询条件标签化

<?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.xu1.dao.TeacherDao">

    <!--
    映射实体类属性:
        private Integer id;
        private String name;
        private String course;
        private String address;
        private Date date;

    数据库表属性值:
        id  teacherName  class_name  address  birth_date
         1  admin        math        芙蓉区      2022-07-06
         2  tomcat       Chinese     海淀区      2022-07-22
         3  Tom          English     福田区      2022-07-19
    -->

    <resultMap id="myTeacher" type="com.xu1.bean.Teacher">
        <id property="id" column="id"/>
        <result property="name" column="teacherName"/>
        <result property="course" column="class_name"/>
        <result property="address" column="address"/>
        <result property="date" column="birth_date"/>
    </resultMap>
<!--
     //直接传入对象,根据动态条件进程查询
      public List<Teacher> getTeacherByCondition(Teacher teacher);

-->
    <select id="getTeacherByCondition" resultMap="myTeacher">
        select * from t_teacher
        <!--where标签帮我们剔除前面多余的and-->
        <where>
            <!--
                test="":编写判断条件
                id!=null,取出传入的javaBean属性中的id值,判断其是否为空
            -->
            <if test="id!=null">
                id > #{id}
            </if>
            <!--
                空串""
                and:&&
                or:||
                if():传入非常强大的判断条件;OGNL表达式
            -->
            <if test="name!=null &amp;&amp; !name.equals(  &quot; &quot;)">
                and teacherName like #{name}
            </if>
            <if test="date!=null">
                and birth_date &lt; #{date}
            </if>
        </where>
    </select>



</mapper>

查询结果测试:

image-20220706155531993

3-3 动态sql-trim标签

image-20220706155913036

TeacherDao.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.xu1.dao.TeacherDao">

    <!--
    映射实体类属性:
        private Integer id;
        private String name;
        private String course;
        private String address;
        private Date date;

    数据库表属性值:
        id  teacherName  class_name  address  birth_date
         1  admin        math        芙蓉区      2022-07-06
         2  tomcat       Chinese     海淀区      2022-07-22
         3  Tom          English     福田区      2022-07-19
    -->

    <resultMap id="myTeacher" type="com.xu1.bean.Teacher">
        <id property="id" column="id"/>
        <result property="name" column="teacherName"/>
        <result property="course" column="class_name"/>
        <result property="address" column="address"/>
        <result property="date" column="birth_date"/>
    </resultMap>

    <select id="getTeacherById" resultMap="myTeacher">
        select * from t_teacher where id=#{id}
    </select>


<!--
     //直接传入对象,根据动态条件进程查询
      public List<Teacher> getTeacherByCondition(Teacher teacher);

-->
    <select id="getTeacherByCondition" resultMap="myTeacher">
        select * from t_teacher
        <!--
            prefix:如果
        -->
        <trim prefix="where" prefixOverrides="and" suffixOverrides="and" >
            <!--
                test="":编写判断条件
                id!=null,取出传入的javaBean属性中的id值,判断其是否为空
            -->
            <if test="id!=null">
                id > #{id} and
            </if>
            <!--
                空串""
                and:&&
                or:||
                if():传入非常强大的判断条件;OGNL表达式
            -->
            <if test="name!=null &amp;&amp; !name.equals(  &quot; &quot;)">
                teacherName like #{name} and
            </if>
            <if test="date!=null">
                and birth_date &lt; #{date}
            </if>
        </trim>
    </select>



</mapper>

测试结果:

image-20220706160712364

image-20220706161135452

3-4 动态sql--foreach标签

image-20220706164001742

image-20220706163638718

TeacherDao.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.xu1.dao.TeacherDao">

    <!--
    映射实体类属性:
        private Integer id;
        private String name;
        private String course;
        private String address;
        private Date date;

    数据库表属性值:
        id  teacherName  class_name  address  birth_date
         1  admin        math        芙蓉区      2022-07-06
         2  tomcat       Chinese     海淀区      2022-07-22
         3  Tom          English     福田区      2022-07-19
    -->

    <resultMap id="myTeacher" type="com.xu1.bean.Teacher">
        <id property="id" column="id"/>
        <result property="name" column="teacherName"/>
        <result property="course" column="class_name"/>
        <result property="address" column="address"/>
        <result property="date" column="birth_date"/>
    </resultMap>
    
    <!--    
    //根据传入了id集合返回Teacher老师集合
    public List<Teacher> getTeacherByIdIn(@Param(value = "ids") List<Integer> ids);
    
    -->
    <select id="getTeacherByIdIn" resultMap="myTeacher">
            SELECT * FROM t_teacher WHERE id IN 
            <foreach collection="ids" item="id_items" separator="," open="(" close=")">
                #{id_items}
            </foreach>
    </select>
</mapper>

测试结果:

image-20220706164921036

代码参考:

TeacherDao.java:

package com.xu1.dao;

import com.xu1.bean.Teacher;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @auther xu
 * @Description
 * @date 2022/07/06 - 9:55:03
 * @Modified By:
 */
public interface TeacherDao {
    public Teacher getTeacherById(int i);

    //直接传入对象,根据动态条件进程查询
    public List<Teacher> getTeacherByCondition(Teacher teacher);

    //根据传入了id集合返回Teacher老师集合
    public List<Teacher> getTeacherByIdIn(@Param(value = "ids") List<Integer> ids);
}

3-5 动态sql--choose标签

TeacherDao.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.xu1.dao.TeacherDao">

    <!--
    映射实体类属性:
        private Integer id;
        private String name;
        private String course;
        private String address;
        private Date date;

    数据库表属性值:
        id  teacherName  class_name  address  birth_date
         1  admin        math        芙蓉区      2022-07-06
         2  tomcat       Chinese     海淀区      2022-07-22
         3  Tom          English     福田区      2022-07-19
    -->

    <resultMap id="myTeacher" type="com.xu1.bean.Teacher">
        <id property="id" column="id"/>
        <result property="name" column="teacherName"/>
        <result property="course" column="class_name"/>
        <result property="address" column="address"/>
        <result property="date" column="birth_date"/>
    </resultMap>

    <!--
        //直接传入对象,根据动态条件进行查询,使用choose标签,区别于if(类似与if-else:只要有一个满足,就不继续往下查)
        public List<Teacher> getTeacherByChoose(Teacher teacher);
    -->
    <select id="getTeacherByChoose" resultMap="myTeacher">
        SELECT * FROM t_teacher
        <where>
            <choose>
                <when test="id!=null">
                    id = #{id}
                </when>
                <when test="name!=null and name.equal(&quot;&quot;)">
                    teacherName = #{name}
                </when>
                <when test="date!=null">
                    birth_date = #{date}
                </when>
                <otherwise>
                <!-- 以上条件没有1个满足,全部都查询-->
                    1=1
                </otherwise>
            </choose>
        </where>
    </select>


</mapper>

测试结果:

image-20220706170727806

image-20220706170908882

代码参考:

TeacherDao.xml:

package com.xu1.dao;

import com.xu1.bean.Teacher;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @auther xu
 * @Description
 * @date 2022/07/06 - 9:55:03
 * @Modified By:
 */
public interface TeacherDao {
    public Teacher getTeacherById(int i);

    //直接传入对象,根据动态条件进程查询
    public List<Teacher> getTeacherByCondition(Teacher teacher);

    //根据传入了id集合返回Teacher老师集合
    public List<Teacher> getTeacherByIdIn(@Param(value = "ids") List<Integer> ids);

    //直接传入对象,根据动态条件进程查询,使用choose标签,区别于if(类似与if-else:只要有一个满足,就不继续往下查)
    public List<Teacher> getTeacherByChoose(Teacher teacher);
}

3-6 动态sql--set标签用于动态更新

<?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.xu1.dao.TeacherDao">
    <!--
    实体:
            private Integer id;
            private String name;
            private String course;
            private String address;
            private Date date;
    数据库:
        id  teacherName  class_name  address    birth_date

        //更新数据
        public int updateTeacher(Teacher teacher);
    -->
    <update id="updateTeacher">
        UPDATE t_teacher
            <set>
                <if test="name!=null and !name.equals(&quot;&quot;)">
                    teacherName = #{name},
                </if>
                <if test="course!=null and !course.equals(&quot;&quot;)">
                    class_name = #{course},
                </if>
                <if test="address!=null and !address.equals(&quot;&quot;)">
                    address = #{address},
                </if>
                <if test="date!=null">
                    birth_date=date
                </if>
            </set>
            <where>
                id=#{id}
            </where>
    </update>
</mapper>

测试结果:

image-20220706175043220

image-20220706175125998

补充:set标签也会自动删除多余的逗号。

代码参考:

TeacherDao.java

package com.xu1.dao;

import com.xu1.bean.Teacher;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @auther xu
 * @Description
 * @date 2022/07/06 - 9:55:03
 * @Modified By:
 */
public interface TeacherDao {
    public Teacher getTeacherById(int i);

    //直接传入对象,根据动态条件进程查询
    public List<Teacher> getTeacherByCondition(Teacher teacher);

    //根据传入了id集合返回Teacher老师集合
    public List<Teacher> getTeacherByIdIn(@Param(value = "ids") List<Integer> ids);

    //直接传入对象,根据动态条件进程查询,使用choose标签,区别于if(类似与if-else:只要有一个满足,就不继续往下查)
    public List<Teacher> getTeacherByChoose(Teacher teacher);

    //更新数据
    public int updateTeacher(Teacher teacher);
}

3-7 动态sql补充

1.OGNL--对象图导航语言

image-20220707085853060

image-20220707091211946

2.对于_parameter和_databaseId说明

image-20220707090947897

代码参考:

<select id="" resultMap="">
      <if test="_parameter">
          
      </if>
      <if test="_databaseId=='MySql'" >
          select * from table
      </if>
      <if test="_databaseId=='Oracle'" >
          select * from table
      </if>
</select>

3-8 抽取可重用的sql

3-8-1--bind标签的介绍

image-20220707091924024

3-8-2 sql标签配合include标签可以实现sql语句的重用

image-20220707092348663

第4章--缓存

4-1 mybatis缓存简介

image-20220707101349691

image-20220707102413733

4-2 体验一级缓存

image-20220707104503197

image-20220707104415880

代码参考:

TeacherDao.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.xu1.dao.TeacherDao">

    <!--
    映射实体类属性:
        private Integer id;
        private String name;
        private String course;
        private String address;
        private Date date;

    数据库表属性值:
        id  teacherName  class_name  address  birth_date
         1  admin        math        芙蓉区      2022-07-06
         2  tomcat       Chinese     海淀区      2022-07-22
         3  Tom          English     福田区      2022-07-19
    -->

    <resultMap id="myTeacher" type="com.xu1.bean.Teacher">
        <id property="id" column="id"/>
        <result property="name" column="teacherName"/>
        <result property="course" column="class_name"/>
        <result property="address" column="address"/>
        <result property="date" column="birth_date"/>
    </resultMap>

    <select id="getTeacherById" resultMap="myTeacher">
        select * from t_teacher where id=#{id}
    </select>

</mapper>

4-3 一级缓存失效的情况

4-3-1 失效情况1

image-20220707105822347

image-20220707110349302

4-3-2 缓存失效情况2

image-20220707110533192

image-20220707110921422

4-3-3 缓存失效情况3

image-20220707111202041

/**
 *
 * @Description
 * 缓存失效的情况3
 * @Date 2022/07/07 10:58:51
 *
 */
@Test
public void cacheTest02() {
    //1.与数据库开启的第1个会话
    SqlSession sqlSession1 = sqlSessionFactory.openSession();
    TeacherDao teacherDao = sqlSession1.getMapper(TeacherDao.class);

    Teacher teacher1 = teacherDao.getTeacherById(1);//查询id=1的老师

    //模拟在会话期间执行增删改
    Teacher teacher = new Teacher();
    teacher.setId(3);
    teacher.setName("333");
    teacherDao.updateTeacher(teacher);

    Teacher teacher2 = teacherDao.getTeacherById(1);//查询id=1的老师
    
    System.out.println(teacher1+"\n"+teacher2);
    sqlSession1.close();
}

结果测试:

image-20220707111736860

4-3-4 手动清空一级缓存

image-20220707112313989

image-20220707112057325

4-3-5 mybatis缓存源码参考

/**
 *    Copyright 2009-2017 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.cache.impl;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;

import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.CacheException;

/**
 * @author Clinton Begin
 */
public class PerpetualCache implements Cache {

  private final String id;

  private Map<Object, Object> cache = new HashMap<Object, Object>();

  public PerpetualCache(String id) {
    this.id = id;
  }

  @Override
  public String getId() {
    return id;
  }

  @Override
  public int getSize() {
    return cache.size();
  }

  @Override
  public void putObject(Object key, Object value) {
    cache.put(key, value);
  }

  @Override
  public Object getObject(Object key) {
    return cache.get(key);
  }

  @Override
  public Object removeObject(Object key) {
    return cache.remove(key);
  }

  @Override
  public void clear() {
    cache.clear();
  }

  @Override
  public ReadWriteLock getReadWriteLock() {
    return null;
  }

  @Override
  public boolean equals(Object o) {
    if (getId() == null) {
      throw new CacheException("Cache instances require an ID.");
    }
    if (this == o) {
      return true;
    }
    if (!(o instanceof Cache)) {
      return false;
    }

    Cache otherCache = (Cache) o;
    return getId().equals(otherCache.getId());
  }

  @Override
  public int hashCode() {
    if (getId() == null) {
      throw new CacheException("Cache instances require an ID.");
    }
    return getId().hashCode();
  }

}

image-20220707113632567

4-4 二级缓存体验

解决的问题:有些数据不需要频繁修改,但是需要经常使用,对于这些数据处理可以采用二级缓存

image-20220707140120483

image-20220707150327870

image-20220707143524496

image-20220707143811077

实验测试:

image-20220707145607746

/**
 *
 * @Description
 * 二级缓存
 * @Date 2022/07/07 10:58:51
 *
 */
@Test
public void cacheTest03() {
    //开启访问数据库的2次会话
    SqlSession sqlSession1 = sqlSessionFactory.openSession();
    SqlSession sqlSession2 = sqlSessionFactory.openSession();

    //使用第一个会话访问数据库id=1的老师,并关闭会话
    TeacherDao teacherDao1 = sqlSession1.getMapper(TeacherDao.class);
    Teacher teacher1 = teacherDao1.getTeacherById(1);
    System.out.println(teacher1);
    sqlSession1.close();

    //使用第二个会话也访问数据库id=1的老师
    TeacherDao teacherDao2 = sqlSession2.getMapper(TeacherDao.class);
    Teacher teacher2 = teacherDao2.getTeacherById(1);
    System.out.println(teacher2);
    sqlSession2.close();
}

结果分析:

image-20220707145517856

4-5 缓存的查询顺序

image-20220707151110690

image-20220707152057942

image-20220707153100584

4-6 缓存原理(重要)

image-20220708050027573

4-7缓存有关的属性

image-20220708051344093

4-7-1 useCache标签表明是否使用二级缓存:

image-20220708051257840

image-20220708051920631

4-8 整合第3方缓存库--以EHCache为例子说明

image-20220708054606594

第1步:导入依赖

<!--        使用第3方缓存库,EHcache需要导入的依赖-->
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-core</artifactId>
            <version>2.6.11</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.caches</groupId>
            <artifactId>mybatis-ehcache</artifactId>
            <version>1.0.3</version>
        </dependency>
        <!--    使用EHcache需要的日志依赖    -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.32</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.6</version>
        </dependency>

第2步:写配置文件

image-20220708060132692

参考:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
 <!-- 磁盘保存路径 -->
 <diskStore path="D:\44\ehcache" />
 
 <defaultCache 
   maxElementsInMemory="1" 
   maxElementsOnDisk="10000000"
   eternal="false" 
   overflowToDisk="true" 
   timeToIdleSeconds="120"
   timeToLiveSeconds="120" 
   diskExpiryThreadIntervalSeconds="120"
   memoryStoreEvictionPolicy="LRU">
 </defaultCache>
</ehcache>
 
<!-- 
属性说明:
l diskStore:指定数据在磁盘中的存储位置。
l defaultCache:当借助CacheManager.add("demoCache")创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略
 
以下属性是必须的:
l maxElementsInMemory - 在内存中缓存的element的最大数目 
l maxElementsOnDisk - 在磁盘上缓存的element的最大数目,若是0表示无穷大
l eternal - 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断
l overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上
 
以下属性是可选的:
l timeToIdleSeconds - 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时,这些数据便会删除,默认值是0,也就是可闲置时间无穷大
l timeToLiveSeconds - 缓存element的有效生命期,默认是0.,也就是element存活时间无穷大
 diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区.
l diskPersistent - 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false。
l diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔,默认是120秒。每个120s,相应的线程会进行一次EhCache中数据的清理工作
l memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)
 -->

第3步:进行实验

image-20220708060515571

1.需要表明使用Ehcache作为二级缓存:

image-20220708061747111

2.查询结果:补充(该实体类可以不用实现序列化接口)

image-20220708061612778

3.将数据保存到磁盘中:

image-20220708062529514

4.共用别的二级缓存空间:

image-20220708062948893

第5章--ssm整合

5-1 环境配置

第一步:导包

image-20220708110510954

1)、Spring

【aop核心】4
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar

【ioc核心】6
commons-logging-1.1.3.jar
spring-aop-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar

【jdbc核心】3
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar

【测试】1
spring-test-4.0.0.RELEASE.jar

2)、SpringMVC

【ajax】
jackson-annotations-2.1.5.jar
jackson-core-2.1.5.jar
jackson-databind-2.1.5.jar
【数据校验】
hibernate-validator-5.0.0.CR2.jar
hibernate-validator-annotation-processor-5.0.0.CR2.jar
classmate-0.8.0.jar
jboss-logging-3.1.1.GA.jar
validation-api-1.1.0.CR1.jar
【上传下载】
commons-fileupload-1.2.1.jar
commons-io-2.0.jar
【jstl-jsp标准标签库】
jstl.jar
standard.jar
【验证码】
kaptcha-2.3.2.jar
【springmvc核心】
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar

3)、MyBatis

【mybatis核心】
mybatis-3.4.1.jarmybatis-spring-1.3.0.jar
【和Spring整合包】
【ehcache整合】
ehcache-core-2.6.8.jar
mybatis-ehcache-1.0.3.jar
log4j-1.2.17.jar
slf4j-api-1.7.21.jar
slf4j-log4j12-1.7.21.jar

4)、其他的

mysql-connector-java-5.1.37-bin.jar
c3p0-0.9.1.2.jar

第2步 写配置

image-20220708110506509

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

<!--    配置spring容器启动-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <!--  指定spring配置文件位置  -->
        <param-value>classpath:spring/applicationContext.xml</param-value>
    </context-param>

<!--    配置springMVC前端控制器-->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/applicationContext-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--  2个标准配置  -->
    <!--  字符编码  -->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--  支持rust风格  -->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

applictionContext.xml:(spring配置)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:content="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"

       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd

       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd

       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--    处理控制器交给springMVC扫描外,其他注解(实体类上的注解)都交给spring扫描-->
    <content:component-scan base-package="com.xu1">
<!--        不需要写use-default-filters,使用默认规则-->
        <content:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </content:component-scan>

<!--1.导入外部配置文件-->
    <context:property-placeholder location="classpath:dbconfig.properties"></context:property-placeholder>
<!--   2.配置数据源-->
    <bean id="db" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.username}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
        <property name="minPoolSize" value="${jdbc.minPoolSize}"></property>
    </bean>

<!--    3.配置JdbcTemplate操作数据库。(现在使用mybatis)-->
<!--    3.配置使用mybatis操作数据库-->


<!--    4.配置事务控制;配置事务管理器,让他控制数据源里面的链接的关闭和提交-->
    <bean id="tm" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--   控制数据源-->
        <property name="dataSource" ref="db"></property>
    </bean>
<!--    5基于xml配置,配置事务;那些方法切入事务还要写切入点表达式-->
    <aop:config>
        <!--  配置切入点表达式  -->
        <aop:pointcut id="txPoint" expression="execution(* com.xu1.service.*.*(..))"/>
        <aop:advisor advice-ref="myTx" pointcut-ref="txPoint"></aop:advisor>
    </aop:config>

<!--    6.配置事务增强,事务属性,事务建议

-->
    <tx:advice id="myTx" transaction-manager="tm">
        <!--    配置事务属性-->
        <tx:attributes>
            <!--  对于所有方法,一旦出现异常,就进行事务回滚 -->
            <tx:method name="*" rollback-for="java.lang.Exception"/>
            <!--  对某一个具体的方法配置事务属性 -->
            <tx:method name="get*" read-only="true"></tx:method>
<!--            <tx:method name="insertEmp" isolation="READ_UNCOMMITTED"></tx:method>-->
        </tx:attributes>
    </tx:advice>
</beans>

applictionContext-mvc.xml:(springMVC配置)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--  SpringMVC只扫描控制器,并禁用默认规则  -->
   <context:component-scan base-package="com.xu1" use-default-filters="false">
       <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
   </context:component-scan>

    <!--    配置一个视图解析器:能帮我们拼接页面的地址-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--    配置文件上传及解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--        设置上传文件的最大尺寸-->
        <property name="maxInMemorySize" value="#{1024*1024*20}"></property>
        <!--        设置默认编码-->
        <property name="defaultEncoding" value="UTF-8"></property>
    </bean>

<!--    扫描静态资源-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>
<!--    扫描动态资源-->
    <mvc:annotation-driven></mvc:annotation-driven>
</beans>

配置mybatis整合包:

第一步:导入可以将代理对象加入ioc容器中的依赖,然后可以利用autoAward

mybatis整合包
mybatis根据dao中的接口类,实现一个dao.xml相当于接口的实现类的配置文件,SqlSession.getMapper(dao.class)得到器接口的代理对象,而以下依赖
可以将该依赖假如ioc容器。

image-20220709075616807

image-20220709080159791

image-20220709080315690

image-20220709084507481

注意:事务控制交给spring管理

代码参考:


<!--    3.配置JdbcTemplate操作数据库。(现在使用mybatis)-->
<!--    3.配置使用mybatis操作数据库-->
        <!--  可以根据配置文件得到sqlSessionFactory  -->
        <bean class="org.mybatis.spring.SqlSessionFactoryBean">
            <!-- 指定mybatis全局配置文件的位置  -->
            <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
            <!-- 指定使用的数据源 -->
            <property name="dataSource" ref="db"></property>
            <!--  指定相当于dao接口实现类的xml文件的位置  -->
            <property name="mapperLocations" value="classpath:mybatis/mapper/*.xml"></property>
        </bean>
        <!-- 把每一个dao接口的实现加入到ioc容器中  -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <!-- 指定dao接口所在的包  -->
            <property name="basePackage" value="com.xu1.dao"></property>
        </bean>

error:跟老师代码一摸一样,不知道是因为使用的是idea软件,还是Tomcat等环境问题导致项目出现如下错误。

D:\Java\servlet2\noteAndSorce\apache-tomcat-8.5.78\bin\catalina.bat run
[2022-07-09 11:32:53,090] Artifact mybatis-07-SSM:war exploded: Waiting for server connection to start artifact deployment...
Using CATALINA_BASE:   "C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Unnamed_mybatisProject"
Using CATALINA_HOME:   "D:\Java\servlet2\noteAndSorce\apache-tomcat-8.5.78"
Using CATALINA_TMPDIR: "D:\Java\servlet2\noteAndSorce\apache-tomcat-8.5.78\temp"
Using JRE_HOME:        "D:\Java\java1.8"
Using CLASSPATH:       "D:\Java\servlet2\noteAndSorce\apache-tomcat-8.5.78\bin\bootstrap.jar;D:\Java\servlet2\noteAndSorce\apache-tomcat-8.5.78\bin\tomcat-juli.jar"
Using CATALINA_OPTS:   ""
09-Jul-2022 11:32:54.169 警告 [main] org.apache.catalina.startup.SetAllPropertiesRule.begin [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'URIEconding' to 'UTF-8' did not find a matching property.
09-Jul-2022 11:32:54.204 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server.服务器版本: Apache Tomcat/8.5.78
09-Jul-2022 11:32:54.204 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 服务器构建:        Mar 31 2022 16:05:28 UTC
09-Jul-2022 11:32:54.204 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 服务器版本号:      8.5.78.0
09-Jul-2022 11:32:54.204 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 操作系统名称:      Windows 10
09-Jul-2022 11:32:54.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log OS.版本:           10.0
09-Jul-2022 11:32:54.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 架构:              amd64
09-Jul-2022 11:32:54.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java 环境变量:     D:\Java\java1.8\jre
09-Jul-2022 11:32:54.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java虚拟机版本:    1.8.0_311-b11
09-Jul-2022 11:32:54.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log JVM.供应商:        Oracle Corporation
09-Jul-2022 11:32:54.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:     C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Unnamed_mybatisProject
09-Jul-2022 11:32:54.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:     D:\Java\servlet2\noteAndSorce\apache-tomcat-8.5.78
09-Jul-2022 11:32:54.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:       -Djava.util.logging.config.file=C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Unnamed_mybatisProject\conf\logging.properties
09-Jul-2022 11:32:54.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:       -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
09-Jul-2022 11:32:54.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:       -Dcom.sun.management.jmxremote=
09-Jul-2022 11:32:54.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:       -Dcom.sun.management.jmxremote.port=1099
09-Jul-2022 11:32:54.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:       -Dcom.sun.management.jmxremote.ssl=false
09-Jul-2022 11:32:54.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:       -Dcom.sun.management.jmxremote.password.file=C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Unnamed_mybatisProject\jmxremote.password
09-Jul-2022 11:32:54.206 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:       -Dcom.sun.management.jmxremote.access.file=C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Unnamed_mybatisProject\jmxremote.access
09-Jul-2022 11:32:54.206 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:       -Djava.rmi.server.hostname=127.0.0.1
09-Jul-2022 11:32:54.206 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:       -Djdk.tls.ephemeralDHKeySize=2048
09-Jul-2022 11:32:54.206 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:       -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
09-Jul-2022 11:32:54.206 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:       -Dignore.endorsed.dirs=
09-Jul-2022 11:32:54.206 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:       -Dcatalina.base=C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Unnamed_mybatisProject
09-Jul-2022 11:32:54.206 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:       -Dcatalina.home=D:\Java\servlet2\noteAndSorce\apache-tomcat-8.5.78
09-Jul-2022 11:32:54.206 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:       -Djava.io.tmpdir=D:\Java\servlet2\noteAndSorce\apache-tomcat-8.5.78\temp
09-Jul-2022 11:32:54.206 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent 使用APR版本[1.7.0]加载了基于APR的Apache Tomcat本机库[1.2.32]。
09-Jul-2022 11:32:54.209 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR功能:IPv6[true]、sendfile[true]、accept filters[false]、random[true]、UDS [{4}]。
09-Jul-2022 11:32:54.209 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL配置:useAprConnector[false],useOpenSSL[true]
09-Jul-2022 11:32:54.212 信息 [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL成功初始化 [OpenSSL 1.1.1n  15 Mar 2022]
09-Jul-2022 11:32:54.329 信息 [main] org.apache.coyote.AbstractProtocol.init 初始化协议处理器 ["http-nio-8080"]
09-Jul-2022 11:32:54.349 信息 [main] org.apache.catalina.startup.Catalina.load Initialization processed in 461 ms
09-Jul-2022 11:32:54.408 信息 [main] org.apache.catalina.core.StandardService.startInternal 正在启动服务[Catalina]
09-Jul-2022 11:32:54.408 信息 [main] org.apache.catalina.core.StandardEngine.startInternal 正在启动 Servlet 引擎:[Apache Tomcat/8.5.78]
09-Jul-2022 11:32:54.429 信息 [main] org.apache.coyote.AbstractProtocol.start 开始协议处理句柄["http-nio-8080"]
09-Jul-2022 11:32:54.460 信息 [main] org.apache.catalina.startup.Catalina.start Server startup in 112 ms
Connected to server
[2022-07-09 11:32:54,759] Artifact mybatis-07-SSM:war exploded: Artifact is being deployed, please wait...
09-Jul-2022 11:32:54.997 警告 [RMI TCP Connection(3)-127.0.0.1] org.apache.tomcat.util.descriptor.web.WebXml.setVersion 未知版本字符串 [4.0]。将使用默认版本。
09-Jul-2022 11:32:56.568 信息 [RMI TCP Connection(3)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间和JSP编译时间。
09-Jul-2022 11:32:56.890 信息 [RMI TCP Connection(3)-127.0.0.1] org.springframework.web.servlet.DispatcherServlet.initServletBean FrameworkServlet 'DispatcherServlet': initialization started
09-Jul-2022 11:32:56.920 信息 [RMI TCP Connection(3)-127.0.0.1] org.springframework.web.context.support.XmlWebApplicationContext.prepareRefresh Refreshing WebApplicationContext for namespace 'DispatcherServlet-servlet': startup date [Sat Jul 09 11:32:56 CST 2022]; root of context hierarchy
09-Jul-2022 11:32:57.032 信息 [RMI TCP Connection(3)-127.0.0.1] org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions Loading XML bean definitions from class path resource [spring/applicationContext-mvc.xml]
09-Jul-2022 11:32:57.543 严重 [RMI TCP Connection(3)-127.0.0.1] org.springframework.web.servlet.DispatcherServlet.initServletBean Context initialization failed
	org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'teacherController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.xu1.service.TeacherService com.xu1.controller.TeacherController.teacherService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xu1.service.TeacherService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
		at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
		at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
		at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
		at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
		at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
		at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
		at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
		at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
		at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:643)
		at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:606)
		at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:657)
		at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:525)
		at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:466)
		at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
		at javax.servlet.GenericServlet.init(GenericServlet.java:158)
		at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1173)
		at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1118)
		at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1011)
		at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4952)
		at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5266)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
		at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:753)
		at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:727)
		at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:695)
		at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1775)
		at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
		at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
		at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.lang.reflect.Method.invoke(Method.java:498)
		at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:291)
		at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
		at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
		at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:483)
		at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:431)
		at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
		at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
		at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.lang.reflect.Method.invoke(Method.java:498)
		at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:291)
		at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
		at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
		at com.sun.jmx.remote.security.MBeanServerAccessController.invoke(MBeanServerAccessController.java:468)
		at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
		at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
		at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
		at java.security.AccessController.doPrivileged(Native Method)
		at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1408)
		at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
		at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
		at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
		at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.lang.reflect.Method.invoke(Method.java:498)
		at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
		at sun.rmi.transport.Transport$1.run(Transport.java:200)
		at sun.rmi.transport.Transport$1.run(Transport.java:197)
		at java.security.AccessController.doPrivileged(Native Method)
		at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
		at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
		at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
		at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
		at java.security.AccessController.doPrivileged(Native Method)
		at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
		at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
		at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
		at java.lang.Thread.run(Thread.java:748)
	Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.xu1.service.TeacherService com.xu1.controller.TeacherController.teacherService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xu1.service.TeacherService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
		at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
		at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
		at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
		... 67 more
	Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xu1.service.TeacherService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
		at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1100)
		at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
		at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855)
		at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
		... 69 more
[2022-07-09 11:32:57,578] Artifact mybatis-07-SSM:war exploded: Artifact is deployed successfully
[2022-07-09 11:32:57,578] Artifact mybatis-07-SSM:war exploded: Deploy took 2,819 milliseconds
09-Jul-2022 11:33:00.713 信息 [http-nio-8080-exec-6] org.springframework.web.servlet.DispatcherServlet.initServletBean FrameworkServlet 'DispatcherServlet': initialization started
09-Jul-2022 11:33:00.714 信息 [http-nio-8080-exec-6] org.springframework.web.context.support.XmlWebApplicationContext.prepareRefresh Refreshing WebApplicationContext for namespace 'DispatcherServlet-servlet': startup date [Sat Jul 09 11:33:00 CST 2022]; root of context hierarchy
09-Jul-2022 11:33:00.715 信息 [http-nio-8080-exec-6] org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions Loading XML bean definitions from class path resource [spring/applicationContext-mvc.xml]
09-Jul-2022 11:33:00.767 严重 [http-nio-8080-exec-6] org.springframework.web.servlet.DispatcherServlet.initServletBean Context initialization failed
	org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'teacherController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.xu1.service.TeacherService com.xu1.controller.TeacherController.teacherService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xu1.service.TeacherService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
		at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
		at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
		at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
		at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
		at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
		at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
		at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
		at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
		at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:643)
		at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:606)
		at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:657)
		at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:525)
		at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:466)
		at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
		at javax.servlet.GenericServlet.init(GenericServlet.java:158)
		at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1173)
		at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1118)
		at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:789)
		at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:128)
		at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
		at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:543)
		at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
		at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
		at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:698)
		at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
		at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:367)
		at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:639)
		at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
		at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:882)
		at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1647)
		at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
		at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
		at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
		at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
		at java.lang.Thread.run(Thread.java:748)
	Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.xu1.service.TeacherService com.xu1.controller.TeacherController.teacherService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xu1.service.TeacherService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
		at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
		at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
		at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
		... 37 more
	Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xu1.service.TeacherService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
		at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1100)
		at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
		at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855)
		at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
		... 39 more
09-Jul-2022 11:33:04.443 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [D:\Java\servlet2\noteAndSorce\apache-tomcat-8.5.78\webapps\manager]
09-Jul-2022 11:33:04.680 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[D:\Java\servlet2\noteAndSorce\apache-tomcat-8.5.78\webapps\manager]的部署已在[236]毫秒内完成

第6章--MGB

简介:

image-20220711141532871

mybatis官网:mybatis与Spring整合等其他各种产品

mybatis官网

mybatis-spring文档:mybati-spring文档

6-1 MGB官方文档

MGB官方文档

image-20220711153038242

6-1 使用MBG之清晰简洁版(【尚硅谷】2022版MyBatis零基础入门教程(细致全面,快速上手))

image-20220711164129295

pom.xml:

<?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">
    <parent>
        <artifactId>mybatisProject</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>mybatis-08-MBG</artifactId>
    <dependencies>
        <!-- MyBatis核心依赖包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>
        <!-- junit测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <!-- MySQL驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.27</version>
        </dependency>
        <!-- log4j日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>
    <!-- 控制Maven在构建过程中相关配置 -->
    <build>
        <!-- 构建过程中用到的插件 -->
        <plugins>
            <!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 -->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.0</version>
                <!-- 插件的依赖 -->
                <dependencies>
                    <!-- 逆向工程的核心依赖 -->
                    <dependency>
                        <groupId>org.mybatis.generator</groupId>
                        <artifactId>mybatis-generator-core</artifactId>
                        <version>1.3.2</version>
                    </dependency>
                    <!-- 数据库连接池 -->
                    <dependency>
                        <groupId>com.mchange</groupId>
                        <artifactId>c3p0</artifactId>
                        <version>0.9.2</version>
                    </dependency>
                    <!-- MySQL驱动 -->
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.27</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

</project>

generatorConfig.xml:

<!DOCTYPE generatorConfiguration PUBLIC
        "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <context id="DB2tables" targetRuntime="MyBatis3Simple">
<!--  1.连接数据源-->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/mybatis_0325"
                        userId="root" password="draf19"/>
<!--
2.javaModelGenerator:生成pojo
targetPackage:生成的pojo放到哪一个包下
-->
        <javaModelGenerator targetPackage="com.xu1.bean" targetProject=".\src\main\java">
<!--            是否使用子包,也就是是否使用多级目录-->
            <property name="enableSubPackages" value="true"/>
<!--            去掉表属性名左右的空格-->
            <property name="trimString" value="true"/>
        </javaModelGenerator>
<!--3.sql映射文件生成器;指定xml生成的地方-->
        <sqlMapGenerator targetPackage="com.xu1.dao" targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
<!--4.dao接口生成的地方-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.xu1.dao" targetProject=".\src\main\java"/>

<!--5.
table:指定要逆向生成数据库中的哪一张表
tableName:表名
domainObjectName:映射的实体名
-->
        <table tableName="t_teacher" domainObjectName="Teacher"/>
        <table tableName="t_cat" domainObjectName="Cat"/>
        <table tableName="t_employee" domainObjectName="Employee"/>
    </context>
</generatorConfiguration>

mybatis-config.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>-->
<!--        &lt;!&ndash;    延迟加载,按需查询sql语句    &ndash;&gt;-->
<!--        <setting name="lazyLoadingEnabled" value="true"/>-->
<!--        <setting name="aggressiveLazyLoading" value="false"/>-->
<!--        -->
<!--&lt;!&ndash;        开启全局缓存开关&ndash;&gt;-->
<!--        <setting name="cacheEnabled" value="true"/>-->
<!--    </settings>-->

    <settings>
        <!--        mapUnderscoreToCamelCase:是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <typeAliases>
        <package name=""/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_0325"/>
                <property name="username" value="root"/>
                <property name="password" value="draf19"/>
            </dataSource>
        </environment>
    </environments>

<!--    引入我们编写的每一个接口的实现文件-->
        <mappers>
<!--            <package name="com.xu1.dao"/>-->
            <package name=""/>
        </mappers>
</configuration>

结果:

逆向生成bean,dao,以及xml配置文件,具体见mybati-08-MBG,以下看一下自动生成老师表映射文件与实体类。

TeacherMapper.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.xu1.dao.TeacherMapper">
  <resultMap id="BaseResultMap" type="com.xu1.bean.Teacher">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Mon Jul 11 16:38:05 CST 2022.
    -->
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="teacherName" jdbcType="VARCHAR" property="teachername" />
    <result column="class_name" jdbcType="VARCHAR" property="className" />
    <result column="address" jdbcType="VARCHAR" property="address" />
    <result column="birth_date" jdbcType="DATE" property="birthDate" />
  </resultMap>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Mon Jul 11 16:38:05 CST 2022.
    -->
    delete from t_teacher
    where id = #{id,jdbcType=INTEGER}
  </delete>
  <insert id="insert" parameterType="com.xu1.bean.Teacher">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Mon Jul 11 16:38:05 CST 2022.
    -->
    insert into t_teacher (id, teacherName, class_name, 
      address, birth_date)
    values (#{id,jdbcType=INTEGER}, #{teachername,jdbcType=VARCHAR}, #{className,jdbcType=VARCHAR}, 
      #{address,jdbcType=VARCHAR}, #{birthDate,jdbcType=DATE})
  </insert>
  <update id="updateByPrimaryKey" parameterType="com.xu1.bean.Teacher">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Mon Jul 11 16:38:05 CST 2022.
    -->
    update t_teacher
    set teacherName = #{teachername,jdbcType=VARCHAR},
      class_name = #{className,jdbcType=VARCHAR},
      address = #{address,jdbcType=VARCHAR},
      birth_date = #{birthDate,jdbcType=DATE}
    where id = #{id,jdbcType=INTEGER}
  </update>
  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Mon Jul 11 16:38:05 CST 2022.
    -->
    select id, teacherName, class_name, address, birth_date
    from t_teacher
    where id = #{id,jdbcType=INTEGER}
  </select>
  <select id="selectAll" resultMap="BaseResultMap">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Mon Jul 11 16:38:05 CST 2022.
    -->
    select id, teacherName, class_name, address, birth_date
    from t_teacher
  </select>
</mapper>

TeacherMapper.java:

package com.xu1.dao;

import com.xu1.bean.Teacher;
import java.util.List;

public interface TeacherMapper {
    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    int deleteByPrimaryKey(Integer id);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    int insert(Teacher record);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    Teacher selectByPrimaryKey(Integer id);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    List<Teacher> selectAll();

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    int updateByPrimaryKey(Teacher record);
}

Teacher.java:

package com.xu1.bean;

import java.util.Date;

public class Teacher {
    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_teacher.id
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    private Integer id;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_teacher.teacherName
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    private String teachername;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_teacher.class_name
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    private String className;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_teacher.address
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    private String address;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_teacher.birth_date
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    private Date birthDate;

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_teacher.id
     *
     * @return the value of t_teacher.id
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    public Integer getId() {
        return id;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_teacher.id
     *
     * @param id the value for t_teacher.id
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_teacher.teacherName
     *
     * @return the value of t_teacher.teacherName
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    public String getTeachername() {
        return teachername;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_teacher.teacherName
     *
     * @param teachername the value for t_teacher.teacherName
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    public void setTeachername(String teachername) {
        this.teachername = teachername;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_teacher.class_name
     *
     * @return the value of t_teacher.class_name
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    public String getClassName() {
        return className;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_teacher.class_name
     *
     * @param className the value for t_teacher.class_name
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    public void setClassName(String className) {
        this.className = className;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_teacher.address
     *
     * @return the value of t_teacher.address
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    public String getAddress() {
        return address;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_teacher.address
     *
     * @param address the value for t_teacher.address
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    public void setAddress(String address) {
        this.address = address;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_teacher.birth_date
     *
     * @return the value of t_teacher.birth_date
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    public Date getBirthDate() {
        return birthDate;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_teacher.birth_date
     *
     * @param birthDate the value for t_teacher.birth_date
     *
     * @mbggenerated Mon Jul 11 16:31:17 CST 2022
     */
    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }
}

6-2 使用MyBatis3进行逆向工程的操作:

image-20220713052724528

以Teacher为示例代码参考:

image-20220713053450855

Teacher.java:

generatorConfig.xml:

<!DOCTYPE generatorConfiguration PUBLIC
        "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!--    <context id="DB2tables" targetRuntime="MyBatis3Simple">-->
    <context id="DB2tables" targetRuntime="MyBatis3">
<!--  1.连接数据源-->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/mybatis_0325"
                        userId="root" password="draf19"/>
<!--
2.javaModelGenerator:生成pojo
targetPackage:生成的pojo放到哪一个包下
-->
        <javaModelGenerator targetPackage="com.xu1.bean" targetProject=".\src\main\java">
<!--            是否使用子包,也就是是否使用多级目录-->
            <property name="enableSubPackages" value="true"/>
<!--            去掉表属性名左右的空格-->
            <property name="trimString" value="true"/>
        </javaModelGenerator>
<!--3.sql映射文件生成器;指定xml生成的地方-->
        <sqlMapGenerator targetPackage="com.xu1.dao" targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
<!--4.dao接口生成的地方-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.xu1.dao" targetProject=".\src\main\java"/>

<!--5.
table:指定要逆向生成数据库中的哪一张表
tableName:表名
domainObjectName:映射的实体名
-->
        <table tableName="t_teacher" domainObjectName="Teacher"/>
        <table tableName="t_cat" domainObjectName="Cat"/>
        <table tableName="t_employee" domainObjectName="Employee"/>
    </context>
</generatorConfiguration>
package com.xu1.bean;

import java.util.Date;

public class Teacher {
    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_teacher.id
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    private Integer id;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_teacher.teacherName
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    private String teachername;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_teacher.class_name
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    private String className;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_teacher.address
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    private String address;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_teacher.birth_date
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    private Date birthDate;

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_teacher.id
     *
     * @return the value of t_teacher.id
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public Integer getId() {
        return id;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_teacher.id
     *
     * @param id the value for t_teacher.id
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_teacher.teacherName
     *
     * @return the value of t_teacher.teacherName
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public String getTeachername() {
        return teachername;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_teacher.teacherName
     *
     * @param teachername the value for t_teacher.teacherName
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public void setTeachername(String teachername) {
        this.teachername = teachername;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_teacher.class_name
     *
     * @return the value of t_teacher.class_name
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public String getClassName() {
        return className;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_teacher.class_name
     *
     * @param className the value for t_teacher.class_name
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public void setClassName(String className) {
        this.className = className;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_teacher.address
     *
     * @return the value of t_teacher.address
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public String getAddress() {
        return address;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_teacher.address
     *
     * @param address the value for t_teacher.address
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public void setAddress(String address) {
        this.address = address;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_teacher.birth_date
     *
     * @return the value of t_teacher.birth_date
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public Date getBirthDate() {
        return birthDate;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_teacher.birth_date
     *
     * @param birthDate the value for t_teacher.birth_date
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "id=" + id +
                ", teachername='" + teachername + '\'' +
                ", className='" + className + '\'' +
                ", address='" + address + '\'' +
                ", birthDate=" + birthDate +
                '}';
    }
}

TeacherExample.java:

package com.xu1.bean;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

public class TeacherExample {
    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    protected String orderByClause;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    protected boolean distinct;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    protected List<Criteria> oredCriteria;

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public TeacherExample() {
        oredCriteria = new ArrayList<Criteria>();
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public void setOrderByClause(String orderByClause) {
        this.orderByClause = orderByClause;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public String getOrderByClause() {
        return orderByClause;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public void setDistinct(boolean distinct) {
        this.distinct = distinct;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public boolean isDistinct() {
        return distinct;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public List<Criteria> getOredCriteria() {
        return oredCriteria;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public void or(Criteria criteria) {
        oredCriteria.add(criteria);
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public Criteria or() {
        Criteria criteria = createCriteriaInternal();
        oredCriteria.add(criteria);
        return criteria;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public Criteria createCriteria() {
        Criteria criteria = createCriteriaInternal();
        if (oredCriteria.size() == 0) {
            oredCriteria.add(criteria);
        }
        return criteria;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    protected Criteria createCriteriaInternal() {
        Criteria criteria = new Criteria();
        return criteria;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public void clear() {
        oredCriteria.clear();
        orderByClause = null;
        distinct = false;
    }

    /**
     * This class was generated by MyBatis Generator.
     * This class corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    protected abstract static class GeneratedCriteria {
        protected List<Criterion> criteria;

        protected GeneratedCriteria() {
            super();
            criteria = new ArrayList<Criterion>();
        }

        public boolean isValid() {
            return criteria.size() > 0;
        }

        public List<Criterion> getAllCriteria() {
            return criteria;
        }

        public List<Criterion> getCriteria() {
            return criteria;
        }

        protected void addCriterion(String condition) {
            if (condition == null) {
                throw new RuntimeException("Value for condition cannot be null");
            }
            criteria.add(new Criterion(condition));
        }

        protected void addCriterion(String condition, Object value, String property) {
            if (value == null) {
                throw new RuntimeException("Value for " + property + " cannot be null");
            }
            criteria.add(new Criterion(condition, value));
        }

        protected void addCriterion(String condition, Object value1, Object value2, String property) {
            if (value1 == null || value2 == null) {
                throw new RuntimeException("Between values for " + property + " cannot be null");
            }
            criteria.add(new Criterion(condition, value1, value2));
        }

        protected void addCriterionForJDBCDate(String condition, Date value, String property) {
            if (value == null) {
                throw new RuntimeException("Value for " + property + " cannot be null");
            }
            addCriterion(condition, new java.sql.Date(value.getTime()), property);
        }

        protected void addCriterionForJDBCDate(String condition, List<Date> values, String property) {
            if (values == null || values.size() == 0) {
                throw new RuntimeException("Value list for " + property + " cannot be null or empty");
            }
            List<java.sql.Date> dateList = new ArrayList<java.sql.Date>();
            Iterator<Date> iter = values.iterator();
            while (iter.hasNext()) {
                dateList.add(new java.sql.Date(iter.next().getTime()));
            }
            addCriterion(condition, dateList, property);
        }

        protected void addCriterionForJDBCDate(String condition, Date value1, Date value2, String property) {
            if (value1 == null || value2 == null) {
                throw new RuntimeException("Between values for " + property + " cannot be null");
            }
            addCriterion(condition, new java.sql.Date(value1.getTime()), new java.sql.Date(value2.getTime()), property);
        }

        public Criteria andIdIsNull() {
            addCriterion("id is null");
            return (Criteria) this;
        }

        public Criteria andIdIsNotNull() {
            addCriterion("id is not null");
            return (Criteria) this;
        }

        public Criteria andIdEqualTo(Integer value) {
            addCriterion("id =", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdNotEqualTo(Integer value) {
            addCriterion("id <>", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdGreaterThan(Integer value) {
            addCriterion("id >", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdGreaterThanOrEqualTo(Integer value) {
            addCriterion("id >=", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdLessThan(Integer value) {
            addCriterion("id <", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdLessThanOrEqualTo(Integer value) {
            addCriterion("id <=", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdIn(List<Integer> values) {
            addCriterion("id in", values, "id");
            return (Criteria) this;
        }

        public Criteria andIdNotIn(List<Integer> values) {
            addCriterion("id not in", values, "id");
            return (Criteria) this;
        }

        public Criteria andIdBetween(Integer value1, Integer value2) {
            addCriterion("id between", value1, value2, "id");
            return (Criteria) this;
        }

        public Criteria andIdNotBetween(Integer value1, Integer value2) {
            addCriterion("id not between", value1, value2, "id");
            return (Criteria) this;
        }

        public Criteria andTeachernameIsNull() {
            addCriterion("teacherName is null");
            return (Criteria) this;
        }

        public Criteria andTeachernameIsNotNull() {
            addCriterion("teacherName is not null");
            return (Criteria) this;
        }

        public Criteria andTeachernameEqualTo(String value) {
            addCriterion("teacherName =", value, "teachername");
            return (Criteria) this;
        }

        public Criteria andTeachernameNotEqualTo(String value) {
            addCriterion("teacherName <>", value, "teachername");
            return (Criteria) this;
        }

        public Criteria andTeachernameGreaterThan(String value) {
            addCriterion("teacherName >", value, "teachername");
            return (Criteria) this;
        }

        public Criteria andTeachernameGreaterThanOrEqualTo(String value) {
            addCriterion("teacherName >=", value, "teachername");
            return (Criteria) this;
        }

        public Criteria andTeachernameLessThan(String value) {
            addCriterion("teacherName <", value, "teachername");
            return (Criteria) this;
        }

        public Criteria andTeachernameLessThanOrEqualTo(String value) {
            addCriterion("teacherName <=", value, "teachername");
            return (Criteria) this;
        }

        public Criteria andTeachernameLike(String value) {
            addCriterion("teacherName like", value, "teachername");
            return (Criteria) this;
        }

        public Criteria andTeachernameNotLike(String value) {
            addCriterion("teacherName not like", value, "teachername");
            return (Criteria) this;
        }

        public Criteria andTeachernameIn(List<String> values) {
            addCriterion("teacherName in", values, "teachername");
            return (Criteria) this;
        }

        public Criteria andTeachernameNotIn(List<String> values) {
            addCriterion("teacherName not in", values, "teachername");
            return (Criteria) this;
        }

        public Criteria andTeachernameBetween(String value1, String value2) {
            addCriterion("teacherName between", value1, value2, "teachername");
            return (Criteria) this;
        }

        public Criteria andTeachernameNotBetween(String value1, String value2) {
            addCriterion("teacherName not between", value1, value2, "teachername");
            return (Criteria) this;
        }

        public Criteria andClassNameIsNull() {
            addCriterion("class_name is null");
            return (Criteria) this;
        }

        public Criteria andClassNameIsNotNull() {
            addCriterion("class_name is not null");
            return (Criteria) this;
        }

        public Criteria andClassNameEqualTo(String value) {
            addCriterion("class_name =", value, "className");
            return (Criteria) this;
        }

        public Criteria andClassNameNotEqualTo(String value) {
            addCriterion("class_name <>", value, "className");
            return (Criteria) this;
        }

        public Criteria andClassNameGreaterThan(String value) {
            addCriterion("class_name >", value, "className");
            return (Criteria) this;
        }

        public Criteria andClassNameGreaterThanOrEqualTo(String value) {
            addCriterion("class_name >=", value, "className");
            return (Criteria) this;
        }

        public Criteria andClassNameLessThan(String value) {
            addCriterion("class_name <", value, "className");
            return (Criteria) this;
        }

        public Criteria andClassNameLessThanOrEqualTo(String value) {
            addCriterion("class_name <=", value, "className");
            return (Criteria) this;
        }

        public Criteria andClassNameLike(String value) {
            addCriterion("class_name like", value, "className");
            return (Criteria) this;
        }

        public Criteria andClassNameNotLike(String value) {
            addCriterion("class_name not like", value, "className");
            return (Criteria) this;
        }

        public Criteria andClassNameIn(List<String> values) {
            addCriterion("class_name in", values, "className");
            return (Criteria) this;
        }

        public Criteria andClassNameNotIn(List<String> values) {
            addCriterion("class_name not in", values, "className");
            return (Criteria) this;
        }

        public Criteria andClassNameBetween(String value1, String value2) {
            addCriterion("class_name between", value1, value2, "className");
            return (Criteria) this;
        }

        public Criteria andClassNameNotBetween(String value1, String value2) {
            addCriterion("class_name not between", value1, value2, "className");
            return (Criteria) this;
        }

        public Criteria andAddressIsNull() {
            addCriterion("address is null");
            return (Criteria) this;
        }

        public Criteria andAddressIsNotNull() {
            addCriterion("address is not null");
            return (Criteria) this;
        }

        public Criteria andAddressEqualTo(String value) {
            addCriterion("address =", value, "address");
            return (Criteria) this;
        }

        public Criteria andAddressNotEqualTo(String value) {
            addCriterion("address <>", value, "address");
            return (Criteria) this;
        }

        public Criteria andAddressGreaterThan(String value) {
            addCriterion("address >", value, "address");
            return (Criteria) this;
        }

        public Criteria andAddressGreaterThanOrEqualTo(String value) {
            addCriterion("address >=", value, "address");
            return (Criteria) this;
        }

        public Criteria andAddressLessThan(String value) {
            addCriterion("address <", value, "address");
            return (Criteria) this;
        }

        public Criteria andAddressLessThanOrEqualTo(String value) {
            addCriterion("address <=", value, "address");
            return (Criteria) this;
        }

        public Criteria andAddressLike(String value) {
            addCriterion("address like", value, "address");
            return (Criteria) this;
        }

        public Criteria andAddressNotLike(String value) {
            addCriterion("address not like", value, "address");
            return (Criteria) this;
        }

        public Criteria andAddressIn(List<String> values) {
            addCriterion("address in", values, "address");
            return (Criteria) this;
        }

        public Criteria andAddressNotIn(List<String> values) {
            addCriterion("address not in", values, "address");
            return (Criteria) this;
        }

        public Criteria andAddressBetween(String value1, String value2) {
            addCriterion("address between", value1, value2, "address");
            return (Criteria) this;
        }

        public Criteria andAddressNotBetween(String value1, String value2) {
            addCriterion("address not between", value1, value2, "address");
            return (Criteria) this;
        }

        public Criteria andBirthDateIsNull() {
            addCriterion("birth_date is null");
            return (Criteria) this;
        }

        public Criteria andBirthDateIsNotNull() {
            addCriterion("birth_date is not null");
            return (Criteria) this;
        }

        public Criteria andBirthDateEqualTo(Date value) {
            addCriterionForJDBCDate("birth_date =", value, "birthDate");
            return (Criteria) this;
        }

        public Criteria andBirthDateNotEqualTo(Date value) {
            addCriterionForJDBCDate("birth_date <>", value, "birthDate");
            return (Criteria) this;
        }

        public Criteria andBirthDateGreaterThan(Date value) {
            addCriterionForJDBCDate("birth_date >", value, "birthDate");
            return (Criteria) this;
        }

        public Criteria andBirthDateGreaterThanOrEqualTo(Date value) {
            addCriterionForJDBCDate("birth_date >=", value, "birthDate");
            return (Criteria) this;
        }

        public Criteria andBirthDateLessThan(Date value) {
            addCriterionForJDBCDate("birth_date <", value, "birthDate");
            return (Criteria) this;
        }

        public Criteria andBirthDateLessThanOrEqualTo(Date value) {
            addCriterionForJDBCDate("birth_date <=", value, "birthDate");
            return (Criteria) this;
        }

        public Criteria andBirthDateIn(List<Date> values) {
            addCriterionForJDBCDate("birth_date in", values, "birthDate");
            return (Criteria) this;
        }

        public Criteria andBirthDateNotIn(List<Date> values) {
            addCriterionForJDBCDate("birth_date not in", values, "birthDate");
            return (Criteria) this;
        }

        public Criteria andBirthDateBetween(Date value1, Date value2) {
            addCriterionForJDBCDate("birth_date between", value1, value2, "birthDate");
            return (Criteria) this;
        }

        public Criteria andBirthDateNotBetween(Date value1, Date value2) {
            addCriterionForJDBCDate("birth_date not between", value1, value2, "birthDate");
            return (Criteria) this;
        }
    }

    /**
     * This class was generated by MyBatis Generator.
     * This class corresponds to the database table t_teacher
     *
     * @mbggenerated do_not_delete_during_merge Wed Jul 13 05:05:30 CST 2022
     */
    public static class Criteria extends GeneratedCriteria {

        protected Criteria() {
            super();
        }
    }

    /**
     * This class was generated by MyBatis Generator.
     * This class corresponds to the database table t_teacher
     *
     * @mbggenerated Wed Jul 13 05:05:30 CST 2022
     */
    public static class Criterion {
        private String condition;

        private Object value;

        private Object secondValue;

        private boolean noValue;

        private boolean singleValue;

        private boolean betweenValue;

        private boolean listValue;

        private String typeHandler;

        public String getCondition() {
            return condition;
        }

        public Object getValue() {
            return value;
        }

        public Object getSecondValue() {
            return secondValue;
        }

        public boolean isNoValue() {
            return noValue;
        }

        public boolean isSingleValue() {
            return singleValue;
        }

        public boolean isBetweenValue() {
            return betweenValue;
        }

        public boolean isListValue() {
            return listValue;
        }

        public String getTypeHandler() {
            return typeHandler;
        }

        protected Criterion(String condition) {
            super();
            this.condition = condition;
            this.typeHandler = null;
            this.noValue = true;
        }

        protected Criterion(String condition, Object value, String typeHandler) {
            super();
            this.condition = condition;
            this.value = value;
            this.typeHandler = typeHandler;
            if (value instanceof List<?>) {
                this.listValue = true;
            } else {
                this.singleValue = true;
            }
        }

        protected Criterion(String condition, Object value) {
            this(condition, value, null);
        }

        protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
            super();
            this.condition = condition;
            this.value = value;
            this.secondValue = secondValue;
            this.typeHandler = typeHandler;
            this.betweenValue = true;
        }

        protected Criterion(String condition, Object value, Object secondValue) {
            this(condition, value, secondValue, null);
        }
    }
}

TeacherMapper.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.xu1.dao.TeacherMapper" >
  <resultMap id="BaseResultMap" type="com.xu1.bean.Teacher" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="teacherName" property="teachername" jdbcType="VARCHAR" />
    <result column="class_name" property="className" jdbcType="VARCHAR" />
    <result column="address" property="address" jdbcType="VARCHAR" />
    <result column="birth_date" property="birthDate" jdbcType="DATE" />
  </resultMap>
  <sql id="Example_Where_Clause" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    <where >
      <foreach collection="oredCriteria" item="criteria" separator="or" >
        <if test="criteria.valid" >
          <trim prefix="(" suffix=")" prefixOverrides="and" >
            <foreach collection="criteria.criteria" item="criterion" >
              <choose >
                <when test="criterion.noValue" >
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue" >
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue" >
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue" >
                  and ${criterion.condition}
                  <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  <sql id="Update_By_Example_Where_Clause" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    <where >
      <foreach collection="example.oredCriteria" item="criteria" separator="or" >
        <if test="criteria.valid" >
          <trim prefix="(" suffix=")" prefixOverrides="and" >
            <foreach collection="criteria.criteria" item="criterion" >
              <choose >
                <when test="criterion.noValue" >
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue" >
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue" >
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue" >
                  and ${criterion.condition}
                  <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  <sql id="Base_Column_List" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    id, teacherName, class_name, address, birth_date
  </sql>
  <select id="selectByExample" resultMap="BaseResultMap" parameterType="com.xu1.bean.TeacherExample" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    select
    <if test="distinct" >
      distinct
    </if>
    <include refid="Base_Column_List" />
    from t_teacher
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null" >
      order by ${orderByClause}
    </if>
  </select>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    select 
    <include refid="Base_Column_List" />
    from t_teacher
    where id = #{id,jdbcType=INTEGER}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    delete from t_teacher
    where id = #{id,jdbcType=INTEGER}
  </delete>
  <delete id="deleteByExample" parameterType="com.xu1.bean.TeacherExample" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    delete from t_teacher
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
  </delete>
  <insert id="insert" parameterType="com.xu1.bean.Teacher" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    insert into t_teacher (id, teacherName, class_name, 
      address, birth_date)
    values (#{id,jdbcType=INTEGER}, #{teachername,jdbcType=VARCHAR}, #{className,jdbcType=VARCHAR}, 
      #{address,jdbcType=VARCHAR}, #{birthDate,jdbcType=DATE})
  </insert>
  <insert id="insertSelective" parameterType="com.xu1.bean.Teacher" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    insert into t_teacher
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        id,
      </if>
      <if test="teachername != null" >
        teacherName,
      </if>
      <if test="className != null" >
        class_name,
      </if>
      <if test="address != null" >
        address,
      </if>
      <if test="birthDate != null" >
        birth_date,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        #{id,jdbcType=INTEGER},
      </if>
      <if test="teachername != null" >
        #{teachername,jdbcType=VARCHAR},
      </if>
      <if test="className != null" >
        #{className,jdbcType=VARCHAR},
      </if>
      <if test="address != null" >
        #{address,jdbcType=VARCHAR},
      </if>
      <if test="birthDate != null" >
        #{birthDate,jdbcType=DATE},
      </if>
    </trim>
  </insert>
  <select id="countByExample" parameterType="com.xu1.bean.TeacherExample" resultType="java.lang.Integer" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    select count(*) from t_teacher
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
  </select>
  <update id="updateByExampleSelective" parameterType="map" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    update t_teacher
    <set >
      <if test="record.id != null" >
        id = #{record.id,jdbcType=INTEGER},
      </if>
      <if test="record.teachername != null" >
        teacherName = #{record.teachername,jdbcType=VARCHAR},
      </if>
      <if test="record.className != null" >
        class_name = #{record.className,jdbcType=VARCHAR},
      </if>
      <if test="record.address != null" >
        address = #{record.address,jdbcType=VARCHAR},
      </if>
      <if test="record.birthDate != null" >
        birth_date = #{record.birthDate,jdbcType=DATE},
      </if>
    </set>
    <if test="_parameter != null" >
      <include refid="Update_By_Example_Where_Clause" />
    </if>
  </update>
  <update id="updateByExample" parameterType="map" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    update t_teacher
    set id = #{record.id,jdbcType=INTEGER},
      teacherName = #{record.teachername,jdbcType=VARCHAR},
      class_name = #{record.className,jdbcType=VARCHAR},
      address = #{record.address,jdbcType=VARCHAR},
      birth_date = #{record.birthDate,jdbcType=DATE}
    <if test="_parameter != null" >
      <include refid="Update_By_Example_Where_Clause" />
    </if>
  </update>
  <update id="updateByPrimaryKeySelective" parameterType="com.xu1.bean.Teacher" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    update t_teacher
    <set >
      <if test="teachername != null" >
        teacherName = #{teachername,jdbcType=VARCHAR},
      </if>
      <if test="className != null" >
        class_name = #{className,jdbcType=VARCHAR},
      </if>
      <if test="address != null" >
        address = #{address,jdbcType=VARCHAR},
      </if>
      <if test="birthDate != null" >
        birth_date = #{birthDate,jdbcType=DATE},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.xu1.bean.Teacher" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Wed Jul 13 05:05:30 CST 2022.
    -->
    update t_teacher
    set teacherName = #{teachername,jdbcType=VARCHAR},
      class_name = #{className,jdbcType=VARCHAR},
      address = #{address,jdbcType=VARCHAR},
      birth_date = #{birthDate,jdbcType=DATE}
    where id = #{id,jdbcType=INTEGER}
  </update>
</mapper>

补充说明:

image-20220713064500029

测试结果:

image-20220713053831346

image-20220713054608464

image-20220713054857104

关于修改测试:

image-20220713065714403

image-20220713065846093

image-20220713070236130

第7章---pagehelper

官网链接

7-1 使用pageHelper进行环境搭建(营造需要分页的需求)

image-20220713100000732

第一步:引入插件

image-20220713100043680

第二步:造方法

image-20220713100314883

第三步:插入数据

image-20220713100538257

7-1 pageHeler插件的使用:(跟SSM一样的报500)

image-20220713105953062

image-20220713110520534

老师上课视频:

image-20220713140755336

image-20220713140810626

将当前页包装进PageInfo对象中:

image-20220713141243103

image-20220713141327930

实现上一页,下一页:

<%--
  Created by IntelliJ IDEA.
  User: 许荣
  Date: 2022/07/13
  Time: 12:11:15
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <table cellpadding="5" cellspacing="0" border="1">
        <tr>
            <td>id</td>
            <td>name</td>
            <td>course</td>
            <td>address</td>
        </tr>
        <c:forEach items="${teachers}" var="tea">
            <tr>
                <td>${tea.id}</td>
                <td>${tea.name}</td>
                <td>${tea.course}</td>
                <td>宝安区</td>
            </tr>
        </c:forEach>
        <tr>
            <td colspan="4">
                <a href="getall?pageNum=1">首页</a> <a href="getall?pageNum=${info.prePage}">上一页</a> ${info.pageNum} <a href="getall?pageNum=${info.nextPage}">下一页</a> <a href="getall?pageNum=${info.pages}">末页</a>
            </td>
        </tr>
    </table>
</body>
</html>

连续显示页:

image-20220713142218028

image-20220713142512523

image-20220713142543078

posted @ 2022-09-15 10:55  远道而重任  阅读(5)  评论(0编辑  收藏  举报