创建一个简单的Mybatis项目


一、创建一个简单的Mybatis项目

浅说一下mybatis的原理(目前理解):代替了原来Dao层(数据持久层)每次使用都需要connection连接数据库的操作,使用xml文件的方式,配置一次数据库的连接,之后使用Dao层的方法不再需要专门连接;同时将Dao层中实现接口的方法(sql语句)改用为xml文件实现

1.mybatis在线文档

https://mybatis.net.cn/getting-started.html

2.创建一个Maven项目

3.在pom.xml加入Maven依赖




    org.mybatis
    mybatis
    3.5.9





    mysql
    mysql-connector-java
    8.0.28





    org.junit.jupiter
    junit-jupiter-api
    5.8.2
    test


4.在resource中创建mybatis配置文件



<?xml version="1.0" encoding="UTF-8" ?>


  
    
      
      
          
          
        
          
        
        
        
          
      
    
  
    
    
     

5.整体包的结构如下

6.接下来创建utils包和MybatisUtils类

MybatisUtils类的作用是利用SqlSessionFactory创建一个SqlSession类,用于操作之后接口中的方法

package com.Gw.utils;

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;
/*
	简单来说只用三句话,意思是从resource资源文件中以流形式得到xml配置文件,创建SqlSessionFactory,并创建SqlSession
	String resource = "mybatis-config.xml";
	InputStream inputStream = Resources.getResourceAsStream(resource);
	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
*/
    static {
        //此处填写刚才的配置文件
        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

7.编写Dao层

先说明一下实体类包pojo中的User类,实际由id、name、pwd组成,有对应的set、get方法和构造函数

本文省略了与数据库连接的部分,与数据库中数据的创建,给实例图读者自行创建、连接

在UserMapper中创建sql语句的接口

package com.Gw.dao;

import com.Gw.pojo.User;
import java.util.List;

public interface UserMapper {
    List getUserList();
    //根据id查询用户
    User getUserById(int id);

    //插入用户
    void addUser(User user);

    //修改用户
    int updateUser(User user);

    //删除一个用户
    int deleteUser(int id);
}

在UserMapper.xml中实现对应的sql查询

<?xml version="1.0" encoding="UTF-8" ?>




    
    
    
    
        insert into mybatis.user(id, name, pwd) values (#{id}, #{name}, #{pwd});
    
    
        update mybatis.user set name =#{name},pwd=#{pwd} where id = #{id};
    
    
        delete from mybatis.user where id=#{id}
    







8.测试执行

在test包中创建与main包中的相同结构,创建UserMapperTest类,具体参考5

使用junit进行测试

说明:在使用UserMapper中的方法时,需要先通过MybatisUtils创建SqlSession,再利用SqlSession通过UserMapper的接口获得mapper映射,之后就可以通过mapper对象调用UserMapper中的方法

package com.Gw.Dao;

import com.Gw.dao.UserMapper;
import com.Gw.pojo.User;
import com.Gw.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.jupiter.api.Test;

import java.util.List;

public class UserMapperTest {

    @Test
    public void test(){
        //第一步:获取SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //第二步:执行sql语句
        //方法一:getMapper
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List userList = mapper.getUserList();

        //方法二:不推荐
        List list = sqlSession.selectList("com.Gw.dao.UserDao.getUserList");

        for (User user : userList) {
            System.out.println(user.getId() + " " + user.getName() + " " + user.getPwd());
        }
        sqlSession.close();
    }
    @Test
    public void getUserById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        System.out.println(mapper.getUserById(1).getName());
    }
    @Test
    public void addUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setId(4);
        user.setName("小芳");
        user.setPwd("123456");
        mapper.addUser(user);

        //提交事务,修改完一定要提交事务
        sqlSession.commit();

        sqlSession.close();
    }
    @Test
    public void updateUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.updateUser(new User(1,"李华","456789"));
        sqlSession.commit();
        sqlSession.close();
    }
    @Test
    public void deleteUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.deleteUser(2);
        sqlSession.commit();
        sqlSession.close();
    }
    @Test
    public void getUserLike(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List userLike = mapper.getUserLike("%李%");
        for (User user : userLike) {
            System.out.println(user.getName() + " " + user.getPwd());
        }
        sqlSession.close();
    }
}

二、配置解析

在config-mybatis.xml中必须按照此顺序设置
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
    environment(环境变量)
        transactionManager(事务管理器)
        dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)

1.environment

1.事务管理器(transactionManager)

在Mybatis中有两种类型的事务管理器,JDBC和MANAGED

  • JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
  • MANAGED – 这个配置几乎没做什么。

如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器,因为 Spring 模块会使用自带的管理器来覆盖前面的配置。

2.数据源(dataSource)

  • POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这种处理方式很流行,能使并发 Web 应用快速响应请求。
  • UNPOOLED– 这个数据源的实现会每次请求时打开和关闭连接。虽然有点慢,但对那些数据库连接可用性要求不高的简单应用程序来说,是一个很好的选择。 性能表现则依赖于使用的数据库,对某些数据库来说,使用连接池并不重要,这个配置就很适合这种情形。
  • JNDI – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用。

2.属性(properties)

  • 可以引入外部文件db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&userUnicode=true&characterEncoding=UTF-8
username=root
password=123456

使用时需在mybatis-config.xml加入properties标签




  • 可以在xml中插入properties标签

	

  • 当二者都存在时,先使用外部配置文件

3.类型别名(typeAliases)

简化使用实体类中的类名



    




    

在实体类比较少的时候使用第一种,多的时候使用第二种;

第一种可以自定义别名,第二种自定义别名则需要在实体上加注解

@Alias("user")
public class user{}

4.设置(settings)

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。

重点掌握

设置名 描述 有效值 默认值
cacheEnabled 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 true | false true
lazyLoadingEnabled 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 true | false false
useGeneratedKeys 允许 JDBC 支持自动生成主键,需要数据库驱动支持。如果设置为 true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作(如 Derby)。 true | false False
logImpl 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING 未设置

5.其他配置

typeHandlers(类型处理器)
objectFactory(对象工厂)

插件(plugin)

  • mybatis-generator-core
  • mybatis-plus-boot-starter
  • 通用mapper

6.映射器(mappers)

1.原始方式


    

2.使用class的文件绑定注册


	

3.通过package


	

注意:2、3的接口和它的Mapper配置文件必须同名并且接口和它的配置文件必须在一个包下

7.作用域和生命周期

不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。

SqlSessionFactoryBuilder

  • 一旦创建了 SqlSessionFactory,就不再需要它了
  • 局部变量

SqlSessionFactory

  • 可以想象成数据库连接池

  • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。

  • SqlSessionFactory 的最佳作用域是应用作用域。

  • 在应用运行期间不要重复创建多次有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。

SqlSession

  • 每一个独享一个线程,与连接池连接

  • 每个线程都应该有它自己的 SqlSession 实例。

  • 它的最佳的作用域是请求或方法作用域。

  • 考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它

总结:

mapper就相当于一个业务

三、解决实体类和数据库名字不一致的问题

pojo中为password

数据库中为pwd

解决方法:

  • 起别名

结果集映射(resultMap)简介

  • resultMap 元素是 MyBatis 中最重要最强大的元素。
  • ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。