龙空技术网

MyBatis3.5.11-从入门到高阶

IT知识分享官 1470

前言:

如今姐妹们对“原生js分页”大体比较关注,同学们都需要分析一些“原生js分页”的相关知识。那么小编在网上网罗了一些有关“原生js分页””的相关知识,希望小伙伴们能喜欢,朋友们一起来了解一下吧!

一.课程介绍MyBatis概述MyBatis基础应用MyBatis高级MyBatis进阶二.MyBatis概述1、为什么需要MyBatis在我们程序中,运行时期产生的数据都是存放在内存中的,那么在内存中的数据就不是持久化的数据,因为他有一个特性那就是断电既失,那么我们如何保证我们的数据不丢失呢?答案就是存储在数据库中,将数据进行持久化,那么此时我们就需要思考一个问题,在Java程序中,如何将数据存储到数据库?在Java中操作数据库的技术有很多,其中MyBatis就是持久层框架的佼佼者,也是本次我们要学习的框架2、何为MyBatisMyBatis是一个半ORM的数据库持久化框架框架:框架指的就是一些类和接口的集合,通过这些类和接口协调可以完成一系列的程序实现,框架又叫做开发中的半成品,框架不能提供整个应用程序的所有东西,但是框架有技术实现以及辅助业务逻辑的作用持久化:就是将对象数据,保存到数据库当中,从而达到数据断电也存在的目的,叫做持久化ORM:对象关系映射(Object Relational Mapping,简称ORM):是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术半ORM(半映射):不是通过完整的映射方式,需要自己写sql语句全ORM框架(全映射):JPA、HibernateJava数据库类表属性字段/列对象记录/行3、MyBatis起源MyBatis的前身是Apache的一个开源项目一一iBatis,2010 iBatis 项目由 Apache 基金会迁移到了 Google Code ,并正式更名为 MyBatis,2013 11 月, MyBatis 迁移到 Github因为MyBatis的前身是iBatis,所以在后续的学习当中,我们可以发现引入的依赖包是iBatis的4、持久层技术对比1.JDBCSQL语句与代码写在一起,耦合度高不易维护,在实际开发中如果要修改SQL语句还需要修改代码代码冗长,开发效率低代码量多,重复代码过多开发麻烦,需要手动设置参数,如果有查询结果还需要手动转换结果性能高,Java连接数据库的唯一技术2.Hibernate&JPA全映射ORM框架,大量字段时映射部分字段比较困难自动生成的SQL语句不易优化内部反射操作多,性能较低开发简单,效率高3.MyBatisSQL语句与代码分开,职责分离轻量级框架,易上手开发效率虽然不如Hibernate,也可以接受5、MyBatis下载MyBatis下载地址:github.com/mybatis/myb…三.MyBatis基础应用1、MyBatis入门准备1.开发环境说明开发工具:IDEA2021.3.3MySql版本:8.0Maven版本:3.8.6MyBatis版本:3.5.112.学习来源学习MyBatis推荐参考MyBatis官网进行学习官方网站: mybatis.org/mybatis-3/3.MyBatis使用步骤项目工程准备导入依赖编写核心配置文件编写mapper接口编写SQL映射文件测试,调用方法,执行SQL2、MyBatis入门实现1.创建Maven工程2.导入依赖

<dependencies>    <!--mybatis依赖-->    <dependency>        <groupId>org.mybatis</groupId>        <artifactId>mybatis</artifactId>        <version>3.5.11</version>    </dependency>    <!--Junit依赖-->    <dependency>        <groupId>junit</groupId>        <artifactId>junit</artifactId>        <version>4.12</version>        <scope>test</scope>    </dependency>    <!--mysql依赖-->    <dependency>        <groupId>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>        <version>8.0.29</version>    </dependency></dependencies>复制代码
3.编写核心配置文件基本上框架都有自己的核心配置文件,MyBatis也不例外,配置文件名称推荐为mybatis-config.xml,业内基本上都是如此命名,但是不是强制要求,也可以叫其他名称MyBatis核心配置文件中的配置可以分为两类数据库连接配置MyBatis全局配置配置文件没有必要手写,可以从官网复制过来修改即可
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"        ";><!--configuration:核心配置根标签--><configuration>    <!--连接数据库环境配置根标签,可以配置多套环境,以default参数作为选择哪个环境标识-->    <environments default="development">        <!--environment:连接数据库环境配置标签,可以配置数据库连接相关参数                id是此环境的唯一标识,default属性选择哪个id那么哪个环境就生效            -->        <environment id="development">            <!--transactionManager:事务管理器,默认就使用JDBC事务管理器即可-->            <transactionManager type="JDBC"/>            <!--dataSource:数据库连接配置                    type="POOLED":表示使用传统的javax.sql.DataSource规范中的连接池                -->            <dataSource type="POOLED">                <!--驱动配置-->                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>                <!--mysql连接地址-->                <property name="url" value="jdbc:mysql://localhost:3306/itsource_mybatis"/>                <!--mysql账号-->                <property name="username" value="root"/>                <!--mysql密码-->                <property name="password" value="root"/>            </dataSource>        </environment>    </environments>    <!--引入SQL映射文件,等写了映射文件再回来修改路径-->    <mappers>        <mapper resource="org/mybatis/example/BlogMapper.xml"/>    </mappers></configuration>复制代码
4.数据库准备4.1.创建数据库表
CREATE TABLE `t_employee` (  `id` bigint NOT NULL AUTO_INCREMENT,  `name` varchar(255) DEFAULT NULL,  `age` int DEFAULT NULL,  `sex` char(1) DEFAULT NULL,  `email` varchar(255) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;复制代码
4.2.编写domain在Java中我们需要有一个类来接收从数据库中查询出来的数据,一般而言我们都使用对象的方式来进行接收,这种对象我们叫做实体类,实体类的类名与表名保持一致,字段名称需要和数据库中表字段名称保持一致
package cn.itsource.mybatis.domain;/** * @BelongsProject: mybatis_01 * @BelongsPackage: cn.itsource.mybatis.domain * @Author: shezhan * @CreateTime: 2022-11-12  20:10 * @Description: employee对应domain实体 * @Version: 1.0 */public class Employee {    private Long id;    private String name;    private Integer age;    private String sex;    private String email;    public Employee() {    }    public Employee(Long id, String name, Integer age, String sex, String email) {        this.id = id;        this.name = name;        this.age = age;        this.sex = sex;        this.email = email;    }    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Integer getAge() {        return age;    }    public void setAge(Integer age) {        this.age = age;    }    public String getSex() {        return sex;    }    public void setSex(String sex) {        this.sex = sex;    }    public String getEmail() {        return email;    }    public void setEmail(String email) {        this.email = email;    }    @Override    public String toString() {        return "Employee{" +                "id=" + id +                ", name='" + name + '\'' +                ", age=" + age +                ", sex='" + sex + '\'' +                ", email='" + email + '\'' +                '}';    }}复制代码
5.编写mapper接口5.1.概述通过官网我们可以发现,MyBatis提供了mapper接口映射SQL文件的方式,让我们可以调用接口方法时,调用SQL映射语句MyBatis底层会使用动态代理的方式,帮助我们创建mapper接口的对应实现类,所以当我们把mapper接口字节码交给MyBatis时,返回的就是他帮我们创建的实现类,那么我们直接可以调用实现类中的方法,MyBatis会根据mapper接口的全类名+方法名称定位到SQL映射文件中的namespace+id,从而实现SQL语句的调用5.2.实现mapper接口命名规则:实体类名称+Mapper
package cn.itsource.mybatis.mapper;import cn.itsource.mybatis.domain.Employee;import java.util.List;/** * @BelongsProject: mybatis_01 * @BelongsPackage: cn.itsource.mybatis.mapper * @Author: shezhan * @CreateTime: 2022-11-12  20:34 * @Description: employee表对应mapper接口 * @Version: 1.0 */public interface EmployeeMapper {    /*     * @Description: 查询所有     * @Author: shezhan     * @Date: 2022/11/12 20:30     * @return: java.util.List<cn.itsource.mybatis.domain.Employee>     **/    List<Employee> selectAll();}复制代码
6.编写Sql映射文件6.1.概述映射文件:MyBatis有自己专门写SQL语句的文件,也就是我们的映射文件,也称之为mapper文件映射文件的名称一般叫做 XxxMapper.xml (Xxx代表的是实体类名称)例如实体类有: cn.itsource.mybatis.domain.Employee映射文件名为: resources/mappers/EmployeeMapper.xml注意namespace的名称通常是接口的完全限定名除了MyBatis支持的类型,其它的类型都通通使用全限定我们可以从官网找到映射文件示例6.2.实现
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        ";><!--    namespace:命名空间,用来标识此SQL映射文件对应是那个mapper接口        参数值是mapper接口的全类名--><mapper namespace="cn.itsource.mybatis.mapper.EmployeeMapper">    <!--        select:查询SQL标签,在SQL映射文件中有mysql增删改查的对应标签,在标签中就写我们需要执行的sql语句            id:此sql语句的唯一标识,在同一个命名空间下id不能重复                id值就是此sql语句对应的mapper接口方法名称            resultType:自动映射,标识我们要将查询结果封装到那个实体类对象中                参数值就是要封装的实体类的全类名,必须是数据库字段与实体类字段名一直时才能自动映射            resultMap:自定义映射,当实体类字段名称与查询结果字段名称不一致时,我们需要使用自定义映射            注意:查询时必须设置resultType或者resultMap    -->    <select id="selectAll" resultType="cn.itsource.mybatis.domain.Employee">        select * from t_employee    </select></mapper>复制代码
注意:之前我们在核心配置文件中的SQL映射文件路径还未指定,此时我们编辑好了映射文件需要回去进行指定7.测试
package cn.itsource.mybatis.test;import cn.itsource.mybatis.domain.Employee;import cn.itsource.mybatis.mapper.EmployeeMapper;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.InputStream;import java.util.List;/** * @BelongsProject: mybatis_01 * @BelongsPackage: cn.itsource.mybatis.test * @Author: shezhan * @CreateTime: 2022-11-12  20:50 * @Description: mybatis测试 * @Version: 1.0 */public class MyBatisTest {    @Test    public void testSelectAll(){        try {            // 1.通过MyBatis提供的读取核心配置文件工具类,读取核心配置文件            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");            // 2.根据核心配置文件,得到连接构建工厂            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);            // 3.从连接构建工厂中获取数据库连接            SqlSession sqlSession = sqlSessionFactory.openSession();            // 4.指定需要得到的mapper接口字节码,得到实现类            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);            // 5.调用查询所有方法,相当于调用映射文件sql语句,执行查询            // 原理是根据接口的全类名+调用方法名,去匹配SQL映射文件的namespace+id,找到就执行SQL语句            List<Employee> employees = employeeMapper.selectAll();            employees.forEach(System.out::println);        }catch (Exception e){            e.printStackTrace();        }    }}复制代码
3、MyBatis基础CRUD1.查询第一步:编写查询接口方法
package cn.itsource.mybatis.mapper;import cn.itsource.mybatis.domain.Employee;import java.util.List;/** * @BelongsProject: mybatis_01 * @BelongsPackage: cn.itsource.mybatis.mapper * @Author: shezhan * @CreateTime: 2022-11-12  20:34 * @Description: employee表对应mapper接口 * @Version: 1.0 */public interface EmployeeMapper {        /*     * @Description: 根据主键值查询数据     * @Author: shezhan     * @Date: 2022/11/19 15:17     * @param id: 条件数据     * @return: cn.itsource.mybatis.domain.Employee     **/    Employee selectOne(Long id);}复制代码
第二步:编写映射文件XML
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        ";><!--    namespace:命名空间,用来标识此SQL映射文件对应是那个mapper接口        参数值是mapper接口的全类名--><mapper namespace="cn.itsource.mybatis.mapper.EmployeeMapper">    <!--根据主键Id查询数据        1、获取mapper接口传递过来的值有两种方式,此处我们先有个概念,知道他做什么的,后续我们专门会进行讲解           1.#{}:可以有效防止SQL注入问题           2.${}:也可以获取mapper接口,但是有SQL注入风险        2、parameterType:标识传递进来的参数的类型,可以不写,mybatis会自动识别,具体对照表参照官网,此处我们传递的是Long类型的Id,那么对应mybatis中的类型就是小long    -->    <select id="selectOne" parameterType="long" resultType="cn.itsource.mybatis.domain.Employee">        select * from t_employee where id = #{id}    </select></mapper>复制代码
第三步:测试
    /*     * @Description: 测试根据Id查询     * @Author: shezhan     * @Date: 2022/11/19 15:24     * @return: void     **/    @Test    public void testSelectOne(){        try {            // 1.通过MyBatis提供的读取核心配置文件工具类,读取核心配置文件            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");            // 2.根据核心配置文件,得到连接构建工厂            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);            // 3.从连接构建工厂中获取数据库连接            SqlSession sqlSession = sqlSessionFactory.openSession();            // 4.指定需要得到的mapper接口字节码,得到实现类            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);            // 5.调用根据Id查询员工方法            Employee employee = employeeMapper.selectOne(1L);            System.out.println(employee);        }catch (Exception e){            e.printStackTrace();        }    }复制代码
2.新增第一步:编写新增接口方法
package cn.itsource.mybatis.mapper;import cn.itsource.mybatis.domain.Employee;import java.util.List;/** * @BelongsProject: mybatis_01 * @BelongsPackage: cn.itsource.mybatis.mapper * @Author: shezhan * @CreateTime: 2022-11-12  20:34 * @Description: employee表对应mapper接口 * @Version: 1.0 */public interface EmployeeMapper {            /*     * @Description: 新增员工     * @Author: shezhan     * @Date: 2022/11/19 15:52     * @param employee: 员工对象     * @return: int 代表受影响的行数,真实开发中返回值类型我们一般设置为void     **/    int insert(Employee employee);}复制代码
第二步:编写映射文件XML
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        ";><!--    namespace:命名空间,用来标识此SQL映射文件对应是那个mapper接口        参数值是mapper接口的全类名--><mapper namespace="cn.itsource.mybatis.mapper.EmployeeMapper">        <!--新增员工数据        1.parameterType:代表传递进来的参数类型,如果是我们的实体类对象,那么需要写实体类的全类名        	新增不需要写返回值类型,mybatis默认增删改都是返回受影响的行数,也就是一个int类型的数字        2.在映射文件中,如果我们想要获取对象中的字段值,那么我们可以有两种方式            #{}和${},直接在{}中写上传递进来的对象的字段名称即可调用对象字段的getter方法进行参数获取            此处我们使用#{},原因我们后续讲解    -->    <insert id="insert" parameterType="cn.itsource.mybatis.domain.Employee">        insert into t_employee(name, age, sex, email) values (#{name}, #{age}, #{sex}, #{email})    </insert></mapper>复制代码
第三步:测试
    /*     * @Description: 测试新增     * @Author: shezhan     * @Date: 2022/11/19 15:24     * @return: void     **/    @Test    public void testInsert(){        try {            // 1.通过MyBatis提供的读取核心配置文件工具类,读取核心配置文件            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");            // 2.根据核心配置文件,得到连接构建工厂            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);            // 3.从连接构建工厂中获取数据库连接            SqlSession sqlSession = sqlSessionFactory.openSession();            // 4.指定需要得到的mapper接口字节码,得到实现类            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);            // 5.创建需要新增的员工对象,并设置数据            Employee employee = new Employee();            employee.setName("赵六");            employee.setAge(22);            employee.setSex("男");            employee.setEmail("ww@itsource.cn");            // 6.执行新增            int insert = employeeMapper.insert(employee);            // 7.默认是需要我们手动提交事务的,也可以在获取连接时sqlSessionFactory.openSession(true);代表自动提交事务            sqlSession.commit();            System.out.println(insert);        }catch (Exception e){            e.printStackTrace();        }    }复制代码
3.修改第一步:编写修改接口方法
package cn.itsource.mybatis.mapper;import cn.itsource.mybatis.domain.Employee;import java.util.List;/** * @BelongsProject: mybatis_01 * @BelongsPackage: cn.itsource.mybatis.mapper * @Author: shezhan * @CreateTime: 2022-11-12  20:34 * @Description: employee表对应mapper接口 * @Version: 1.0 */public interface EmployeeMapper {    /*     * @Description: 根据Id修改员工信息     * @Author: shezhan     * @Date: 2022/11/19 16:02     * @param employee: 要修改的员工信息对象     * @return: void,不接收受影响的行数     **/    void update(Employee employee);}复制代码
第二步:编写映射文件XML
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        ";><!--    namespace:命名空间,用来标识此SQL映射文件对应是那个mapper接口        参数值是mapper接口的全类名--><mapper namespace="cn.itsource.mybatis.mapper.EmployeeMapper">    <!--修改员工数据-->    <update id="update" parameterType="cn.itsource.mybatis.domain.Employee">        update t_employee set name = #{name} where id = #{id}    </update>    </mapper>复制代码
第三步:测试
    /*     * @Description: 测试修改     * @Author: shezhan     * @Date: 2022/11/19 16:05     * @return: void     **/    @Test    public void testUpdate(){        try {            // 1.通过MyBatis提供的读取核心配置文件工具类,读取核心配置文件            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");            // 2.根据核心配置文件,得到连接构建工厂            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);            // 3.从连接构建工厂中获取数据库连接,我们打开自动提交事务,就无需手动提交了            SqlSession sqlSession = sqlSessionFactory.openSession(true);            // 4.指定需要得到的mapper接口字节码,得到实现类            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);            // 5.创建需要新增的员工对象,并设置数据            Employee employee = new Employee();            employee.setName("司马懿");            employee.setId(4L);            // 6.执行修改            employeeMapper.update(employee);        }catch (Exception e){            e.printStackTrace();        }    }复制代码
4.删除第一步:编写新增接口方法
package cn.itsource.mybatis.mapper;import cn.itsource.mybatis.domain.Employee;import java.util.List;/** * @BelongsProject: mybatis_01 * @BelongsPackage: cn.itsource.mybatis.mapper * @Author: shezhan * @CreateTime: 2022-11-12  20:34 * @Description: employee表对应mapper接口 * @Version: 1.0 */public interface EmployeeMapper {    /*     * @Description: 查询所有     * @Author: shezhan     * @Date: 2022/11/12 20:30     * @return: java.util.List<cn.itsource.mybatis.domain.Employee>     **/    List<Employee> selectAll();    /*     * @Description: 根据主键值查询数据     * @Author: shezhan     * @Date: 2022/11/19 15:17     * @param id: 条件数据     * @return: cn.itsource.mybatis.domain.Employee     **/    Employee selectOne(Long id);    /*     * @Description: 新增员工     * @Author: shezhan     * @Date: 2022/11/19 15:52     * @param employee: 员工对象     * @return: int 代表受影响的行数,真实开发中返回值类型我们一般设置为void     **/    int insert(Employee employee);    /*     * @Description: 根据Id修改员工信息     * @Author: shezhan     * @Date: 2022/11/19 16:02     * @param employee: 要修改的员工信息对象     * @return: void,受影响的行数     **/    void update(Employee employee);    /*     * @Description: 根据Id删除员工信息     * @Author: shezhan     * @Date: 2022/11/19 16:11     * @param id: 员工对应主键Id数据     * @return: void     **/    void delete(Long id);}复制代码
第二步:编写映射文件XML
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        ";><!--    namespace:命名空间,用来标识此SQL映射文件对应是那个mapper接口        参数值是mapper接口的全类名--><mapper namespace="cn.itsource.mybatis.mapper.EmployeeMapper">    <!--根据Id删除员工信息-->    <delete id="delete" parameterType="long">        delete from t_employee where id = #{id}    </delete>    </mapper>复制代码
第三步:测试
    /*     * @Description: 测试根据Id删除员工信息     * @Author: shezhan     * @Date: 2022/11/19 16:13     * @return: void     **/    @Test    public void testDelete(){        try {            // 1.通过MyBatis提供的读取核心配置文件工具类,读取核心配置文件            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");            // 2.根据核心配置文件,得到连接构建工厂            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);            // 3.从连接构建工厂中获取数据库连接,我们打开自动提交事务,就无需手动提交了            SqlSession sqlSession = sqlSessionFactory.openSession(true);            // 4.指定需要得到的mapper接口字节码,得到实现类            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);            // 6.执行删除            employeeMapper.delete(4L);        }catch (Exception e){            e.printStackTrace();        }    }复制代码
4、MyBatis工具类封装1.概述前面我们已经实现了使用MyBatis进行增删改查我们的数据库数据了,那么各位也可以发现,在五个方法中,大部分代码都是重复的以查询所有为例2.封装工具类
package cn.itsource.mybatis.utils;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import java.io.IOException;import java.io.InputStream;/** * @BelongsProject: mybatis_01 * @BelongsPackage: cn.itsource.mybatis.utils * @Author: shezhan * @CreateTime: 2022-11-19  16:27 * @Description: MyBatis工具类 * @Version: 1.0 */public class MyBatisUtil {    // 1.定义一个私有的全局连接工厂对象    private static SqlSessionFactory sqlSessionFactory = null;    // 2.在类加载时加载一次连接工厂对象    static {        try {            // 1.获取MyBatis核心配置文件            InputStream resource = Resources.getResourceAsStream("mybatis-config.xml");            // 2.根据核心配置文件创建连接工厂对象            sqlSessionFactory = new SqlSessionFactoryBuilder().build(resource);        } catch (IOException e) {            e.printStackTrace();        }    }    // 3.提供获取连接的方法    public static SqlSession getSqlSession(){        if (sqlSessionFactory != null){            return sqlSessionFactory.openSession(true);        }        return null;    }}复制代码
3.工具类测试
    /*     * @Description: MyBatis工具类测试     * @Author: shezhan     * @Date: 2022/11/19 16:32     * @return: void     **/    @Test    public void testMyBatisUtil(){        // 1.获取连接        SqlSession sqlSession = MyBatisUtil.getSqlSession();        // 2.得到mapper接口实现类        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);        // 3.执行查询所有        List<Employee> employees = mapper.selectAll();        // 4.打印输出        employees.forEach(System.out::println);    }复制代码
5、MyBatis使用细节1.新增返回自增Id在真实开发当中,某些情况下我们需要知道当前新增数据的主键Id是多少,那么此时我们可以通过配置开启主键返回得到我们的自增长主键Id第一步:映射文件中开启主键返回
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        ";><!--    namespace:命名空间,用来标识此SQL映射文件对应是那个mapper接口        参数值是mapper接口的全类名--><mapper namespace="cn.itsource.mybatis.mapper.EmployeeMapper">    <!--新增员工数据        1.parameterType:代表传递进来的参数类型,如果是我们的实体类对象,那么需要写实体类的全类名        新增不需要写返回值类型,mybatis默认增删改都是返回受影响的行数,也就是一个int类型的数字        2.在映射文件中,如果我们想要获取对象中的字段值,那么我们可以有两种方式            #{}和${},直接在{}中写上传递进来的对象的字段名称即可调用对象字段的getter方法进行参数获取            此处我们使用#{},原因我们后续讲解        3.自增主键返回属性            useGeneratedKeys:开启自增主键返回                true:开启返回自增主键                false:关闭返回自增主键,默认值            keyProperty:此属性表示将Id返回到传递进来的对象的那个字段,一般我们都填写id字段            keyColumn:此属性表示数据库中的那一列是主键,如果主键列在数据库表中是第一列,那么默认可以不写,                通常情况下我们在设计表时主键都是第一列,所以此属性可以不写    -->    <insert id="insert" parameterType="cn.itsource.mybatis.domain.Employee"        useGeneratedKeys="true" keyProperty="id" keyColumn="id">        insert into t_employee(name, age, sex, email) values (#{name}, #{age}, #{sex}, #{email})    </insert>    </mapper>复制代码
第二步:测试获取自增主键
    /*     * @Description: 测试新增获取自增长Id     * @Author: shezhan     * @Date: 2022/11/19 17:15     * @return: void     **/    @Test    public void testInsertGetId(){        try {            // 1.获取连接            SqlSession sqlSession = MyBatisUtil.getSqlSession();            // 2.得到mapper接口实现类            EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);            // 4.指定需要得到的mapper接口字节码,得到实现类            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);            // 5.创建需要新增的员工对象,并设置数据            Employee employee = new Employee();			employee.setName("仁宗帝");            employee.setAge(34);            employee.setSex("男");            employee.setEmail("rzd@itsource.cn");            // 6.执行新增            employeeMapper.insert(employee);            // 7.获取返回的自增Id,因为我们的keyProperty属性设置的是id字段,所以主键会返回到我们传递进去对象的id字段中            System.out.println(employee.getId());        }catch (Exception e){            e.printStackTrace();        }    }复制代码
2.MyBatis运行日志通过前面对于MyBatis的运用,我们发现一个问题,我们并不知道我们的SQL语句在运行时期是什么样子,因为我们都是通过占位符进行SQL的编写,这样不便于我们在真实开发当中进行排错,所以我们需要开启log4j的支持日志级别:ALL < TRACE< DEBUG < INFO < WARN < ERROR < FATAL < OFFOFF | 关闭:最高级别,不打印日志FATAL | 致命:指明非常严重的可能会导致应用终止执行错误事件ERROR | 错误:指明错误事件,但应用可能还能继续运行WARN | 警告:指明可能潜在的危险状况INFO | 信息:指明描述信息,从粗粒度上描述了应用运行过程DEBUG | 调试:指明细致的事件信息,对调试应用最有用TRACE | 跟踪:指明程序运行轨迹,比DEBUG级别的粒度更细ALL | 所有:所有日志级别,包括定制级别第一步:导入依赖
<!--log4j日志,用于打印mybatis运行日志--><dependency>    <groupId>log4j</groupId>    <artifactId>log4j</artifactId>    <version>1.2.17</version></dependency>复制代码
第二步:复制配置文件到src->main->resource下,日志文件名称为log4j.properties,名称是固定的
#日志器logger #輸出器appender #布局器layout#1.控制台输出#指定日志器的输出级别和日志器的名称#log4j.rootLogger=info,myconsole#指定输出器#log4j.appender.myconsole=org.apache.log4j.ConsoleAppender#指定布局器#log4j.appender.myconsole.layout=org.apache.log4j.SimpleLayout#2.文件输出.txt#指定日志器的输出级别和日志器的名称#log4j.rootLogger=error,myfile#指定输出器#log4j.appender.myfile=org.apache.log4j.FileAppender#log4j.appender.myfile.File=E:\\log4j.txt#指定布局器(普通布局表示文本输出)#log4j.appender.myfile.layout=org.apache.log4j.SimpleLayout#3.文件输出.html#指定日志器的输出级别和日志器的名称#log4j.rootLogger=error,myhtml#指定输出器#log4j.appender.myhtml=org.apache.log4j.FileAppender#log4j.appender.myhtml.File=D:\\log4j.html#指定布局器(网页布局)#log4j.appender.myhtml.layout=org.apache.log4j.HTMLLayout#4.控制台输出+文件输出.txt#指定日志器的输出级别和日志器的名称#log4j.rootLogger=error,con,file#指定输出器#log4j.appender.con=org.apache.log4j.ConsoleAppender#log4j.appender.file=org.apache.log4j.FileAppender#log4j.appender.file.File=D\:\\log4j.txt#指定布局器(网页布局)#log4j.appender.con.layout=org.apache.log4j.SimpleLayout#log4j.appender.file.layout=org.apache.log4j.SimpleLayout#5.控制台输出+自定义布局#指定日志器的输出级别和日志器的名称log4j.rootLogger=DEBUG,custom#指定输出器,输出到控制台log4j.appender.custom=org.apache.log4j.ConsoleAppender#指定布局为自定义布局,可以灵活的配置布局log4j.appender.custom.layout=org.apache.log4j.PatternLayout#指定在自定义布局的格式,%d -- 表示当前系统时间,%t -- 执行该业务的线程名称,%p -- 日记器的级别,-5 -- 5表示输出字符的个数,符号表示右对齐#%c -- 表示指定业务所在的类的完全限定名(包名.类名),%m -- 输出额外信息,%n -- 表示换行log4j.appender.custom.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n#设置要输出日志的包package(可以是自定义的包也可以是api的包)输出级别log4j.logger.org.apache.ibatis=infolog4j.logger.cn.itsource=debug复制代码
第三步:执行新增查看控制台6、MyBatis核心配置文件详解1.environmentsenvironments:配置多个连接数据库的环境,在MyBatis核心配置文件中,我们可以配置多套连接数据库的环境,并且以default属性来选择默认的环境default:此属性用于选择默认使用哪套环境,对应的值就是environment标签的id值environment:配置一个连接数据库的环境id:标识此环境的唯一标识,不能重复,用于让外部environments的default属性进行选择transactionManager:设置事务的管理方式type:设计事务管理的类型,有两个值JDBC:表示当前环境中,执行SQL时使用JDBC原生的事务管理方式,也就是需要手动提交事务或者手动回滚事务MANAGED:表示当前环境中事务被管理,比如以后我们使用spring框架,那么事务可以被spring框架管理dataSource:配置数据源,也就是设置连接数据库的四大属性type:设置连接数据源的类型POOLED:表示使用数据库连接池来缓存连接,那么下次需要获取连接时从缓存中获取即可UNPOOLED:表示不使用数据库连接池JNDI:是SUN公司推出的一套规范,可以在服务器中注册数据源property:设置连接数据库的四大属性2.properties在MyBatis核心配置文件中,数据源的四大连接属性官方推荐是写在配置文件中,通过properties属性引入到核心配置文件中再进行读取,我们之前是直接写死的,接下来我们按照官方的方式进行配置第一步:在resources下创建jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/itsource_mybatisjdbc.username=rootjdbc.password=root复制代码
第二步:改造核心配置文件
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"        ";><!--configuration:核心配置根标签--><configuration>    <!--引入jdbc.properties,动态读取数据源四大属性值-->    <properties resource="jdbc.properties"></properties>    <!--连接数据库环境配置根标签,可以配置多套环境,以default参数作为选择哪个环境标识-->    <environments default="development">        <!--environment:连接数据库环境配置标签,可以配置数据库连接相关参数                id是此环境的唯一标识,default属性选择哪个id那么哪个环境就生效            -->        <environment id="development">            <!--transactionManager:事务管理器,默认就使用JDBC事务管理器即可-->            <transactionManager type="JDBC"/>            <!--dataSource:数据库连接配置                    type="POOLED":表示使用传统的javax.sql.DataSource规范中的连接池                -->            <dataSource type="POOLED">                <!--驱动配置-->                <property name="driver" value="${jdbc.driver}"/>                <!--mysql连接地址-->                <property name="url" value="${jdbc.url}"/>                <!--mysql账号-->                <property name="username" value="${jdbc.username}"/>                <!--mysql密码-->                <property name="password" value="${jdbc.password}"/>            </dataSource>        </environment>    </environments>    <!--引入SQL映射文件,等写了映射文件再回来修改路径-->    <mappers>        <mapper resource="mappers/EmployeeMapper.xml"/>    </mappers></configuration>复制代码
3.typeAliases在MyBatis中,有一些内置的别名,我们在映射文件中使用时就可以根据已经内置好的别名进行使用,除此之外我们也可以将我们的实体类进行别名映射,这样以后在映射文件中写返回值类型时,我们就无需再写类的全类名了

别名

映射的类型

_byte

byte

_long

long

_short

short

_int

int

_integer

int

_double

double

_float

float

_boolean

boolean

string

String

byte

Byte

long

Long

short

Short

int

Integer

integer

Integer

double

Double

float

Float

boolean

Boolean

date

Date

decimal

BigDecimal

bigdecimal

BigDecimal

object

Object

map

Map

hashmap

HashMap

list

List

arraylist

ArrayList

collection

Collection

iterator

Iterator

第一种:单个类取别名

<!--类型别名映射标签,注意按照MyBatis核心配置文件编写顺序,此标签需要在properties下--><typeAliases>    <!--typeAlias:给单个实体类对象映射别名                默认别名:如果不写alias属性,那么别名的名称就是类名或者是类名首字母小写                alias:设置类型别名名称,如果设置了,那么以设置的为准,一般我们不进行设置,即便设置也是类名        -->    <typeAlias type="cn.itsource.mybatis.domain.Employee" alias="Employee"></typeAlias></typeAliases>复制代码
第二种:给包下所有类取别名,推荐使用
<!--类型别名映射标签,注意按照MyBatis核心配置文件编写顺序,此标签需要在properties下--><typeAliases>    <!--package:指定要取别名的包路径,那么这个包下面所有类都会取别名,别名默认就是类名或者类型小写-->    <package name="cn.itsource.mybatis.domain"/></typeAliases>复制代码
别名使用
<!-- resultType:取了别名以后返回值类型直接写别名,无需再写全类名 --><select id="selectAll" resultType="Employee">    select * from t_employee</select>复制代码
4.mappers此标签是用来引入我们的映射文件的,之前我们是使用的mapper标签对映射文件进行单个引入,这种方式在真实开发当中不常用,因为我们以后的映射文件肯定是很多的,一个数据库表对应一个mapper接口,一个mapper接口对应一个映射文件,所以我们会采用对映射文件以包的方式进行引入映射文件包创建规范在resources下必须以 / 的方式进行创建,这样才能创建出多级包路径包的路径必须跟mapper接口路径保持一致7、MyBatis获取参数值的两种方式1.概述如果有学过JDBC的同学应该知道,在JDBC中我们可以使用两种方式进行SQL语句参数的赋值,一种是SQL语句拼接参数,一种是使用占位符,那么其实在MyBatis中${}和#{}就是对应这两种方式之前在映射文件中,我们讲过可以通过两种方式获取到mapper接口的参数值${}:本质上是字符串拼接,如果参数类型是字符串或者是时间类型那么需要手动添加单引号#{}:本质上是占位符赋值,也被称为预编译,如果参数类型是字符串或者是时间类型那么会自动加单引号

String name = "'123' OR 1=1";

select * from t_employee where name = '123' OR 1=1

2.区别#{}#{} 解析为一个预编译语句的参数标记符,一个 #{} 被解析为一个参数占位符SQL语句:"SELECT * FROM t_employee where name = #{name}"预编译语句为:"SELECT * FROM t_employee where name = ?"#{} 解析之后会将String类型或者时间类型的数据自动加上引号,其他数据类型不会#{} 很大程度上可以防止SQL注入${}${}仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换SQL语句:"SELECT * FROM t_employee where name = '"+name+"'"${} 解析之后是什么就是什么,他不会当做字符串处理,所以如果是字符串或者时间类型需要我们手动加上单引号${} 主要用于SQL拼接的时候,有很大的SQL注入隐患在某些特殊场合下只能用${},不能用#{}例如:在使用排序时ORDER BY ${id},如果使用#{id},则会被解析成ORDER BY “id”,这显然是一种错误的写法SQL注入如果使用拼接的方式,那么我们就是在条件后面拼接参数值,那么如果是下面这种情况,就会出现SQL注入问题了,不管我是否知道具体的条件,我都可以通过拼接OR 1= 1得到数据,这就是SQL注入name值为:123 OR 1 = 1SQL语句为:"SELECT * FROM t_employee where name = '"+username+"'"最终运行时:"SELECT * FROM t_employee where name = 123 OR 1 = 1"3.实战运用3.1.参数为单个字面量#{}方式获取参数${}获取参数3.2.参数为多个字面量定义接口#{}方式获取参数${}方式获取参数3.3.@Param注解方式当参数为多个时,通常我们不会用MyBatis给我们准备的参数名称,而是自己使用@Param注解定义参数别名,当然一个参数时也可以使用别名的方式定义参数名称#{}方式获取参数${}方式获取参数3.4.参数为Map集合当参数为Map时,我们在xml中根据map的key获取参数值即可定义接口#{}方式获取参数${}方式获取参数3.5.参数为实体类对象定义接口#{}方式获取参数${}方式获取参数3.6.参数为List集合或者数组此处我们不做演示,在批量新增和删除时我们再进行研究四.MyBatis高级1、MyBatis多种结果封装在MyBatis中,对于一条查询结果和多条查询结果我们需要使用不同的处理方式搭建新工程1.一条结果封装1.1.对象封装结果创建接口编写映射XML测试1.2.List封装结果编写接口编写映射XML测试1.3.Map封装结果编写接口编写映射XML测试1.4.使用@MapKey注解我们可以将数据作为Map的Key、Value,那么也可以将数据作为Value我们指定一个字段作为Key编写接口编写映射XML测试2.多条结果封装2.1.List封装结果编写接口编写映射XML测试2.2.Map封装结果编写接口编写映射XML测试2、MyBatis模糊查询模糊查询:通过一个字符或者多个字符去匹配某个字段值,叫做模糊查询1.${}实现模糊查询编写接口编写映射XML测试2.concat函数实现模糊查询编写映射XML测试4.SQL拼接实现模糊查询编写映射XML测试3、MyBatis原生分页查询1.概述在MySql数据库中,limit是分页关键字,后面需要填写两个分页参数以逗号分隔第一个参数:分页数据起始位置第二个参数:分页每页数据展示条数2.实战定义分页条件对象

package cn.itsource.mybatis.query;import lombok.Data;/** * @BelongsProject: mybatis_02 * @BelongsPackage: cn.itsource.mybatis.query * @Author: shezhan * @CreateTime: 2022-12-14  15:38 * @Description: 数据查询公共条件类 * @Version: 1.0 */@Datapublic class BaseQuery {    // 分页页码    private Integer currentPage;    // 分页每页展示条数    private Integer pageSize;    /*     * @Description: 前端传递的参数不是数据起始位置,而是页码,所以我们需要根据页码进行计算     * @Author: shezhan     * @Date: 2022/12/14 15:40     * @return: java.lang.Integer     **/    public Integer getStart(){        // 分页起始位置计算公式:(页码-1) * 每页展示条数        return (this.currentPage - 1) * this.pageSize;    }}复制代码
编写接口编写映射XML测试4、MyBatis动态表名1.概述在以后的实际开发中,一张表的数据过多时,会影响操作性能,此时就会使用水平切分,将一张表的数据,切分到多张表共同存储一张表的数据当数据在多张表时,我们查询数据表名就不固定了,那么就需要将表名通过参数的形式传递到SQL中,此时我们可以使用${}的方式获取参数作为表名注意此时不能使用#{},因为#{}会帮助我们添加单引号,表名是不能添加单引号的2.实战编写接口编写映射XML测试5、MyBatis动态SQLMybatis 动态Sql可以让我们在 Xml 映射文件内,以标签的形式编写动态Sql,完成逻辑判断和动态拼接Sql 的功能1.if标签1.1.概述if标签可以解决SQL语句条件不确定是否执行的问题,通过test属性,我们可以判断某个参数是否存在,如果表达式为true,那么标签中的语句会被执行,否则不执行注意如果不需要过滤空字符串那么只需要判断null值如果参数需要判定是否为空字符串,那么需要判断null和空字符串并且需要去空白1.2.实战编写条件对象改造查询接口,使用条件类编写映射XML测试2.where标签2.1.概述where标签可以解决不确定if标签中表达式是否成立所引发的问题,它有两个功能如果where标签中的条件成立,那么会自动加上where关键字会自动去掉标签中条件语句前面多余的and或者是or关键字2.2.实战编写映射XML测试3.trim标签3.1.概述标签的功能是可以实现代替其他标签的功能,但同时又比其他标签更加灵活,他有四个属性prefix:指定要动态添加的前缀suffix属性:指定要动态添加的后缀prefixOverrides:去除sql语句前面的关键字或者字符,假设该属性指定为"AND",当sql语句的开头为"AND",trim标签将会去除该"AND",使用“|”分隔有可能的多个值suffixOverrides属性:指定要动态去掉的后缀,使用“|”分隔有可能的多个值3.2.实战编写映射XML测试4.foreach标签4.1.概述foreach标签的使用场景是对集合进行遍历,并可以自定义的设置foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量,它也允许你指定开头与结尾的字符串以及各个元素之间的分隔符,这个元素也不会错误地添加多余的分隔符属性详解collection: 表示要遍历的对象,如果要遍历的参数使用@Param注解取名了就使用该名字,如果没有取名List,或者collectionitem: 表示遍历出来的元素,我们到时候要拼接SQL语句就得使用这个元素,如果遍历出来的元素是POJO对象, 那么我们就通过 #{遍历出来的元素.POJO的属性} 获取数据,如果遍历出来的元素是简单类型的数据,那么我们就使用 #{遍历出来的元素} 获取这个简单类型数据separator: 遍历出来的元素之间的分隔符open: 在遍历出来的第一个元素之前添加前缀close: 在遍历出来的最后一个元素之后添加后缀4.2.实战实战我们就放在批量删除和批量新增时进行使用5.choose&when&otherwise标签5.1.概述choose标签实现多路选择,当choose下的when标签条件满足时,就将when中的sql拼进外面的sql,反之若不满足,则将下面的otherwise标签中的sql拼进总sql这三个关键字是一套组合标签,类似于Java中的 if(){}else if(){}else{} 的功能choose是父标签,when和otherwise标签需要写在此标签下when相当于 if(){}else if(){}otherwise相当于最后的 else{}5.2.实战编写映射XML测试6.特殊符号处理6.1.概述在sql语句中,我们会使用到一些比较符号,在xml中需要特殊处理注意:在xml中特殊字符不处理会报错在xml的转义字符符号:<、<=、>、>=、&、' 、"gt :大于lt:小于get:大于等于let:小于等于或者可以用CDATA代码段大于等于 <![CDATA[ >= ]]>小于等于 <![CDATA[ <= ]]>6.2.实战编写映射XML测试7.sql标签7.1.概述在java代码中,经常使用到的代码,我们会将他抽取为一个方法,在需要使用的地方引入,那么在SQL中也可以将重复的SQL代码块进行抽取,然后引入使用7.2.实战编写映射XML测试8.set标签8.1.概述set标签是在我们进行update操作时使用,可以解决修改条件不确定时引发的问题,通常和if标签搭配使用,它有两个功能如果set标签中的条件成立,那么会自动加上set关键字会自动去掉标签中条件语句中多余的逗号8.2.实战编写接口编写映射XML测试6、Mybatis批量新增1.sql中批量添加写法
INSERT INTO t_employee (name,age,sex,email) VALUES ("小明",18,'男',"xm@itsource.com"),("小李",19,'女',"xl@itsource.com")复制代码
2.实战编写接口编写映射XML测试7、MyBatis批量删除1.sql中批量删除写法
DELETE FROM t_employee where id in (4,5,6); -- 推荐使用DELETE FROM t_employee where id=4 or id=5 or id=6; -- 不推荐复制代码
2.实战编写接口编写映射XML测试8、MyBatis解决字段映射名称不一致方案1.概述在实际开发中,数据库中的字段名规范是以下划线分隔,而Java的实体类字段规范是小驼峰,所以这就会导致字段自动映射失败,无法将数据库数据封装到实体类对象中问题展示2.Sql别名方案在Sql语句中,我们可以给返回值起别名,那么我们可以让我们的字段别名与实体类字段名称保持一致,这样就可以自动映射成功这种方式过于麻烦,不推荐使用3.MyBatis全局配置方案MyBatis提供了全局属性配置来解决数据库与实体类字段名称不一致问题,我们只需要配置开启,那么就会自动将数据库下划线字段映射成实体类驼峰字段实际开发中使用较多,推荐使用4.MyBatis自定义映射方案我们之前映射XML中SQL语句的返回值属性一直使用的是resultType,此属性是自动映射的意思,会根据数据库名称和实体类名称进行自动映射,当我们的数据库字段与实体类不一致时,那么还可以使用resultMap进行自定义映射,手动指定数据库字段与实体类字段的映射关系注意:自定义映射只要需要查询的字段都需要映射完整,不管字段名称是否一致
属性:    id:此resultMap映射的名称    type:自定义映射到那个实体类中    property:指定实体类字段是谁    column:指定数据库字段是谁标签:    id:指定数据库主键字段与实体类字段映射关系的标签    result:指定数据库普通字段与实体类字段映射关系的标签复制代码
9、关联关系概述1.关联关系的分类1.1.一对一一个人对应一个身份证ID一个QQ对应一个QQ空间一个手机号对应一个微信号真实开发使用的地方较少1.2.一对多站在部门的角度看问题例子:一个部门【dept】对应多个员工【emp】真实开发使用较多1.3.多对一站在员工的角度去看问题例子:多个员工【emp】对应一个部门【dept】真实开发使用较多1.4.多对多老师【teacher】对学生【student】学生【student】对老师【teacher】多个用户【user】对应多个角色【role】真实开发使用较多2.关联关系表的设计2.1.一对一共享主键一对一:耦合度太高,不方便维护唯一外键一对一,在任意一方设计外键2.2.一对多&多对一表设计都一样只要有外键就是多方在多方设计外键2.3.多对多需要一个中间表3.关联关系domain设计3.1.一对一在任意一方添加对方的对象字段3.2.一对多在一方添加多方的List集合对象字段3.3.多对一在多方添加一个一方的对象字段3.4.多对多双方都保存对方的List集合对象字段10、MyBatis实现关联关系查询MyBatis提供两种方式处理我们关联对象,嵌套查询和嵌套结果嵌套结果查询: 发送1条SQL,查询所有的信息(本身+关联对象)嵌套语句查询:发送1+N条sql接下来,分别使用两种方式对多对一、一对多进行处理1.一对多代码实现1.1.嵌套结果查询一对多与多对一的表设计是一样的,只是看待表的角度不同使用较多1.创建domain模型2.Mapper接口的准备3.Mapper的XML准备当我们要把数据封装到集合中时需要使用collection标签property:表示要把集合封装到对象的那个字段中ofType:表示集合泛型是什么4.功能测试1.2.嵌套语句查询使用较少1.Mapper接口的准备2.Mapper的XML准备collection标签表示封装集合property:封装对象的那个字段column:调用SQL语句时传递的参数select:集合的数据通过那条SQL语句获得EmployeeMapper.xmlDepartmentMapper.xml3.功能测试2.多对一代码实现一对一与多对一代码编写上是一样的,所以一对一就不单独讲解2.1.嵌套结果查询1.创建domain模型2.Mapper接口准备3.Mapper的XML准备association:此标签用于封装对象property:对象封装到实体类的那个字段javaType:封装的对象类型4.功能测试2.2.嵌套语句查询使用较少1.Mapper接口的准备2.Mapper的XML准备association:此标签用于封装对象property:标识对象封装到实体类的那个字段column:调用SQL语句时传递的参数select:对象的数据来自哪条SQL语句DepartmentMapper.xmlEmployeeMapper.xml3.功能测试3.多对多多对多其实就是双向一对多,我们已经学习了一对多的查询,那么多对多就是SQL查询语句不一样,封装结果操作都是一样的,各位同学可以自己进行练习11、延迟加载1.概述MyBatis中的延迟加载,也称为懒加载,是指在进行关联查询时,按照设置延迟规则推迟对关联对象的select查询,延迟加载可以有效的减少数据库压力MyBatis的延迟加载只是对关联对象的查询有延迟设置,对于主加载对象都是直接执行查询语句的2.开启延迟加载mybatis-config.xmllazyLoadingEnabled:延迟加载全局开关,设置为true代表开启,当开启时所有对象都会进行延迟加载aggressiveLazyLoading:此属性表示是否需要按需加载true:即便全局延迟加载打开,对象还是会加载所有属性false:默认值,所有对象的属性都按需加载
<settings>    <!--开启延迟加载-->    <setting name="lazyLoadingEnabled" value="true"/>    <!--关闭积极加载-->    <setting name="aggressiveLazyLoading" value="false"/></settings>复制代码
3.局部立即加载当我们开启了全局延迟加载之后,如果有些SQL我们需要立即加载,那么可以在collection或者是association标签中指定fetchType属性fetchType:局部指定SQL语句是延迟加载还是立即加载,一般当我们开启了全局延迟加载之后,部分SQL需要立即加载时配置此属性eager:立即加载lazy:延迟加载(默认)五.MyBatis进阶1、MyBatis缓存1.什么是缓存缓存就是内存中的一个对象,用于对数据库查询结果的保存,用于减少与数据库的交互次数从而降低数据库的压力,进而提高响应速度2.什么是MyBatis缓存MyBatis 中的缓存就是说 MyBatis 在执行一次SQL查询之后,这条SQL语句的查询结果并不会消失,而是被MyBatis缓存起来,当再次执行相同SQL语句的时候,就会直接从缓存中进行提取,而不是再次执行SQL命令MyBatis中的缓存分为一级缓存和二级缓存3.MyBatis一级缓存3.1.概述一级缓存又被称为 SqlSession 级别的缓存,是MyBatis默认开启的缓存SqlSession是什么:SqlSession 是SqlSessionFactory会话工厂创建出来的一个会话的对象,这个SqlSession对象用于执行具体的SQL语句并返回给用户请求的结果SqlSession级别的缓存是什么意思?SqlSession级别的缓存表示的就是每当执行一条SQL语句后,默认就会把该SQL语句缓存起来,也被称为会话缓存3.2.四种失效情况使用不同的SqlSession查询数据同一个SqlSession但是查询条件不同同一个SqlSession两次查询期间执行了任意一次增删改操作同一个SqlSession两次查询期间手动清除了缓存4.MyBatis二级缓存4.1.概述二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取4.2.二级缓存开启条件在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置在映射文件中设置标签二级缓存必须在SqlSession关闭或提交之后有效查询的数据所转换的实体类类型必须实现序列化的接口4.3.失效情况两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效4.4.二级缓存配置在mapper配置文件中添加的cache标签可以设置一些属性eviction:缓存回收策略LRU:最近最少使用的:移除最长时间不被使用的对象,默认的是 LRUFIFO:先进先出:按对象进入缓存的顺序来移除它们SOFT:移除基于垃圾回收器状态和软引用规则的对象WEAK:更积极地移除基于垃圾收集器状态和弱引用规则的对象flushInterval:刷新间隔,单位毫秒,默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新,也就是执行增删改才刷新缓存size属性:(引用数目)属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024readOnly属性:是否只读true:只读缓存,会给所有调用者返回缓存对象的相同实例,因此这些对象不能被修改,性能较高false:读写缓存,会返回缓存对象的拷贝,性能较低,但是安全,因此默认是 false4.5.缓存查询执行顺序先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用如果二级缓存没有命中,再查询一级缓存如果一级缓存也没有命中,则查询数据库SqlSession关闭之后,一级缓存中的数据会写入二级缓存2、PageHelper分页插件1.概述在前面我们通过手动实现了MyBatis的分页,这种原生的方式虽然性能最高,但是实现上稍微有点复杂,所以在真实开发中,也会使用分页插件PageHelper是一个开源的基于MyBatis拦截器开发的通用分页插件工具,该插件是国人开发的,所以文档是中文的PageHelper官网地址:pagehelper.github.io/PS:可以通过阅读官网文档进行学习2.使用导入依赖配置PageHelper一般只设置一个reasonable(是否合理分页)为true,其它参数请参考具体文档执行分页PageHelper的分页使用非常简单,只需要在执行mapper方法之前,调用静态方法传入分页参数即可3.对象说明Page对象和PageInfo对象中的属性是不一样的,以后真实开发中我们需要根据前端所需要的参数要决定我们需要返回那个对象Page对象
private int pageNum;	//当前页码private int pageSize; 	//每页数据的数量private int startRow;	//始页首行行号private int endRow;		//尾页尾行行号private long total;		//总记录数private int pages;		//总页数private Boolean reasonable; //分页合理化private Boolean pageSizeZero; //当设置为true的时候,如果pagesize设置为0(或RowBounds的limit=0),就不执行分页,返回全部结果复制代码
PageInfo对象
private int pageNum;   			//当前页private int pageSize;			//每页显示数据条数private int size;				//当前页的数量private int startRow; 			//始页首行行号private int endRow;				//尾页尾行行号private long total;				//总记录数private int pages;				//总页数private List<T> list;			//查询结果的数据private int firstPage;			//首页private int prePage;			//上一页private int nextPage;			// 下一页private int lastPage;			//最后一页private boolean isFirstPage;	//是不是第一页private boolean isLastPage;		//是不是最后一页private boolean hasPreviousPage;//有没有上一页private boolean hasNextPage;	//有没有下一页private int navigatePages;		//所有导航页号private int[] navigatepageNums;	//导航页码数复制代码
3、MyBatis逆向工程1.概述在实际开发中,为了提高开发效率,节省开发时间,那么通常一些重复的代码我们会使用工具进行生成,比如像domain、mapper、SQL语句等等有固定模板的都是可以通过工具进行基础代码的生成,一般有两种玩法正向工程:先创建Java实体类,由框架根据实体类生成数据库表,Hibernate支持正向工程逆向工程:先创建数据库表,由框架来负责根据数据库表,反向生成下面的资源Java实体类Mapper接口Mapper映射文件官方网址:mybatis.org/generator/2.使用导入依赖
<!-- 依赖MyBatis核心包 --><dependencies>    <dependency>        <groupId>org.mybatis</groupId>        <artifactId>mybatis</artifactId>        <version>3.5.11</version>    </dependency>    <!--junit驱动-->    <dependency>        <groupId>junit</groupId>        <artifactId>junit</artifactId>        <version>4.12</version>    </dependency>    <!--log4j驱动-->    <dependency>        <groupId>log4j</groupId>        <artifactId>log4j</artifactId>        <version>1.2.17</version>    </dependency>    <!-- MySQL驱动 -->    <dependency>        <groupId>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>        <version>8.0.29</version>    </dependency></dependencies><!-- 控制Maven在构建过程中相关配置 --><build>    <!-- 构建过程中用到的插件 -->    <plugins>        <!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 -->        <plugin>            <groupId>org.mybatis.generator</groupId>            <artifactId>mybatis-generator-maven-plugin</artifactId>            <version>1.4.1</version>            <!-- 插件的依赖 -->            <dependencies>                <!-- 逆向工程的核心依赖 -->                <dependency>                    <groupId>org.mybatis.generator</groupId>                    <artifactId>mybatis-generator-core</artifactId>                    <version>1.4.1</version>                </dependency>                <!--此处添加一个mysql-connector-java依赖可以防止找不到jdbc Driver-->                <dependency>                    <groupId>mysql</groupId>                    <artifactId>mysql-connector-java</artifactId>                    <version>8.0.29</version>                    <scope>runtime</scope>                </dependency>            </dependencies>        </plugin>    </plugins></build>复制代码
配置文件准备mybatis-config.xmljdbc.propertieslog4j.propertiesgeneratorConfig.xmlgeneratorConfig.xml:逆向工程核心配置文件,必须叫这个名称
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE generatorConfiguration        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"        ";><generatorConfiguration>    <!--    targetRuntime: 执行生成的逆向工程的版本        MyBatis3Simple: 生成基本的CRUD        MyBatis3: 生成带条件的CRUD        defaultModelType :flat 该模型为每一张表只生成一个实体类(解决一表生成多个实体)    -->    <context id="MySqlTables" targetRuntime="MyBatis3Simple" defaultModelType="flat">        <commentGenerator>            <!-- 是否去除自动生成的注释 true:是 : false:否 -->            <property name="suppressAllComments" value="true" />        </commentGenerator>        <!-- 数据库的连接信息 -->        <jdbcConnection driverClass="com.mysql.jdbc.Driver"                        connectionURL="jdbc:mysql://localhost:3306/itsource_mybatis"                        userId="root"                        password="root">            <!--解决映射文件出现重复多余字段-->            <property name="nullCatalogMeansCurrent" value="true"/>        </jdbcConnection>        <!-- 把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,            true时把JDBC DECIMAL NUMERIC 类型解析为java.math.BigDecimal            默认为false-->        <javaTypeResolver>            <property name="forceBigDecimals" value="true" />        </javaTypeResolver>        <!-- domain的生成策略-->        <javaModelGenerator targetPackage="cn.itsource.mybatis.domain" targetProject=".\src\main\java">            <!--是否允许使用子包:表示targetPackage属性的值是多级目录还是一级,true为多级目录,false为一级-->            <property name="enableSubPackages" value="true"/>            <!--是否去除数据库表字段前后空格,true为去除,false不去除-->            <property name="trimStrings" value="true"/>        </javaModelGenerator>        <!-- SQL映射文件的生成策略 -->        <sqlMapGenerator targetPackage="cn.itsource.mybatis.mapper" targetProject=".\src\main\resources">            <property name="enableSubPackages" value="true"/>        </sqlMapGenerator>        <!-- Mapper接口的生成策略 -->        <javaClientGenerator type="XMLMAPPER" targetPackage="cn.itsource.mybatis.mapper"                             targetProject=".\src\main\java">            <property name="enableSubPackages" value="true"/>        </javaClientGenerator>        <!-- 逆向分析的表 -->        <!-- tableName:设置要生成的表名 -->        <!-- domainObjectName:指定生成出来的实体类的类名 -->        <table tableName="t_department" domainObjectName="Department"/>    </context></generatorConfiguration>复制代码
执行插件查看效果3.逆向工程版本区别在配置文件中targetRuntime属性可以设置为两个值MyBatis3Simple: 生成基本的CRUDMyBatis3: 生成带条件的CRUD,方法众多,功能强大,推荐使用如果属性为MyBatis3那么逆向工程中会生成实例及实例对应的example,example用于添加条件,相当where后面的部分mapper接口中的方法解析

方法

功能说明

int countByExample(UserExample example) thorws SQLException

按条件计数

int deleteByPrimaryKey(Integer id) thorws SQLException

按主键删除

int deleteByExample(UserExample example) thorws SQLException

按条件删除

String/Integer insert(User record) thorws SQLException

插入数据(返回值为ID)

User selectByPrimaryKey(Integer id) thorws SQLException

按主键查询

ListselectByExample(UserExample example) thorws SQLException

按条件查询

ListselectByExampleWithBLOGs(UserExample example) thorws SQLException

按条件查询(包括BLOB字段)。只有当数据表中的字段类型有为二进制的才会产生

int updateByPrimaryKey(User record) thorws SQLException

按主键更新

int updateByPrimaryKeySelective(User record) thorws SQLException

按主键更新值不为null的字段

int updateByExample(User record, UserExample example) thorws SQLException

按条件更新

int updateByExampleSelective(User record, UserExample example) thorws SQLException

按条件更新值不为null的字段

Example类解析

方法

功能说明

example.setOrderByClause(“字段名 ASC”);

添加升序排列条件,DESC为降序

example.setDistinct(false)

去除重复,boolean型,true为选择不重复的记录

criteria.andXxxIsNull

添加字段xxx为null的条件

criteria.andXxxIsNotNull

添加字段xxx不为null的条件

criteria.andXxxEqualTo(value)

添加xxx字段等于value条件

criteria.andXxxNotEqualTo(value)

添加xxx字段不等于value条件

criteria.andXxxGreaterThan(value)

添加xxx字段大于value条件

criteria.andXxxGreaterThanOrEqualTo(value)

添加xxx字段大于等于value条件

criteria.andXxxLessThan(value)

添加xxx字段小于value条件

criteria.andXxxLessThanOrEqualTo(value)

添加xxx字段小于等于value条件

criteria.andXxxIn(List<?>)

添加xxx字段值在List<?>条件

criteria.andXxxNotIn(List<?>)

添加xxx字段值不在List<?>条件

criteria.andXxxLike(“%”+value+”%”)

添加xxx字段值为value的模糊查询条件

criteria.andXxxNotLike(“%”+value+”%”)

添加xxx字段值不为value的模糊查询条件

criteria.andXxxBetween(value1,value2)

添加xxx字段值在value1和value2之间条件

criteria.andXxxNotBetween(value1,value2)

添加xxx字段值不在value1和value2之间条件

标签: #原生js分页