栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

mybatis深度解析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

mybatis深度解析


在茫茫人海中,相遇既是一种缘分,相知则是一种传递,相遇相知构成了这份友谊,所以希望能够有很多跟我一样可能并非天赋异鼎,但是却对技术充满热爱的人。能够从我的文章中收获到东西。

Mybatis的使用教程
  • 前言
  •  mybatis是什么?
  • ‍ mybatis的具体使用流程
    • 殺 pom依赖
    •  mybatis的主配置文件
    • 珞 存储jdbc连接信息的文件
    •  实体类Student
    • 朗 正常的测试流程
    •  接口对应的xml文件
    •  代理对象的使用
  •  mybatis中的Param使用
  • ‍ mybatis中的resultType和resultMap的使用
  •  模糊查询的注意点
  • 濾 动态sql
  •  分页查询


前言

本次的整个mybatis我希望使用引导式的方式来记录自己在学习mybatis过程中是如何一步步理解并掌握的。


提示:以下是本篇文章正文内容,下面案例可供参考

 mybatis是什么?

学习任何框架之前我都会有一个疑问:这个框架是什么?他有什么作用?以及我应该去学习他的那些内容来完美的掌握这个框架。mybatis也不例外。但是在学习mybatis之前我们要先掌握一个概念:什么是框架?

框架(framework)是一个框子——指其约束性,也是一个架子——指其支撑性。是一个基本概念上的结构,用于去解决或者处理复杂的问题。
框架这个广泛的定义使用的十分流行,尤其在软件概念。框架也能用于机械结构。(来自于百度百科)
我们不如通俗一点来说框架你就当成一个舞台,舞台提供的基础功能每个人都能使用,这个基础功能就相当于其他大佬已经给你写好的类或者功能。你直接拿过来使用即可。

对于框架来说一般一个框架针对于一个特定的领域有效,比如mybatis做数据库操作强,但是不能做其他的。那么我们使用mybatis用来做什么呢?

说白了,就是两件事:
1.Sql映射:
可以把数据库表中的一行数据,映射成为一个java对象
一行数据可以看做是一个java对象,操作这个对象,就相当于操作表中的数据
2.数据访问,对数据库执行增删改查。

也就是mybatis帮我们做了以前我们自己做的事:创建连接对象,关闭资源等。我们现在只需要提供给mybatis一个语句剩下的我们都不需要管了。


‍ mybatis的具体使用流程

基础的文件结构:

殺 pom依赖

代码如下:


    
    
      org.mybatis
      mybatis
      3.5.5
    
    
    
      mysql
      mysql-connector-java
      5.1.47
    

    
      junit
      junit
      4.12
      test
    
  

 mybatis的主配置文件

代码如下:







             

    
    
      
        
        
    
    

     





        
         
         
     

    
        
        
            
            
            
            
                
                
                
                
                
            
        

        

            

            

                
                
                
                
            
        

    

    
    
        






          



    


        
珞 存储jdbc连接信息的文件

代码如下:

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/数据库名称
user=root
passwd=自己的数据库密码
 实体类Student

代码如下:

package com.bjpowernode.domain;

public class Student {
     private Integer id;
     private String name;
     private String email;
     private Integer age;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

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

    public String getEmail() {
        return email;
    }

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

    public Integer getAge() {
        return age;
    }

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

朗 正常的测试流程

代码如下:

package com.bjpowernode;
import com.bjpowernode.domain.Student;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestMyBatis {
       @Test
      public void test() throws IOException {

//           1.定义mybatis主配置文件的名称,从类路径的根开始(target/classes)
//        也就是编译完成以后 里面找mybatis路径
           String config="mybatis.xml";
//         2.读取这个config表示的文件
           InputStream in = Resources.getResourceAsStream(config);
//        3.创建SqlSessionFactoryBuilder对象
           SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//         4.创建SqlSessionFactory对象
           SqlSessionFactory factory = builder.build(in);
//          5.【重要】 获取SqlSession对象,从SqlSessionFactory中获取SqlSession
           SqlSession sqlSession =factory.openSession();
//          6.【重要】 指定要执行的sql语句的标识,sql映射文件中的 namespace+"."+标签的id值
           String sqlId="com.bjpowernode.dao.StudentDao"+"."+"insert";
//           7.执行sql语句,通过sqlId找到语句
             Student student=new Student();
             student.setId(1004);
             student.setName("曹操");
             student.setEmail("caocao@qq.com");
             student.setAge(26);
             int num=sqlSession.insert(sqlId, student);
//            8.输出结果
             sqlSession.commit();
//             因为开启了事务所以必须要加上commit,否则只是保存在了缓存里。
//           mybatis默认不是自动提交事务
           System.out.println("执行的结果"+num);
//              9.关闭sqlSession
           sqlSession.close();

       }
}


这里由于 每一次测试都会有大量重复的代码所以我们可以把重复代码封装起来方便后续的使用!

代码如下:

package com.bjpowernode.ustils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

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

public class MyBatisUtils {

        private static SqlSessionFactory factory=null;

    static {

          String config ="mybatis.xml";
          InputStream in = null;

        try {
            in = Resources.getResourceAsStream(config);
             factory=new SqlSessionFactoryBuilder().build(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



//       获取SqlSession对象
         public static SqlSession getSession()
        {        SqlSession sqlSession=null;
               if (factory!=null)
               {
                    sqlSession=factory.openSession();//自动提交事务

               }
               return sqlSession;
        }


}

 接口对应的xml文件

代码如下:




    
            select * from student order by id;
    
    
           insert  into student values(#{id},#{name},#{email},#{age})
    








 代理对象的使用
  public void test()
      {

//          使用mybatis的动态代理机制,使用SqlSession.getMapper(dao接口)
//           getMapper 能获取dao接口对应的实现类
            SqlSession sqlSession= MyBatisUtils.getSession();
            StudentDao dao=sqlSession.getMapper(StudentDao.class);
//            调用dao方法执行操作
            Listlist= dao.list();
//            com.sun.proxy.&Proxy2:jdk的动态代理
            list.forEach(student -> System.out.println(student));
            sqlSession.close();
      }


截止到上面的正常测试为止我们都没有使用到接口就可以正常的访问我们的xml文件。那么我们的接口文件到底用来干什么呢?对于正常测试里面的代码来说还是过多,显得有点冗余复杂,那么我们如何减少代码量呢?通过代理对象的使用。


对比我们正常测试的代码我们进行分析:

List list =dao.list();
杻 dao对象,类型是StudentDao,全限定名称是com.bjpowernode.dao.StudentDao
全限定名称和namespace是一样的。(这个namespace你可以自定义名称 叫什么都可以,但是我们会让他和接口全限定名称一样,就是为了使用代理对象)
 方法名称,list ,这个方法就是mapper文件中的id值list(跟namespace的道理一样)
說 通过dao中方法的返回值也可以确定mybatis 要调用的SqlSession的方法。

   如果返回值是List,调用的就是SqlSession.list()方法。
   如果返回值是int,或是非List的,看mapper文件中的 标签是 
   就会调用SqlSession的insert,update等方法。
    

丹mybatis的动态代理:mybatis根据dao的方法调用,获取执行sql语句的信息
mybatis根据你的dao接口,创建出一个dao接口的实现类,并创建这个类的对象
完成SqlSession调用方法,访问数据库。(也就是有了代理对象,mybatis帮你把
原先你需要写的代码通过框架给你实现了。你需要执行的操作变少了。)

那么实现代理对象的操作是什么?
答:

 SqlSession sqlSession=MyBatisUtils.getSession();
 StudentDao studentDao=sqlSession.getMapper(StudentDao.class);

就是通过getMapper方法获取到StudentDao的类文件。java会通过反射机制帮你获取到接口的代理对象。这样你往后的操作只需要 通过接口调用方法即可实现对于数据库的操作。

这里讲完了正常的mybatis使用流程。我们接下来就讲一下param的使用!

 mybatis中的Param使用

关于Param的使用:

一个简单类型的传值 : 我们只需要在xml文件中通过#{任意字符}即可获取到传过来的参数。
寧多个参数的传值:

1.使用@Param命名参数

接口 public List selectlist(@Param(“myname”) String name,@Param(“myage”) Integer age )

使用 @Param(“参数名”) String name

mapper 文件:
select * from student where name=#{myname} or age=#{myage}

2.使用对象传值

将你的对象里面的属性赋值后,他就类似于一个键值对的形式,id=1,name=“李四” 所以你要获取到对象的值。直接通过#{id} , #{name}即可获取。

3.按位置传值(不重要)
mybatis 3.4之前,使用 #{0},#{1}
mybatis 3.4之后,使用#{arg0},#{arg1}

4.通过Map传值(不重要,这个就类似于你的对象传值)
就是map.put(“myname”,“李四”) 通过接口参数传递。
然后xml文件通过#{myname}获取值。

下面是相关代码:

xml文件:






    
         select  * from student where id = ${id} ;
--           这个可以是任意的字符 不非得是 id!!!!
    

     
           select * from student where name=#{paramname} or age=#{paramage}
     

    
           select * from student order by ${colName};
     



测试文件:

  @Test
       public void test()
      {

                SqlSession sqlSession = MyBatisUtils.getSession();
                StudentDao studentDao= sqlSession.getMapper(StudentDao.class);
                Student student=studentDao.list(1007);
                System.out.println(student);
                sqlSession.close();


      }
      @Test
      public void  test1(){
          SqlSession sqlSession=MyBatisUtils.getSession();
          StudentDao studentDao=sqlSession.getMapper(StudentDao.class);
//          Listlist=studentDao.selectlist("李四", 28);
          QueryParam queryParam=new QueryParam();
          queryParam.setParamage(28);
          queryParam.setParamname("zhangsan");
          List list=studentDao.paramlist(queryParam);
          list.forEach(student -> System.out.println(student));
          sqlSession.close();

//          这里直接用哪个Student对象就行。 然后里面就传两个值就好了。
//            到时候就接受这俩值

      }
      @Test
    public void  test2(){
        SqlSession sqlSession=MyBatisUtils.getSession();
        StudentDao studentDao=sqlSession.getMapper(StudentDao.class);
        Map map=new HashMap<>();
        map.put("myname", "张三");
        map.put("myage",20);
        List list=studentDao.selectMap(map);
        list.forEach(student -> System.out.println(student));
        sqlSession.close();

    }
    @Test
    public void  test3(){
        SqlSession sqlSession=MyBatisUtils.getSession();
        StudentDao studentDao=sqlSession.getMapper(StudentDao.class);
        List list=studentDao.selectUse$("age");
        list.forEach(student -> System.out.println(student));
        sqlSession.close();

    }

索讲完param的传值 接下来就是resultType,顾名思义:resultType就是结果集的意思,那么对于结果集来说跟谁的联系最大?select语句!!

‍ mybatis中的resultType和resultMap的使用

根据上面的提示:select语句跟resultType是息息相关的。那么原因是什么?在我们jdbc的学习阶段我们知道最后通过预编译提交 ps.executeQuery() (这个ps是预编译的对象) 后我们会获得一个 结果集。 然后 rs. next() 我们会将数据库中的每一条数据通过一个对象存储起来并且返回!!! 这个对象类型就是我们resultType的类型。
也就是说我们通过规定 resultType类型的值来决定那个对象去获取到数据库的数据。 这也就跟开始说的mybatis框架作用对照:

可以把数据库表中的一行数据,映射成为一个java对象
一行数据可以看做是一个java对象,操作这个对象,就相当于操作表中的数据

1. 对象映射

通过设置 resultType的值是对象类型(全限定名称)来 映射数据库中的一行数据 ,也就是将这一行数据存放在你定义的这个类型的对象中。 注意:字段名必须和属性名一一对应 所以这也就是为什么我们要根据数据库的表建立对应实体类的目的。


2.Map映射

我们既然知道 对象是属性=value 的形式 那么这跟map 的键值对很相似。所以我们也可以设置
select * from student

resultMap就是为了解决你的对象跟字段名不一样的问题。因为需要相同才可以一一映射。如果不一样我们就无法获取数据库的数据。所以通过resultMap
可以指定字段名跟对象的那个属性进行映射。

 列名和属性名不一样:第二种方式
resultType的默认原则是 同名的列值赋值给同名的属性, 使用列别名。


         select id,name,email,age from student where name like #{name}
    
  • 藍第二种方式就是拼接你可以通过concat或者直接拼接都可以
    
       select * from student where 1=1
        
            and name=#{name}
        
        
            or age=#{age}
        
   

从这一段代码中我们可以看到如果不加 where 1=1的这个条件时,当第一个条件符合,那么拼接and 就会变成

 select * from student and name=#{name}

很明显这个语法是错误的。并且你即使加了 where 1=1 这个条件在和 包含or的语句拼接时也是错误的。

2.所以为了避免这个错误我们的where就要跟if标签一起使用:


    select * from student
    
    
         name=#{name}
    
    
        or age>#{age}
    
    

 where标签的作用就是自动给你添加where条件并自动给你删除or或者多余的and。避免了你手动拼接的错误!

3.foreach标签的用法:

接口文件:

 List selectForeachTwo(List list);

‍xml文件:

   
 分页查询

邏 对于分页查询如果我们使用前端ajax传数据然后后端使用 limit #{page},#{pagesize} 的方法获取分页数据很麻烦。所以通过pageHelper我们就不需要去写limit语句。

1.首先我们要导入pageHelper的依赖:
最新版:可以去maven官网找

  
      com.github.pagehelper
      pagehelper
      5.1.10
    

2.接口的方法:

//     使用pageHelper分页数据
     List selectAll();

3.xml文件:

  

4.测试类(我们在测试类中使用pageHelper):

 @Test
    public void testpagehelper()
    {
        SqlSession sqlSession=MyBatisUtils.getSession();
        StudentDao studentDao= sqlSession.getMapper(StudentDao.class);
//        加入PageHelper的方法,分页
         pageNum:第几页,从1开始
         pageSize:一页中有多少行数据
        PageHelper.startPage(2, 3);

        List list1= studentDao.selectAll();
        list1.forEach(student -> System.out.println(student));
        sqlSession.close();
    }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/351127.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号