Java学习记录之Mybatis

Java学习记录之Mybatis,第1张

Java学习记录之Mybatis Mybatis 1、简介 1.1、什么是Mybatis
  • MyBatis 是一款优秀的持久层框架
  • 它支持自定义 SQL、存储过程以及高级映射。
  • MyBatis免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
  • MyBatis可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录
  • MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了[google code](https://baike.baidu.com/item/google code/2346604),并且改名为MyBatis 。
  • 2013年11月迁移到Github。

如何获得Mybatis?

  • maven仓库

    
        org.mybatis
        mybatis
        3.5.6
    
    
    
  • GitHub:

  • 中文文档:

1.2、持久化

数据持久化

  • 持久化就是将程序的数据在持久状态和瞬时状态转化的过程
  • 内存:断电即失
  • 数据库(JDBC),io文件持久化
  • 生活:冷藏、罐头

为什么需要持久化?

  • 有一些对象,不能让他丢掉
  • 内存太贵了
1.3、持久层

Dao层,Service层,Controller层…

  • 完成持久化工作的代码块
  • 层界限十分明显
1.4、为什么需要Mybatis?
  • 帮助程序员将数据存入到数据库中。
  • 方便
  • 传统的JDBC代码太复杂了,简化,框架,自动化。
  • 不用Mybatis也可以,更容易上手,技术没有高低之分
  • 优点
    • 简单易学
    • 灵活
    • SQL和代码的分离,提高了可维护性
    • 提供映射标签,支持对象与数据库的ORM字段关系映射
    • 提供对象关系映射标签,支持对象关系组件维护
    • 提供xml标签,支持编写动态SQL

最重要的一点:是用的人多!

2、第一个Mybatis程序

思路:搭建环境–>导入Mybatis–>编写代码–>测试!

2.1、搭建环境

搭建数据库

新建项目

  1. 新建一个普通的maven项目
  2. 删除src目录
    
        
        
            mysql
            mysql-connector-java
            5.1.47
        
        
        
        
            org.mybatis
            mybatis
            3.5.6
        
        
        
            junit
            junit
            4.12
        
    
2.2、创建一个模块




    
        
            
            
                
                
                
                
            
        
    


  • 编写Mybatis工具类

    package com.ji.utils;
    
    //import javax.annotation.Resources;
    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 sqlSessionFactory;
        static{
            try {
                //使用Mybatis第一步:获取sqlSessionFactory对象
                String resource = "mybatis-config.xml";
                InputStream inputStream = Resources.getResourceAsStream(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
        // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
        public static SqlSession getSqlSession(){
            return sqlSessionFactory.openSession();
        }
    }
    
    
2.3、编写代码
  • 实体类

    package com.ji.pojo;
    
    //实体类
    public class User {
        private int id;
        private String name;
        private String pwd;
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", name='" + name + ''' +
                    ", pwd='" + pwd + ''' +
                    '}';
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPwd() {
            return pwd;
        }
    
        public void setPwd(String pwd) {
            this.pwd = pwd;
        }
    
        public User() {
        }
    
        public User(int id, String name, String pwd) {
            this.id = id;
            this.name = name;
            this.pwd = pwd;
        }
        
    }
    
    
  • Dao接口

    public interface UserDao {
        List getUserList();
    }
    
  • 接口实现类由原来的UserDaoImp转变为一个Mapper配置文件

    
    
    
    
    
        
            select * from mybatis.user
        
    
    
    
2.4、测试

注意点:org.apache.ibatis.binding.BindingException: Type interface com.ji.dao.UserDao is not known to the MapperRegistry.(类型接口Dao是未知的在Mapper注册中心里面)

MapperRegistry是什么?

核心配置文件中注册Mappers

  • junit测试

    public class UserDaoTest {
    
        @Test
        public void test(){
            //第一步:获得sqlSession对象
            SqlSession sqlSession = MybatisUtils.getSqlSession();
    
            //方式一:getMapper
            UserDao mapper = sqlSession.getMapper(UserDao.class);
            List userList = mapper.getUserList();
    
            for (User user : userList){
                System.out.println(user);
            }
    
            //关闭sqlSession
            sqlSession.close();
        }
    }
    
    

可能会遇到的问题

  1. 配置文件没有注册
  2. 绑定接口错误
  3. 方法名不对
  4. 返回类型不对
  5. Maven导出资源问题
3、CRUD 3.1、namespace

namespace中的包名要和接口的包名一致!

3.2、select

选择,查询语句;

  • id:就是对应的namespace中的方法名;

  • resultType:Sql语句执行的返回值!

  • parameterType:参数类型!

  1. 编写接口

    //根据Id查询用户
        User getUserById(int id);
    
  2. 编写对应Mapper中的sql语句

     
            select * from mybatis.user where id = #{id}
        
    
    • resultMap元素是MyBatis中最重要最强大的元素
    • ResultMap的设计思想是:对于简单的语句根本不需要配置显式的的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。
    • Resultmap最优秀的地方在于,虽然你已经对它相当了解了,但是根本就不需要显式地用到他们。
    6、日志 6.1、日志工厂

    如果一个数据库 *** 作出现了异常,我们需要排错。日志就是最好的助手!

    曾经:sout、debug

    现在:日志工厂!

    在Mybatis中具体使用哪一个日志实现,在设置中设定!

    STDOUT_LOGGING标准日志输出

    在Mybatis核心配置文件中,配置我们的日志

    
            
        
    

    6.2、Log4j

    什么是Log4j?

    • Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件。
    • 我们也可以控制每一条日志的输出格式;
    • 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。
    • 最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
    1. 先导入Log4j的包

      
          log4j
          log4j
          1.2.17
      
      
      
    2. log4j.properties

      log4j.rootLogger=DEBUG,console,file
      
      #控制台输出的相关设置
      log4j.appender.console = org.apache.log4j.ConsoleAppender
      log4j.appender.console.Target = System.out
      log4j.appender.console.Threshold=DEBUG
      log4j.appender.console.layout = org.apache.log4j.PatternLayout
      log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
      
      #文件输出的相关设置
      log4j.appender.file = org.apache.log4j.RollingFileAppender
      log4j.appender.file.File=./log/kuang.log
      log4j.appender.file.MaxFileSize=10mb
      log4j.appender.file.Threshold=DEBUG
      log4j.appender.file.layout=org.apache.log4j.PatternLayout
      log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
      
      #日志输出级别
      log4j.logger.org.mybatis=DEBUG
      log4j.logger.java.sql=DEBUG
      log4j.logger.java.sql.Statement=DEBUG
      log4j.logger.java.sql.ResultSet=DEBUG
      log4j.logger.java.sql.PreparedStatement=DE
      
    3. 配置log4j为日志的实现

       
              
          
      
    4. Log4j的使用!直接测试运行刚才的查询

    简单使用

    1. 在要使用的Log4j的类中,导入包import org.apache.log4j.Logger;

    2. 日志对象,参数为当前类的class

       static Logger logger = Logger.getLogger(UserDaoTest.class);
      
    3. 日志级别

       logger.info("info:进入了testLog4j");
              logger.debug("debug:进入了testLog4j");
              logger.error("error:进入了testLog4j");
      
    7、分页

    思考:为什么要分页?

    • 减少数据的处理量

    使用Limit分页

    语法:select * from user limit startIndex,pageSize;
    

    使用Mybatis实现分页,核心SQL

    1. 接口

       //分页
          List getUserByLimit(Map map);
      
    2. Mapper.xml

       
          
              select * from mybatis.user Limit #{startIndex},#{pageSize}
          
      
    3. 测试

          @Test
          public void getUserByLimit(){
              SqlSession sqlSession = MybatisUtils.getSqlSession();
      
              UserMapper mapper = sqlSession.getMapper(UserMapper.class);
              HashMap map = new HashMap();
              map.put("startIndex",0);
              map.put("pageSize",2);
              List userList = mapper.getUserByLimit(map);
              for (User user : userList) {
                  System.out.println(user);
              }
      
              sqlSession.close();
          }
      
    8、使用注解开发 8.1、开发实例
    1. 注解在接口上实现

          @Select("select * from user")
          List getUsers();
      
    2. 需要在核心配置文件中绑定接口!

       
          
              
          
      
    3. 测试

    本质:反射机制实现

    底层:动态代理!

    8.2、CRUD

    我们可以在工具类创建的时候实现自动提交事务!

     //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
        // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
        public static SqlSession getSqlSession(){
            return sqlSessionFactory.openSession(true);
        }
    

    编写接口,增加注解

    package com.ji.dao;
    
    import com.ji.pojo.User;
    import org.apache.ibatis.annotations.*;
    
    import java.util.List;
    
    public interface UserMapper {
    
        @Select("select * from user")
        List getUsers();
    
        //方法存在多个参数,所有参数前面必须加上@Param("id")注解
        @Select("select * from user where id=#{id}")
        User getUserById(@Param("id") int id);
    
        @Insert("insert into user(id,name,pwd) values (#{id},#{name},#{password})")
        int addUser(User user);
    
        @Update("update user set name=#{name},pwd=#{password} where id=#{id}")
        int updateUser(User user);
    
        @Delete("delete from user where id=#{uid}")
        int deleteUser(@Param("uid") int id);
    
    }
    
    

    测试类

    【注意:我们必须要将接口注册绑定到我们的核心配置文件中】

    关于@Param()注解

    • 基本类型的参数或者String类型,需要加上
    • 引用类型不需要加
    • 如果只有一个基本类型的话,可以忽略,但是建议加上!
    • 我们在SQL中引用的就是我们这里的@Param()中设定的属性名!
    9、Lombok

    使用步骤:

    1. 在IDEA中安装Lombok插件!

    2. 在项目中导入Lombok的jar包

              
                  org.projectlombok
                  lombok
                  1.18.20
              
      
    3. 在实体类上加注解即可!

      @Data
      @AllArgsConstructor
      @NoArgsConstructor
      
    10、多对一处理

    测试环境搭建

    1. 导入Lombok
    2. 新建实体类Teacher,Student
    3. 建立Mapper接口
    4. 建立Mapper.xml文件
    5. 在核心配置文件中绑定注册我们的Mapper接口或者文件!
    6. 测试查询是否能够成功!

    按照查询嵌套处理

     
        
        
            select * from teacher where id=#{id}
        
    

    按照结果嵌套处理

     
        
            select s.id sid, s.name sname, t.name tname, t.id tid
            from student s,teacher t
            where s.tid = t.id and t.id = #{tid}
        
    
        
            
            
            
            
                
                
                
            
    
        
    
    

    按照查询嵌套处理

    
            select * from mybatis.student where tid=#{tid}
        
    

    小结

    1. 关联-association 【多对一】
    2. 集合-collection 【一对多】
    3. JavaType & ofType
      1. JavaType用来指定实体类中的属性的类型
      2. ofType用来指定映射到List或者集合中的pojo类型,泛型中的约束类型!

    注意点:

    • 保证SQL的可读性,尽量保证通俗易懂
    • 注意一对多和多对一中,属性名和字段的问题!
    • 如果问题不好排查错误,可以使用日志,建议使用Log4j

    面试高频

    • MySQL引擎
    • InnoDB底层原理
    • 索引
    • 索引优化!
    12、动态SQL

    什么是动态SQL:动态SQL就是指根据不同的条件生成不同的SQL语句

    如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
    
    if
    choose (when, otherwise)
    trim (where, set)
    foreach
    

    搭建环境

    CREATE TABLE `blog`(
      `id` VARCHAR(50) NOT NULL COMMENT '博客id',
      `title` VARCHAR(100) NOT NULL COMMENT '博客标题',
      `author` VARCHAR(30) NOT NULL COMMENT '博客作者',
      `create_time` DATETIME NOT NULL COMMENT '创建时间',
      `views` INT(30) NOT NULL COMMENT '浏览量'
    )ENGINE=INNODB DEFAULT CHARSET=utf8;
    

    创建一个基础工程

    1. 导包

    2. 编写配置文件

    3. 编写实体类

      @Data
      public class Blog {
          private int id;
          private String title;
          private String author;
          private Date createTime;
          private int  views;
      }
      
    4. 编写实体类对应的Mapper接口和Mapper.XML文件

    IF
    
    

    动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式,去排列组合就可以了

    13、缓存 13.1、简介
    1. 什么是缓存【Cache】?

      • 存在内存中的临时数据。
      • 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
    2. 为什么使用缓存?

      • 减少和数据库的交互次数,减少系统开销,提高系统效率。
    3. 什么样的数据能使用缓存?

      • 经常查询并且不经常改变的数据。
    13.2、Mybatis缓存
    • Mybatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
    • Mybatis系统中默认定义了两级缓存:一级缓存和二级缓存
      • 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
      • 二级缓存需要手动开启和配置,它是基于namespace级别的缓存。
      • 为了提高扩展性,Mybatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存
    13.3、一级缓存
    • 一级缓存也叫本地缓存:SqlSession
      • 与数据库同一次会话期间查询到的数据会放在本地缓存中。
      • 以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库;

    测试步骤:

    1. 开启日志!
    2. 测试在一个Session中查询两次相同记录
    3. 查看日志输出

    缓存失效情况:

    1. 查询不同的东西

    2. 增删改 *** 作,可能会改变原来的数据,所以必定会刷新缓存!

    3. 查询不同的Mapper.xml

    4. 手动清理缓存!

    **小结:**一级缓存默认是开启的,只在一次SqlSession中有效,也就是拿到连接到关闭连接这个区间段!一级缓存就是一个Map。

    13.4、二级缓存
    • 二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存
    • 基于namespace级别的缓存,一个名称空间,对应一个二级缓存;
    • 工作机制
      • 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
      • 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
      • 新的会话查询信息,就可以从二级缓存中获取内容;
      • 不同的Mapper查出的数据会放在自己对应的缓存(map)

    步骤:

    1. 开启全局缓存

              
      
    2. 在要使用的二级缓存中的Mapper中开启

          
      
      
    3. 测试

      我们需要将实体类序列化!否则就会报错!

    小结:

    • 只要开启了二级缓存,在同一个Mapper中就有效
    • 所有的数据都会先放在一级缓存中;
    • 只有当会话提交,或者关闭的时候,才会提交到二级缓存中
    13.5、缓存原理

    欢迎分享,转载请注明来源:内存溢出

    原文地址:https://54852.com/zaji/5609094.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-15
下一篇2022-12-15

发表评论

登录后才能评论

评论列表(0条)

    保存