Mybatis学习记录

  • 1.快速开始示例
    • 1.1 什么是MyMyBatis?
    • 1.2 代码示例
    • 2.基本使用
      • 2.1 #{}和${}
        • 2.2 参数传入
          • 2.2.1 概念说明
          • 2.2.2 单个简单类型
          • 2.2.3 实体类型
          • 2.2.4 零散简单数据类型
          • 2.2.5 Map类型
          • 2.3 返回值
            • 2.3.1 单个简单类型
            • 2.3.2 实体类型
            • 2.3.3 Map类型
            • 2.3.4 List类型
            • 3.多表映射
              • 3.1 什么是多表映射
              • 3.2 对一映射
              • 3.3 对多映射
              • 3.4 对一映射和对多映射的说明
              • 4.动态语句
                • 4.1 为什么需要动态语句
                • 4.2 if where标签
                • 4.3 set标签
                • 4.4 choose when otherwise标签
                • 4.5 foreach标签
                • 5.MyBatis高级扩展
                  • 5.1 批量映射
                  • 5.2 分页插件 pageHelper
                  • 5.3 MybatisX插件

                    1.快速开始示例

                    1.1 什么是MyMyBatis?

                    MyBatis 是一个用于 Java 编程语言的持久层框架,它可以帮助开发者更轻松地管理数据库交互。它的核心思想是将 SQL 语句从 Java 代码中分离出来,通过 XML 或注解的方式来配置和映射 SQL 查询、更新和删除等操作,简化 Java 应用程序与数据库之间的交互过程。

                    1.2 代码示例

                    • 准备数据库
                      CREATE DATABASE `mybatis-example`;
                      USE `mybatis-example`;
                      CREATE TABLE `t_emp`(
                        emp_id INT AUTO_INCREMENT,
                        emp_name CHAR(100),
                        emp_salary DOUBLE(10,5),
                        PRIMARY KEY(emp_id)
                      );
                      INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("tom",200.33);
                      INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("jerry",666.66);
                      INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("andy",777.77);
                      
                      • 准备实体类
                        public class Employee {
                            private Integer empId;
                            private String empName;
                            private Double empSalary;
                            
                            public Integer getEmpId() {
                                return empId;
                            }
                            public String getEmpName() {
                                return empName;
                            }
                            public Double getEmpSalary() {
                                return empSalary;
                            }
                            public void setEmpId(Integer empId) {
                                this.empId = empId;
                            }
                            public void setEmpName(String empName) {
                                this.empName = empName;
                            }
                            public void setEmpSalary(Double empSalary) {
                                this.empSalary = empSalary;
                            }
                            
                             @Override
                            public String toString() {
                                return "Employee{" +
                                        "empId=" + empId +
                                        ", empName='" + empName + '\'' +
                                        ", empSalary=" + empSalary +
                                        '}';
                            }
                        }
                        
                        • 定义Mapper接口
                          public interface EmployeeMapper {
                              //根据id查询员工信息
                              Employee queryById(Integer id);
                              //根据id删除员工
                              int deleteById(Integer id);
                          }
                          
                          • 定义Mapper.xml文件

                            Mybatis学习记录

                            (1) namespace = mapper对应接口的全限定符

                            (2)声明标签写sql语句crud:select insert update delete,每个标签对应接口的一个方法

                            (3)id是对应方法的名称,resultType是返回值。

                            
                            
                                
                                    select emp_id empId,emp_name empName, emp_salary empSalary from
                                    t_emp where emp_id = #{id}
                                
                                
                                    delete from t_emp where emp_id = #{id}
                                
                                
                            
                            
                            • 准备MyBatis配置文件

                              mybatis框架配置文件: 数据库连接信息,性能配置,mapper.xml配置等。

                              
                              
                                  
                                  
                                      
                                      
                                          
                                          
                                          
                                          
                                              
                                              
                                              
                                              
                                              
                                          
                                      
                                  
                                  
                                      
                                      
                                      
                                  
                              
                              
                              • 测试
                                public class MybatisTest {
                                    @Test
                                    public void test_01() throws IOException {
                                        //1.读取外部配置文件(mybatis-config.xml)
                                        InputStream ips = Resources.getResourceAsStream("mybatis-config.xml");
                                        //2.创建sqlSessionFactory
                                        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);
                                        //3.根据sqlSessionFactory创建sqlSession (每次业务创建一个,用完就释放)
                                        SqlSession sqlSession = sqlSessionFactory.openSession();
                                        //4.获取接口的代理对象 (代理技术) 调用代理对象的方法,就会查找mapper接口的方法
                                        //jdk动态代理技术生成的mapper代理对象
                                        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
                                        
                                        // 内部拼接接口的全限定符号.方法名  去查找sql语句标签
                                        Employee employee = mapper.queryById(1);
                                        System.out.println("employee = " + employee);
                                        //5.提交事务(非DQL)和释放资源
                                        sqlSession.commit();
                                        sqlSession.close();
                                    }
                                }
                                

                                2.基本使用

                                2.1 #{}和${}

                                • #{ }:常用

                                  Mybatis会将SQL语句中的#{}转换为占位符

                                • ${ }

                                  ${}形式传参,底层Mybatis做的是字符串拼接操作。

                                  2.2 参数传入

                                  2.2.1 概念说明

                                  这里参数传入是指上层方法(例如Service方法)调用Mapper接口时,数据传入的形式。

                                  • 简单类型:只包含一个值的数据类型
                                    • 基本数据类型:int、byte、short、double、……
                                    • 基本数据类型的包装类型:Integer、Character、Double、……
                                    • 字符串类型:String
                                    • 复杂类型:包含多个值的数据类型
                                      • 实体类类型:Employee、Department、……
                                      • 集合类型:List、Set、Map、……
                                      • 数组类型:int[]、String[]、……
                                      • 复合类型:List、实体类中包含集合……

                                        2.2.2 单个简单类型

                                        //Mapper接口中抽象方法的声明
                                        Employee selectEmployee(Integer empId);
                                        //xml
                                        
                                          select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{empId}
                                        
                                        

                                        2.2.3 实体类型

                                        //Mapper接口中抽象方法的声明
                                        int insertEmployee(Employee employee);
                                        //xml
                                        
                                          insert into t_emp(emp_name,emp_salary) values(#{empName},#{empSalary})
                                        
                                        

                                        2.2.4 零散简单数据类型

                                        零散的多个简单类型参数,如果没有特殊处理,那么Mybatis无法识别自定义名称:

                                        //Mapper接口中抽象方法的声明
                                        int updateEmployee(@Param("empId") Integer empId,@Param("empSalary") Double empSalary);
                                        //XML
                                        
                                          update t_emp set emp_salary=#{empSalary} where emp_id=#{empId}
                                        
                                        

                                        2.2.5 Map类型

                                        //Mapper接口中抽象方法的声明
                                        int updateEmployeeByMap(Map paramMap);
                                        //XML
                                        
                                          update t_emp set emp_salary=#{empSalaryKey} where emp_id=#{empIdKey}
                                        
                                        

                                        2.3 返回值

                                        2.3.1 单个简单类型

                                        //Mapper接口中的抽象方法Java
                                        int selectEmpCount();
                                        //XML
                                        
                                          select count(*) from t_emp
                                        
                                        

                                        select标签,通过resultType指定查询返回值类型!

                                        resultType = “全限定符 | 别名 | 如果是返回集合类型,写范型类型即可”

                                        关于别名可以参考MyBatis官方文档官方文档关于别名的说明

                                        2.3.2 实体类型

                                        //Mapper接口的抽象方法
                                        Employee selectEmployee(Integer empId);
                                        //XML
                                        
                                        
                                        
                                          select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{maomi}
                                        
                                        

                                        2.3.3 Map类型

                                        //Mapper接口的抽象方法
                                        Map selectEmpNameAndMaxSalary();
                                        //XML
                                        
                                          SELECT
                                            emp_name 员工姓名,
                                            emp_salary 员工工资,
                                            (SELECT AVG(emp_salary) FROM t_emp) 部门平均工资
                                          FROM t_emp WHERE emp_salary=(
                                            SELECT MAX(emp_salary) FROM t_emp
                                          )
                                        
                                        

                                        2.3.4 List类型

                                        查询结果返回多个实体类对象,希望把多个实体类对象放在List集合中返回。此时不需要任何特殊处理,在resultType属性中还是设置实体类类型即可。

                                        //Mapper接口中抽象方法
                                        List selectAll();
                                        //XML
                                        
                                          select emp_id empId,emp_name empName,emp_salary empSalary
                                          from t_emp
                                        
                                        

                                        3.多表映射

                                        3.1 什么是多表映射

                                        在实际的开发中,经常需要联合多个表进行查询。例如有2张表:客户表和订单表。分别有如下属性:

                                        customer:customer_id,customer_name
                                        order:order_id,order_name,customer_id
                                        

                                        如果有需求:根据客户id查询客户的信息和订单信息。或者根据订单id查询客户的信息。这时会需要联合多个表查询。

                                        如何对查询得到的结果集进行映射,即多表映射。一般需要完成以下工作:

                                        • 自己编写sql语句完成查询
                                        • 自己设计存储数据的实体类
                                        • 自己定义结果集映射

                                          3.2 和 3.3 中的数据库如下

                                          3.2 对一映射

                                          • 需求:根据id查询订单信息和订单对应的客户(显然,一个订单只能对应一个客户,所以是对一)
                                          • 代码实现

                                            //Order
                                            public class Order {
                                                private Integer orderId;
                                                private String orderName;
                                                private Integer customerId;
                                                private Customer customerInfo; //因为需要返回客户的信息 所以还需要customer类
                                            }
                                            //OrderMapper
                                            public interface OrderMapper {
                                                //根据id查询订单信息和订单对应的客户
                                                Order queryOrderById(Integer id);
                                            }
                                            //OrderMapper.xml
                                            
                                            
                                            
                                                
                                                    
                                                    
                                                        
                                                    
                                                
                                                
                                                
                                                    SELECT * FROM t_order  JOIN  t_customer ON  t_order.customer_id = t_customer.customer_id
                                                    WHERE t_order.order_id = #{id}
                                                
                                            
                                            //mybatis-config.xml  与后面的3.3共用这个mybatis-config.xml
                                            
                                            
                                            
                                                
                                                    
                                                    //开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn
                                                     
                                                    //自动映射任何复杂的结果集(无论是否嵌套)
                                                    
                                                
                                                
                                                
                                                    
                                                    
                                                        
                                                        
                                                        
                                                        
                                                            
                                                            
                                                            
                                                            
                                                            
                                                        
                                                    
                                                
                                                
                                                    
                                                    
                                                    
                                                    
                                                
                                            
                                            

                                            3.3 对多映射

                                            • 需求:根据id查询客户和客户关联的订单信息(单个客户可能有多个订单信息,所以是对多)
                                            • 代码实现
                                              //Customer类
                                              public class Customer {
                                                  private Integer customerId;
                                                  private String customerName;
                                                  private List orderList; //因为需要返回订单信息,是一个列表
                                              }
                                              //CustomerMapper接口
                                              public interface CustomerMapper {
                                                  //根据id查询客户和客户关联的订单信息
                                                  List queryCustomerListById(Integer id);
                                              }
                                              //CustomerMapper.xml
                                              
                                              
                                              
                                                  
                                                      
                                                      
                                                          
                                                      
                                                  
                                                  
                                                      SELECT * FROM t_customer INNER JOIN t_order ON t_customer.customer_id=t_order.customer_id WHERE t_customer.customer_id=#{id}
                                                  
                                                  
                                              
                                              //mbatis-config.xml见3.2代码实现 同
                                              

                                              3.4 对一映射和对多映射的说明

                                              • 开启结果集自动映射,就可以省略部分自定义结果集映射时的代码书写
                                                //在mybatis-config.xml 开启方式如下
                                                
                                                

                                                开启后就可以省略result部分的书写,mybatis会自动映射

                                                    
                                                        
                                                
                                                
                                                        
                                                            
                                                
                                                        
                                                    
                                                
                                                • 对一映射和对多映射中使用的分别是:
                                                  
                                                  
                                                  
                                                  
                                                  • 对orderMapper.xml和customerMapper.xml中对应的说明(颜色相同说明需要保持一致)

                                                    4.动态语句

                                                    4.1 为什么需要动态语句

                                                    在进行按照条件查询的情况下,如果有多个条件,但是有时候有的条件为空,后台需要动态的完成sql语句。例如:淘宝商品筛选中,提供了A-H多个筛选条件,但是客户可能会随机指定几个筛选条件,后台就需要动态的完成sql语句。

                                                    4.2 if where标签

                                                    • if 标签test=" "判断test是否成立,如果成立则添加if语句内到睡起来语句中
                                                    • where标签: where内部有任何一个if满足,自动添加where关键字,不满足去掉where。自动去掉多余的and 和 or 关键字。
                                                      //接口
                                                      List queryByCondition(@Param("name") String name, @Param("salary") Double salary);
                                                      
                                                              select emp_id empId,emp_name empName, emp_salary empSalary from t_emp
                                                              
                                                                  
                                                                      emp_name=#{name}
                                                                  
                                                                  
                                                                      and emp_salary=#{salary}
                                                                  
                                                              
                                                      
                                                      

                                                      4.3 set标签

                                                      set标签自动去掉多余的逗号并自动添加set关键字

                                                      //接口
                                                      int updateInfo(@Param("id") String id, @Param("name") String name, @Param("salary") int salary);
                                                      
                                                          
                                                              update t_emp
                                                              
                                                                  
                                                                      emp_name=#{name},
                                                                  
                                                                  
                                                                      emp_salary=${salary}
                                                                  
                                                              
                                                              where emp_id=#{id}
                                                          
                                                      

                                                      4.4 choose when otherwise标签

                                                      在多个分支条件中,仅执行一个。从上到下依次执行条件判断:遇到的第一个满足条件的分支会被采纳,被采纳分支后面的分支都将不被考虑,如果所有的when分支都不满足,那么就执行otherwise分支。类似switch-case

                                                      //根据两个条件查询,如果姓名不为null使用姓名查询,如果姓名为null,薪水不为空就使用薪水查询! 都为null查询全部
                                                      ListqueryByNameOrSalary(@Param("name") String name, @Param("salary") Double salary);
                                                      
                                                          
                                                              select emp_id empId,emp_name empName, emp_salary empSalary from t_emp t_emp
                                                              where
                                                              
                                                                  
                                                                      emp_name = #{name}
                                                                  
                                                                  
                                                                      emp_salary = #{salary}
                                                                  
                                                                  1=1
                                                              
                                                          
                                                      

                                                      4.5 foreach标签

                                                      collection属性:要遍历的集合

                                                      item属性:遍历集合的过程中能得到每一个具体对象,在item属性中设置一个名字,将来通过这个名字引用遍历出来的对象

                                                      separator属性:指定当foreach标签的标签体重复拼接字符串时,各个标签体字符串之间的分隔符

                                                      open属性:指定整个循环把字符串拼好后,字符串整体的前面要添加的字符串

                                                      close属性:指定整个循环把字符串拼好后,字符串整体的后面要添加的字符串

                                                      index属性:这里起一个名字,便于后面引用

                                                      遍历List集合,这里能够得到List集合的索引值

                                                      遍历Map集合,这里能够得到Map集合的key

                                                          
                                                          (#{emp.empName},#{myIndex},#{emp.empSalary},#{emp.empGender})
                                                      
                                                      

                                                      5.MyBatis高级扩展

                                                      5.1 批量映射

                                                      在myBatis.config.xml的配置文件中,如果有多个Mapper,通常需要进行多次映射,如下所示:

                                                      可以直接在配置文件中使用以下代码代替:

                                                          
                                                      
                                                      

                                                      但是必须满足以下要求:

                                                      • Mapper 接口和 Mapper 配置文件名称一致:EmployeeMapper.java对应EmployeeMapper.xml
                                                      • 在Rsources下创建mapper接口包一致的文件夹结构存放mapper.xml文件

                                                        5.2 分页插件 pageHelper

                                                        • pom.xml引入依赖
                                                              com.github.pagehelper
                                                              pagehelper
                                                              5.1.11
                                                          
                                                          
                                                          • mybatis-config.xml配置分页插件
                                                                
                                                                    
                                                                
                                                            
                                                            
                                                            • 测试代码
                                                              @Test
                                                                  public void testTeacherRelationshipToMulti() {
                                                                      EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
                                                                      PageHelper.startPage(2,2);
                                                                      List employees = mapper.queryBySalary(500.0);
                                                                      PageInfo pageInfo = new PageInfo(employees);
                                                                      System.out.println("pageInfo = " + pageInfo);
                                                                      long total = pageInfo.getTotal(); // 获取总记录数
                                                                      System.out.println("total = " + total);
                                                                      int pages = pageInfo.getPages();  // 获取总页数
                                                                      System.out.println("pages = " + pages);
                                                                      int pageNum = pageInfo.getPageNum(); // 获取当前页码
                                                                      System.out.println("pageNum = " + pageNum);
                                                                      int pageSize = pageInfo.getPageSize(); // 获取每页显示记录数
                                                                      System.out.println("pageSize = " + pageSize);
                                                                      List list = pageInfo.getList();//获取查询页的数据集合
                                                                      System.out.println("teachers = " + list);
                                                                      employees.forEach(System.out::println);
                                                                  }
                                                              //输出
                                                              pageInfo = PageInfo{pageNum=2, pageSize=2, size=2, startRow=3, endRow=4, total=4, pages=2, list=Page{count=true, pageNum=2, pageSize=2, startRow=2, endRow=4, total=4, pages=2, reasonable=false, pageSizeZero=false}[Employee{empId=3, empName='andy', empSalary=500.0}, Employee{empId=4, empName='tom', empSalary=500.0}], prePage=1, nextPage=0, isFirstPage=false, isLastPage=true, hasPreviousPage=true, hasNextPage=false, navigatePages=8, navigateFirstPage=1, navigateLastPage=2, navigatepageNums=[1, 2]}
                                                              total = 4
                                                              pages = 2
                                                              pageNum = 2
                                                              pageSize = 2
                                                              teachers = Page{count=true, pageNum=2, pageSize=2, startRow=2, endRow=4, total=4, pages=2, reasonable=false, pageSizeZero=false}[Employee{empId=3, empName='andy', empSalary=500.0}, Employee{empId=4, empName='tom', empSalary=500.0}]
                                                              Employee{empId=3, empName='andy', empSalary=500.0}
                                                              Employee{empId=4, empName='tom', empSalary=500.0}
                                                              

                                                              5.3 MybatisX插件

                                                              • ORM:ORM(Object-Relational Mapping,对象-关系映射)是一种将数据库和面向对象编程语言中的对象之间进行转换的技术。它将对象和关系数据库的概念进行映射,最后我们就可以通过方法调用进行数据库操作
                                                              • 逆向工程:逆向工程是一种自动化生成持久层代码和映射文件的工具,它可以根据数据库表结构和设置的参数生成对应的实体类、Mapper.xml 文件、Mapper 接口等代码文件
                                                              • MybatisX插件能完成逆向工程,但是只能生成单表crud的操作,多表查询依然需要我们自己编写
                                                              • 步骤

微信扫一扫