Mybatis最佳教学教程入门笔记

一、Mybatis简介

1、Mybatis执行步骤

  • 读取配置文件mybatis-config.xml,主要是获取数据库连接和运行环境信息
  • 加载映射文件mapper.xml,也就是sql映射文件,需要在mybatis-config.xml中加载才能被执行。
  • 创建SqlSessionFactory
  • 根据SqlSessionFactory创建SqlSession
  • 使用SqlSession对象操作数据库,包括增删改查和事务提交
  • 关闭SqlSession

二、Mybatis与Maven整合

1、Maven 依赖

        
            org.mybatis
            mybatis
            3.5.9
        

        
            mysql
            mysql-connector-java
            8.0.27
        

2、mybatis配置文件

src/man/resources/mybatis-config.xml




    
    
        
            
            
                
                
                
                
            
        
    
    
    
        
        
        
        
    

3、工具类

package org.example.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;

    static {
        try {
            // 获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 获取SqlSession实例,SqlSession包含了面向数据库执行SQL命令所需的所有方法
    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession(true);
    }
}

4、Mapper接口

package org.example.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.example.model.SjddSjsctz;
import java.util.List;

@Mapper
public interface SjddSjsctzMapper {

    List selectAll();

}

5、Mapper.xml



    
    

    


6、mapper读取数据

    @Test
    public void testMybatis() {

        // 第一步:获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        // 第二部:getMapper
        SjddSjsctzMapper sjddSjsctzMapper = sqlSession.getMapper(SjddSjsctzMapper.class);

        for (SjddSjsctz sjddSjsctz : sjddSjsctzMapper.selectAll()) {

            System.out.println(sjddSjsctz);
        }
        
        // 第三步:关闭SslSession
        sqlSession.close();
    }

三、简单CURD操作

1、增、删、改、查 示例


    // 一、查询:可以传bean、map、@param修饰的一个或多个参数、顺序传的单个或多个参数
    List selectAll();


    // 二、插入:可以传bean、map、@param修饰的一个或多个参数、顺序传的单个或多个参数
    // id自增,可以手动指定一个id传进去,也可以不传
    int insertOne(Map map);

2、模糊查询

两种方式

// Java代码里的模糊查询参数,传递通配符%%
List userList = mapper.getUserLike("%李%");
select * from user where username like '#{username}';


List userList = mapper.getUserLike("李");
select * from user where username like concat('%',#{username},'%');

3、批量插入

    @Test
    public void testInsert() throws Exception {

        SqlSession sqlSession = MybatisUtils.sqlSessionFactory.openSession(ExecutorType.BATCH);
        SjddSjsctzMapper mapper = sqlSession.getMapper(SjddSjsctzMapper.class);

        for (int i = 0; i < 10; i++) {
            User user = new User();
            user.setUsername(UUID.randomUUID().toString());
            user.setPassword(UUID.randomUUID().toString());
            mapper.insertMany(user);

        }

        sqlSession.commit();

    }

4、返回自增主键

当使用insert或update语句时,返回语句影响记录的自增主键值。

  • useGenerateKeys="true/false"这回让MyBatis使用JDBC的getGenerateKeys方法,来取出由数据库内部生成的主键,默认false。如果设置为 true,将强制使用自动生成主键。
  • keyProperty="id",指定返回自增主键的值,将自增主键值赋予入参值实体类的id属性。
        User user = new User();
        user.setUsername("username");
        user.setPassword("password");
        user.setRoles("roles");
        user.setEnable((byte) 1);

        int i = mapper.insertOne(user);

        System.out.println(i);
        System.out.println(user.getId());  // 得到返回的主键
    
        int insertOne(User user);

    
    -- 将主键返回给传来的user对象的id属性
    
        insert into user(username, password,enable, roles)
        values (#{username}, #{password}, #{enable}, #{roles});
    

5、SQL执行结束的返回值

  1. insert、delete、update语句:

用int返回类型,返回执行的SQL语句影响的记录条数,若果是0则表示没有做更改。

  1. select语句的返回值类型如下:

使用查询语句执行后,数据库返回的实际类型。

  • List/map
  • javabean
  • resultMap

6、mapper.xml接收的参数类型

(1)parameterType

  1. 接收单个参数,参数类型为基本类型/包装类型时,mapper.xml里的参数名可以随便写都能取到值:#{xx}
  2. 接收多个参数,参数类型为基本类型/包装类型时,写入对应的参数名;或者按照顺序写#{0}...#{n}
  1. 接收map、或实体类,mapper.xml里的参数名要和map的key或实体类里的属性名相对应。
int addUser(Map);


    insert into sjdd_sjsctz (id, name, password) values(#{name},#{password}) ;


Map map = new HashMap();
map.put("name", "admin");
map.put("password", "123456");

mapper.addUser(map);

(2)parameterMap

用的比较少

7、mapper.xml返回的参数类型

这里的返回参数,一般是select语句用到的返回数据的参数类型。

(1)resultType

  1. 返回实体类
  1. 返回map
  1. 单字段返回基础类型

(2)resultMap

简单用法是解决表字段与实体类属性不一致的问题。

  1. 方式一:查询语句起别名
    
  1. 方式二:返回值类型设置成:resultMap
    
    
          
    

    

四、复杂查询

1、动态SQL

(1)if


(2)foreach

  • 查询

  • 批量插入
        ArrayList users = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            User user = new User();
            user.setUsername(UUID.randomUUID().toString());
            user.setPassword(UUID.randomUUID().toString());
            users.add(user);
        }

        int i = mapper.insertMany(users);
        System.out.println(i);
 
 
    int insertMany(List list);
    
        insert into user(username, password) values
        
            (#{item.username}, #{item.password})
        
    

(3)choose、when、otherwise


(4)set

待补充。。。。

2、多表查询

多表查询,xml里返回类型需要用resultMap,自定义返回的字段,对一使用association,对多使用collection。实体类里要加入对一的属性。

  • 关联-association【对一】
  • 集合-collection 【对多】

javaType 用来指定实体类中属性的类型
ofType 用来指定映射到List或集合中的pojo类型,泛型中的约束类型

(1)一对一

一对一的,使用resultMap和association。可以对javabean添加属性也可以

  1. 假设一个Article对应一个Author,Article里存放Author的id。在Article的实体类里,增加Author。
@Data
public class Article {

    private String articleId;
    private String title;
    private Integer authorId;

    // 加入需要关联的实体类
    private Author author;
}
  1. 编写resultMap
    
        
        
        
        
        
        
        
            
            
        
    
  1. 编写查询语句
    

(2)一对多

  1. 一的实体类
@Data
public class Article {

    private String articleId;
    private String title;
    private Integer authorId;

    // 加入需要关联的实体类
    private Author author;

    // 需要关联的一对多的评论
    private List remarks;
}


  1. resultMap
    
        
        
        

        
            
            
        

        
            
            
            
        
    
  1. SQL语句
    
  1. 查询结果

[Article(articleId=1, title=葵花宝典, authorId=1, author=Author(id=1, author=黄药师), remarks=[Remark(id=1, cont=良心教程, articleId=1)])]

除了使用resultMap + collection外,也可以在程序中进行多次查询。

(3)多对一

待补充。。。。

五、mybatis-config.xml 配置

1、属性(properties)

这些属性可以在外部进行配置,并可以进行动态替换。既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。例如:

mybatis-config.xml

    
    







    
    
        
            
            
                
                
                
                
            
        
    

database.properties (注意,数据库名用中文报错)

driver = "com.mysql.cj.jdbc.Driver"
url = "jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8"
username = "root"
password = "root"

2、类型别名(typeAliases)

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

  1. 单个别名分别配置:

  
  

  1. 扫描包整个model包

会使用包内 Bean 的首字母小写的非限定类名来作为它的别名,首字母大写也支持。有注解则优先使用注解

    
        
        
    
  1. 注解:@Alias("xxx")
@Alias("author")
public class Author{
    ...
}

配置完别名之后,才能将resultType="com.example.Modle.Author" 变为 resultType="Author"

3、设置(settings)

(1)驼峰命名转换

默认false,不进行转换。开启后将数据库字段的column_table与实体类的columnTable进行自动对应,这样查出来的数据才能赋给实体类。

    
        
    

(2)日志打印

  1. STDOUT_LOGGING
    
        
    
image.png

image.png
  1. LOG4J

(3)字段为null时处理

默认false,当查询一条记录,某个字段为null时,是否调用映射对象的 setter(map 对象时为 put)方法,默认mybatis不会处理这一字段,也就是不会调用null赋值给返回的对象。

    
        
    

(4)返回null的处理

默认false,当查询到记录,但返回行的所有列都是null时,MyBatis默认返回 null对象,而不会创建返回对象,当调用返回对象的方法时,容易导致空指针错误。
当开启这个设置时,MyBatis会创建返回对象,但对象是一个null实例,返回的实体类对象的所有属性都是null。

    
        
    

注意:如果表为空,或者根据条件查找不到记录,必定会返回null或空列表[]
上述设置只适用于,当mybatis查找到了表记录,但是返回的列全是null的时候。如果返回的列,不是全部为null,则会正常创建返回对象。

六、缓存

1、一级缓存:

默认开启,存在于SqlSession的生命周期中,什么是SqlSession的生命周期呢,简单的来说,只有同一个请求才会是同一个SqlSession,那么就是说只有同一个请求我查询第二次这个缓存才会生效。

2、二级缓存:

也称为全局缓存,存在于SqlSessionFactory 的生命周期中,可以理解为跨sqlSession;缓存是以namespace为单位的,不同namespace下的操作互不影响,但是在多人开发的环境下,我的不同的namespace完全是有可能操作同一张表的,那么会导致一个namespace的数据修改了一张表,但是另一个namespace的那张表的数据缓存没被修改,这样查询的数据就会错误。

  • 开启方式:在Mapper.xml里添加即可

七、使用注解开发

@select("select * frome user")
List getUsers();

@select("select * from user where id = #{id}")
User findById(@Param("id") long id);

@Insert("insert into user(id,name,password) values(#{id},#{name},#{password})")
int addUser(User user);

@Update("update user set name=#{name},password=#{password} where id = #{id}")
int updateUser(User user);

@Delete("delete from user where id = #{id}")
int delete(@Param("uid") int id);

mybatis-config.xml



  

八、Mybatis与Spring整合

待补充。。。。

九、Mybatis与SpringBoot整合

待补充。。。。

你可能感兴趣的:(Mybatis最佳教学教程入门笔记)