Mybatis-2-1.SqlSession和Mapper

Mybatis基本工作原理

工作原理

(1)读取MyBatis的配置文件。mybatis-config.xml为MyBatis的全局配置文件,用于配置数据库连接信息。

(2)加载映射文件。映射文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,需要在MyBatis配置文件mybatis-config.xml中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。

(3)构造会话工厂。通过MyBatis的环境配置信息构建会话工厂SqlSessionFactory。

(4)创建会话对象。由会话工厂创建SqlSession对象,该对象中包含了执行SQL语句的所有方法。

(5)Executor执行器。MyBatis底层定义了一个Executor接口来操作数据库,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。

(6)MappedStatement对象。在Executor接口的执行方法中有一个MappedStatement类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等信息。

(7)输入参数映射。输入参数类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输入参数映射过程类似于JDBC对preparedStatement对象设置参数的过程。

(8)输出结果映射。输出结果类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输出结果映射过程类似于JDBC对结果集的解析过程。

SqlSessionFactoryBuilder、SqlSessionFactory

SqlSessionFactoryBuilder用于构建SqlSessionFactory。这是基于建造者模式而设计的。
SqlSessionFactoryBuilder可以通过InputStream或者Reader获取mybatis的配置文件中的内容自动配置SqlSessionFactory。SqlSessionFactory用来创造SqlSession。而Mybatis的使用就是从SqlSession开始的。

SqlSession

是Sql数据库会话,想要执行Mapper中的方法就需要用到SqlSession。
SqlSession有单例的和非单例的。在与框架整合后,SqlSession是单例的。但没有整合的时候可以是单例的也可以不是。
之所以使用单例SqlSession是因为SqlSession根本没必要有多个。按照SqlSession的生命中期,它在执行完一条sql语句之后就应该结束生命周期。这么做的话并不利于提高开发效率(每执行完一条语句都要写一个session.close()效率太低。),所以直接用单例,这样它将贯穿整个程序的运行周期而不需要关闭它,大幅度提高开发效率。

Mapper以及Mapper映射文件

Mapper是一个接口。这里面封装所有要执行的方法。在程序运行前,Mybatis会将Mapper映射文件和Mapper接口做关联。举例:

@Mapper//告知系统该类是一个Mapper类,只有拥有该注解的类才能被当做Mapper使用
public interface UserMapper{
  List selectAllUsers();
  User selectUserById(String id);
}

上面这串代码中的selectAllUsers是获取全部User的方法。该方法有多条结果返回所以返回值是List,而返回的数据是User类型的,所以List的泛型是User。selectUserById是通过ID获取User的方法。因为只有一条记录返回(假设id是User表的主键)所以使用User即可。
当然,只写这些方法是不会有任何作用的。必须还要有对应的Mapper映射文件。

Mapper映射文件和Mapper是一一对应的。Mapper中的方法和Mapper映射文件中的方法也是对应的。
下面是UserMapper配置文件的例子(文件名叫做UserMapper.xml,Mapper映射文件的文件名最好和类名一致):(这里会给出xml文件头部内容,各位读者可以复制头部内容供以后使用。为了方便,后续的章节中所有xml文件的示例代码都不再写头部内容。)




  
  

这样当调用UserMapper下的selectAllUsers的时候Mybatis就会执行UserMapper.xml文件中id为selectAllUsers的sql语句。

下面介绍一下Mapper映射文件的基本内容:
Mapper映射文件是由根标签组成的。在根标签中可以书写 select * from Product

  • 编写Mybatis配置文件-mybatis-cfg.xml
    在src/main/resources文件夹下创建该文件

    
    
        
    
    
        
            
            
                
                
                
                
            
        
    
    
        
    
    
    
  • 编写测试类进行测试
    在test/java下创建一个测试类MybatisTest。测试类中有一成员session和一个无参构造方法。

    private SqlSession session=DBUtil.getSession();
    public MybatisTest() throws IOException {
    }
    
    • 测试添加
      测试类中添加方法insertTest()
      @Test//要导入JUnit包不要导入test包
      public void insertTest(){
          List products=new ArrayList<>();
          ProductMapper mapper = session.getMapper(ProductMapper.class);
          Product product=new Product();
          product.setName("面包");
          product.setPrice(3.5);
          products.add(product);
          product=new Product();
          product.setName("香肠");
          product.setPrice(2.2);
          products.add(product);
          product=new Product();
          product.setName("果酱");
          product.setPrice(5.2);
          products.add(product);
          for (Product p:products){
              if(mapper.insertProduct(p)){
                  session.commit();//默认的session是手动提交的
                  System.out.println("插入成功");
              }else{
                  session.rollback();
                  System.out.println("插入失败");
              }
          }
      }
      
      运行,此时报错,提示Invalidate Bound,这是因为maven在打包的时候不会把非resources文件夹下的mapper.xml文件打包。可以在pom.xml中添加下列代码解决:
          
            
                
                    src/main/java
                    
                        **/*.xml
                    
                
            
        
      

      再次运行我们就可以看到有3条插入成功在控制台中。


      step8-1 插入结果
    • 查找测试
      • 查找全部
        在测试类中添加方法selectAllAndIDTest
        @Test
        public void selectAllAndIDTest(){
            ProductMapper mapper = session.getMapper(ProductMapper.class);
            System.out.println("---获取所有商品---");
            List products = mapper.selectAllProduct();
            products.forEach(e-> System.out.println(e.getId()+"-"+e.getName()+"-"+e.getPrice()));
            System.out.println("---获取id为2的商品---");
            Product product = mapper.selectProductById("2");
            System.out.println(product.getId()+"-"+product.getName()+"-"+product.getPrice());
        }
        

      运行后可以看到结果:


      • 按照价格查找商品
        在测试类中添加方法selectByPriceTest
        @Test
        public void selectByPriceTest(){
            ProductMapper mapper = session.getMapper(ProductMapper.class);
            System.out.println("获取价格小于3元的商品");
            List products = mapper.selectProductWhenPriceLessThan(3);
            products.forEach(p-> System.out.println(p.getName()+"-"+p.getPrice()));
            System.out.println("获取价格大于3元的商品");
            List products2 = mapper.selectProductWhenPriceGreaterThan(3);
            products2.forEach(p-> System.out.println(p.getName()+"-"+p.getPrice()));
        }
        

        运行后可以看到相关的商品列出:


    • 更新商品
      在测试类中创建测试方法updateTest()
      @Test
      public void updateTest(){
          ProductMapper mapper = session.getMapper(ProductMapper.class);
          System.out.println("修改3号商品:");
          Product newProduct=new Product();
          newProduct.setName("冬瓜");
          newProduct.setPrice(1456.25);
          boolean b = mapper.updateProduct("3", newProduct);
          if(b){
              session.commit();
              System.out.println("更新成功");
          }else{
              session.rollback();
              System.out.println("更新失败");
          }
      }
      
      step8-3
    • 删除商品
      创建测试方法deleteTest()
      @Test
      public void deleteTest(){
          ProductMapper mapper = session.getMapper(ProductMapper.class);
          System.out.println("删除1号:");
          int i = mapper.deleteProductById("1");
          System.out.println("删除了"+i+"条数据");
          System.out.println("删除全部货物");
          i=mapper.deleteAll();
          System.out.println("删除了"+i+"条数据");
      }
      

    ![step8-4](https://upload-images.jianshu.io/upload_images/6120602-f7c1e19db8dc15fc.png?imageMogr2/a@Mapper
    public interface UserMapper {
    List selectAllUsers();
    List selectUsersByIdards(List idCards);
    }uto-orient/strip%7CimageView2/2/w/1240)

  • 你可能感兴趣的:(Mybatis-2-1.SqlSession和Mapper)