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

Mybatis

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

Mybatis

1、简介 1.1、什么是Mybatis
  • MyBatis 是一款优秀的持久层框架
  • 它支持自定义 SQL、存储过程以及高级映射。
  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
1.2、优点
  • 简单易学
  • 灵活
  • sql与代码分离,易于维护
  • 提供映射标签,支持对象与数据库的orm字段关系映射
  • 提供xml标签,支持编写动态sql
  • 提供关系映射标签,支持对象关系组建维护
2、Hello,Mybatis(xml篇) 2.1、搭建环境 1. 创建Maven工程,添加Maven依赖

    org.mybatis
    mybatis
    3.5.2



    mysql
    mysql-connector-java
    8.0.21



    junit
    junit
    4.11
    test

2、编写mybatis配置文件mybatis-config.xml

db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&characterEncoding=utf-8&useUnicode=true&serverTimezone=GMT%2B8
username=root
password=



    
    
    
    
        
            
            
                
                
                
                
            
        
    
    
        
    

2.2、SqlSession

其中包含了面向数据库执行sql语句的所有方法

package com.qhit.util;

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;
    //获取sqlSessionFactory对象
    static {
        String resource = "mybatis-config.xml";
        try {
            InputStream stream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获取sqlSession对象
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}
2.3、编写代码 1、实体类
package com.qhit.pojo;

public class User {
    private int id;
    private String usr;
    private String pwd;

    public User() {
    }

    public User(int id, String usr, String pwd) {
        this.id = id;
        this.usr = usr;
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", usr='" + usr + ''' +
                ", pwd='" + pwd + ''' +
                '}';
    }

    public int getId() {
        return id;
    }

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

    public String getUsr() {
        return usr;
    }

    public void setUsr(String usr) {
        this.usr = usr;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}
2、Dao接口
package com.qhit.dao;

import com.qhit.pojo.User;

import java.util.List;
import java.util.Map;

public interface UserMapper {
    List getUsers();          //查询所有

    User getUserById(int id);       //ID查询

    Integer addUser(User user);         //单条插入

    //map传参,参数自定
    Integer addUserByMap(Map map);

    Integer updateUser(User user);      //单条更新

    Integer deleteUserById(int id);     //条件删除

}

3、XML

接口实现类由UserDaoImpl转化为一个Mapper配置文件




    
    
        select *
        from user
        where id = #{id};
    

    
    
        insert into user (id, usr, pwd)
        values (#{id}, #{usr}, #{pwd});
    

    
    
        insert into user (id, usr, pwd)
        values (#{id}, #{username}, #{password});
    

    
    
        update user
        set usr = #{usr},
            pwd = #{pwd}
        where id = #{id}
    

    
    
        delete from user
        where id = #{id};
    

4、Mybatis配置文件中配置Mapper

	

5、测试类
package com.qhit.dao;

import com.qhit.pojo.User;
import com.qhit.util.MybatisUtils;
import junit.framework.TestCase;
import org.apache.ibatis.session.SqlSession;

import java.util.HashMap;
import java.util.Map;

public class UserTest extends TestCase {

    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    public void testGetUsers() {
        for (User user : mapper.getUsers()) {
            System.out.println(user);
        }
    }

    public void testGetUserById() {
        System.out.println(mapper.getUserById(1));
    }

    public void testAddUser() {
        if (0 < mapper.addUser(new User(3, "Test1", "Test1"))) {
            System.out.println("添加成功!");
            sqlSession.commit();
        }
    }

    public void testAddUserByMap() {
        Map map = new HashMap<>();
        map.put("id", 4);
        map.put("username", "Test4");
        map.put("password", "Test4");
        if (mapper.addUserByMap(map) > 0){
            System.out.println("更新成功!");
            sqlSession.commit();
        }
    }

    public void testUpdateUser() {
        if(0 < mapper.updateUser(new User(3, "Test3", "Test3"))){
            System.out.println("添加成功!");
            sqlSession.commit();
        }
    }

    public void testDeleteUserById() {
        if(0 < mapper.deleteUserById(3)){
            System.out.println("删除成功!");
            sqlSession.commit();
        }
    }
}
6、可能遇见的问题 BindingException

问题描述

org.apache.ibatis.binding.BindingException: Type interface com.qhit.dao.UserDao is not known to the MapperRegistry.

解决方案

	在mybatis配置文件中配置Dao
ExceptionInInitializerError

问题描述

java.lang.ExceptionInInitializerError

解决方案
资源过滤问题,在pom文件中加入以下代码

    
       
           
               src/main/resources
               
                   ***.xml
               
               false
           
           
               src/main/java
               
                   ***.xml
               
               false
           
       
   
Cannot find class: com.mysql.jdbc.driver

问题描述

java.sql.SQLException: Error setting driver on UnpooledDataSource. Cause: java.lang.ClassNotFoundException: Cannot find class: com.mysql.jdbc.driver

解决方案
引入mysql依赖,对应数据库版本
查询数据库版本:SELECT VERSION();

	

    mysql
    mysql-connector-java
    8.0.21

Mapper中文报错

问题描述
在mapper.xml中插入中文注释报错
解决方案
将mapper.xml文件上方UTF-8改为UTF8

3、配置解析 3.1、核心配置文件
  • mybatis-config.xml
  • 这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。
configuration(配置)
	properties(属性)
	settings(设置)
	typeAliases(类型别名)
	typeHandlers(类型处理器)
	objectFactory(对象工厂)
	plugins(插件)
	environments(环境配置)
	environment(环境变量)
	transactionManager(事务管理器)
	dataSource(数据源)
	databaseIdProvider(数据库厂商标识)
	mappers(映射器)
3.2、环境配置(Environments)

MyBatis可以配置多种环境
尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

3.3、类型别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:


  

当这样配置时,Blog 可以用在任何使用 domain.blog.Blog 的地方。
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:


  

包下类首字母可以小写,也可以使用注解

@Alias("author")
public class Author {
    ...
}
3.4、其他设置
  • plugins插件
    • mybatis-nenerator-core
    • mybatis-plus
    • 通用mapper
3.5、生命周期和作用域

SqlSessionFactoryBuilder

  • 一旦创建SqlSessionFactory就不被需要
  • 方法作用域
    SqlSessionFactory
  • 可以理解为数据库连接池
  • 一旦创建就一直存在,没有任何理由丢弃或重新创建
  • 应用作用域
  • 最简单的就是使用单例或者静态单例模式
    SqlSession
  • 到连接池的一个请求
  • SqlSession不是线程安全的,因此不能被共享,最佳作用域是请求或方法作用域
  • 用完之后立即关闭,防止资源被占用
4、日志 4.1、日志工厂

如果一个数据库操作出现了异常,我们需要排错,日志就是最好的助手!
曾经:sout、debug
现在:日志工厂

  • LSF4J
  • LOG4J【掌握】
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LONGGING
  • STDOUT_LONGGING【掌握】
  • NO_LONGGING

在Mybatis配置文件中配置我们的日志功能


	

4.2、LOG4J

**什么事LOG4J?

  • Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件
  • 我们可以控制每一条日志的输出格式;
  • 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。
  • 可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
  1. 导包
    
        log4j
        log4j
        1.2.17
    
    
  2. 创建log4j.properties
    #将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
    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=DEBUG
    
4.3、设置setting

	

5、分页 5.1、分页插件PageHelper

1. 引入Maven依赖


     com.github.pagehelper
     pagehelper
     5.1.2

2. 配置SqlSessionFactory工厂


 
 
 
     
         
         
             
                 
                     oracle
                     true
                 
             
         
     
 

6、Association和Collection 6.1、多对一(Association)

多个学生对应一个教师
教师类

import lombok.Data;

@Data
public class Teacher {
    private int id;
    private String name;
}

学生类

@Data
public class Student {
    private int id;
    private String name;
    private Teacher teacher;
}

学生接口

public interface StudentMapper {
    List getStudents();

    Teacher getTeacherById(int id);
}

数据库

CREATE TABLE `student`(
	`id` INT PRIMARY KEY,
	`name` VARCHAR(255) NOT NULL
	`tid` int
);
CREATE TABLE `teacher`(
	`id` INT PRIMARY KEY,
	`name` VARCHAR(255) NOT NULL
);

Mapper.xml配置

方式一:联合查询

    select * from teacher where id = #{id}

方式二:按结果嵌套查询

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

 
     
     
     
     
         
         
         
     
 
方式二:联合查询

    select * from student where tid = #{tid}

8、动态SQL 8.1、if

  SELECT * FROM BLOG WHERe state = ‘ACTIVE’
  
    
      AND title like #{title}
    
    
      AND author_name like #{author.name}
    
    
      AND featured = 1
    
  

8.3、trim、where、set

若将 “state = ‘ACTIVE’” 设置成动态条件


  SELECT *
  FROM POST P
  WHERe ID in
  
        #{item}
  

foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!

提示 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

8.5、bind

bind 元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。比如:


    select
    
    from pub_res_type

9、扩展 9.1、UUID
public static String getID(){
    return UUID.randomUUID().toString().replaceAll("-", "");
}
public static void main(String[] args) {
        System.out.println(getID());
        System.out.println(getID());
        System.out.println(getID());
}

输出

20c5e106ba9d4a9a8d266d25ac1f2489
a893931fa1334bafa031831ba2bb2ab0
db43c936d50f47c5823e4df400cbd070
10、缓存 10.1、简介
查询: 连接数据库,耗资源!
一次查询的结果,给他暂存在一个可以直接取到的地方!-->内存:缓存
我们再次查询相同数据的时候,直接走缓存,就不用走数据库了
  • 什么是缓存[Cache]?
    1. 存在内存中的临时数据
    2. 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
  • 为什么使用缓存?
    1. 减少和数据库的交互次数,减少系统开销,提高系统效率。
  • 什么样的数据能使用缓存?
    1. 经常查询并且不经常改变的数据。
10.2、 Mybatis缓存
  • MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
  • Mybatis默认两级缓存:一级缓存与二级缓存
    • 默认情况下只开启一级缓存(SqlSession级别的缓存,也称本地缓存);
    • 二级缓存需手动配置开启(namespace级别的缓存);
    • 为了提高扩展性,Mybatis提供了Cache缓存接口,我们可以用他来定义二级缓存;
10.3、一级缓存
  • 一级缓存也叫本地缓存:
    • 与数据库同一次会话期间查询到的数据会放在本地缓存中。
    • 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;
  • 映射语句文件中的所有select语句的结果将会被缓存。
  • 映射语句文件中的所有insert, update和delete语句会刷新缓存。
  • 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
  • 缓存不会定时进行刷新(也就是说,没有刷新间隔)缓存会保存列表或对象(无论查询方法返回哪种)的1024个引用。
  • 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
10.4、二级缓存
  • 二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存
  • 基于namespace级别的缓存,一个名称空间,对应一个二级缓存;
  • Mybatis默认开启一级缓存,若要使用二级,只需在mapper.xml中加入cache标签
  • 工作机制
    • 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
    • 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
    • 新的会话查询信息,就可以从二级缓存中获取内容;
    • 不同的mapper查出的数据会放在自己对应的缓存(map)中;
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/592204.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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