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

java学习之Mybatis

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

java学习之Mybatis

Mybatis
  • 1.什么是Mybatis
    • 1.1Mybatis的特性
    • 1.2Mybatis的下载
  • 2.搭建Mybatis
    • 2.1创建maven工程
    • 2.2创建mybatis的核心配置文件
    • 2.3创建Mapper接口
    • 2.4创建Mybatis的映射文件
    • 2.5测试功能CRUD
  • 3.详解核心配置文件(了解)
  • 4.在idea中设置核心配置文件和映射文件的模板
  • 5.Mybatis获取参数值的两种方式(${}和#{})
    • 5.1单个字面量类型的参数
    • 5.2多个字面量类型的参数
    • 5.3map集合类型的参数
    • 5.4实体类类型的参数(掌握)
    • 5.5使用@Param标识参数(掌握)
  • 6.Mybatis的各种查询功能
    • 6.1查询一个实体类对象
    • 6.2查询一个list集合
    • 6.3查询单个数据
    • 6.4查询一条数据为map集合
    • 6.5查询多条数据为map集合
  • 7.特殊SQL的执行
    • 7.1模糊查询
    • 7.2批量删除
    • 7.3动态设置表名
    • 7.4添加功能获取自增的主键
  • 8.自定义映射resultMap
    • 8.1resultMap处理字段和属性的映射关系
  • 9.动态SQL
    • 9.1if
    • 9.2where
    • 9.3trim
    • 9.4choose、when、otherwise
    • 9.5foreach
    • 9.6SQL片段
  • 10.mybatis的缓存
    • 10.1mybatis的一级缓存(SqlSession级别)
    • 10.2mybatis的二级缓存(SqlSessionFactory级别)
    • 10.3二级缓存的相关设置
    • 10.4mybatis缓存查询的顺序(从大到小)
    • 10.5整合第三方缓存EHCache(代替二级缓存)
  • 11.mybatis的逆向工程
    • 11.1创建逆向工程的步骤
    • 11.2mybatis逆向工程奢华尊享版
  • 12.mybatis的分页插件
    • 12.1分页插件的配置
    • 12.2分页插件的使用

参考资料
尚硅谷Mybatis2022版教程

1.什么是Mybatis 1.1Mybatis的特性

1) MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架
2) MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
3) MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java
Objects,普通的Java对象)映射成数据库中的记录
4) MyBatis 是一个 半自动的ORM(对象关系映射)框架
5)轻量级,性能出色
6)SQL 和 Java 编码分开,功能边界清晰。Java代码专注业务、SQL语句专注数据
7)开发效率稍逊于HIbernate,但是完全能够接受

1.2Mybatis的下载

下载地址:
mybatis下载
点开链接后往下拉

选择第一个下载

下载后解压即可,里面的pdf是官方文档,建议收藏,jar包可以通过maven下载,所以用不到。

2.搭建Mybatis 2.1创建maven工程

新建一个空的project,在Settings中找到maven,修改idea自带的maven为你的本地maven

a>打包方式:jar
b>引入依赖


        
        
            org.mybatis
            mybatis
            3.5.7 
        
        
            junit
            junit
            4.12
            test 
        
        
            mysql
            mysql-connector-java
            5.1.3
        
    
2.2创建mybatis的核心配置文件

习惯上命名为mybatis-config.xml,这个文件名仅仅只是建议,并非强制要求。将来整合Spring之后,这个配置文件可以省略,所以大家操作时可以直接复制、粘贴。
核心配置文件主要用于配置连接数据库的环境以及MyBatis的全局配置信息 核心配置文件存放的位置是src/main/resources目录下

a)官方文档中配置信息的位置




    
    
        
            
            
            
            
                
                
                
                
            
        
    
    
    
        
    

2.3创建Mapper接口

MyBatis中的mapper接口相当于以前的dao。但是区别在于,mapper仅仅是接口,我们不需要提供实现类。

a)在数据库中创建一张表

b)创建对应的实体类*

public class User {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private String sex;
    private String email;
}

c)创建Mapper接口(即原来的Dao)

public interface UserMapper {
}
2.4创建Mybatis的映射文件

相关概念:ORM(Object Relationship Mapping)对象关系映射。
对象:Java的实体类对象
关系:关系型数据库
映射:二者之间的对应关系

1、映射文件的命名规则:
表所对应的实体类的类名+Mapper.xml
例如:表t_user,映射的实体类为User,所对应的映射文件为UserMapper.xml
因此一个映射文件对应一个实体类,对应一张表的操作
MyBatis映射文件用于编写SQL,访问以及操作表中的数据
MyBatis映射文件存放的位置是src/main/resources/mappers目录下
2、MyBatis中可以面向接口操作数据,要保证两个一致:
a>mapper接口的全类名和映射文件的命名空间(namespace)保持一致
b>mapper接口中方法的方法名和映射文件中编写SQL的标签的id属性保持一致

下面假设有一个UserMapper(即UserDao),中有一个添加的方法,方法名为:insertUser
那么我们的映射文件(UserMapper.xml)中的对应关系为





    
    
        insert into t_user values (null,'admin','123456',23,'男','12345@qq.com')
    

在mybatis配置文件中引入映射文件


2.5测试功能CRUD

a)添加功能
在上文,我们已经简历好了映射关系,接下来我们来测试添加功能

public class Test {
    @org.junit.Test
    public void testMybatis() throws IOException {
        //加载核心配置文件
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //获取SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //获取SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
        //获取mybatis操作数据库的会话对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取Mapper接口的实现类对象,这个方法底层用了代理模式,可以返回一个接口的实现类对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //测试功能
        int result = mapper.insertUser();
        System.out.println(result);
        //提交事务
        sqlSession.commit();
    }
}

SqlSession:代表Java程序和数据库之间的会话。(HttpSession是Java程序和浏览器之间的会话)
SqlSessionFactory:是“生产”SqlSession的“工厂”。
工厂模式:如果创建某一个对象,使用的过程基本固定,那么我们就可以把创建这个对象的相关代码封装到一个“工厂类”中,以后都使用这个工厂类来“生产”我们需要的对象。

我们也可以优化上面的代码,改为自动提交:
只需要修改一处,加上一个参数true

SqlSession sqlSession = sqlSessionFactory.openSession(true);

b)加入log4j日志功能
加入依赖

        
        
            log4j
            log4j
            1.2.17
        

加入log4j的配置文件
log4j的配置文件名为log4j.xml,存放的位置是src/main/resources目录下




    
        
        
            
        
    
    
    
        
        
        
    
    
        
    
    
        
        
    

下面是添加功能输出的日志信息

c)修改和删除功能
流程:先写Mapper接口中的方法,再去映射文件中写sql语句
接口对象中的

    
    void updateUser();

    
    void deleteUser();

映射文件UserMapper.xml中的

    
    
        update t_user set username='张三' where id=3
    

    
    
        delete  from t_user where id=5
    

d)查询功能
接口对象中的

    
    User getUserById();

    
    List getAllUser();

映射文件UserMapper.xml中的

    
    
    
    
    
        select * from t_user;
    
3.详解核心配置文件(了解)

核心配置文件中的标签必须按照固定的顺序:
properties?,settings?,typeAliases?,typeHandlers?,
objectFactory?,objectWrapperFactory?,reflectorFactory?,
?,environments?,databaseIdProvider?,mappers?

a)environment

environments:配置多个连接数据库的环境
属性:
default:设置默认使用的环境的id

environment(在environments中):配置某个具体的环境
属性:
id:表示连接数据库的环境的唯一标识,不能重复
transactionManager:事务管理方式,type有JDBC(表示当前环境中,执行SQL时,使用的是jdbc中原生的事务管理方式),MANAGED(被管理,例如spring)
dataSource:配置数据源,type有POOLED(表示使用数据库连接池缓存数据库连接),UNPOLLED(表示不使用数据库连接池),JNDI(表示使用上下文中的数据源)

b)properties

properties配置文件,是以键值对的形式存储数据的,为了properties文件内容重复,我们可以在键值对前加上一个前缀来区分功能。

在mybatis核心配置文件中引入properties文件


通过该文件中的键值对来配置数据库

                
                
                
                
                
                

c)typeAliases

类型别名,根据类型顺序,应该放在properties之后,注意别名不区分大小写

    
    
        
        
        
    

另一种更简洁的方式

    
    
    
        
    

d)mappers

此标签用于引入映射文件
在前面的CRUD中已经介绍了单独引入映射文件的方法
下面介绍一种以包为单位的引入方法,引入mapper包下的所有映射文件

    
        
        
        
    
4.在idea中设置核心配置文件和映射文件的模板

我们可以自己设置一个文件模板,以防止重复劳动
核心配置文件
点击settiings,找到如图选项,点击加号


随后,右键new就可以创建一个我们配制好的文件的模板

映射文件

和配置文件一样的流程,这里就不再多介绍了

5.Mybatis获取参数值的两种方式(${}和#{})

5.1单个字面量类型的参数

若mapper接口中的方法参数为单个的字面量类型
此时可以使用${}和#{}以任意的名称获取参数的值,注意${}需要手动加单引号

    
    
        
        select * from t_user where username=#{arg0} and password=#{arg1}
        
        select * from t_user where username='${arg0}' and password='${arg1}'
    
5.3map集合类型的参数

若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合,将这些数据放在map中只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号,写法与5.2类似,只不过键值对变成了我们自己定义的。

5.4实体类类型的参数(掌握)

若mapper接口中的方法参数为实体类对象时此时可以使用${}和#{},通过访问实体类对象中的属性名获取属性值,注意${}需要手动加单引号,这里底部是用set和get方法实现的。

    
    
        insert into t_user values (null,#{username},#{password},#{age},#{sex},#{email})
    
5.5使用@Param标识参数(掌握)

可以通过@Param注解标识mapper接口中的方法参数
此时,会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值;或以param1,param2…为键,以参数为值;只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号
其实就是使用mybatis自定义map集合中的键,且5.1,5,2,5.3都可以用此方法代替

mapper接口中的代码

    
    User checkLoginByParam(@Param("username") String username, @Param("password") String password);

映射文件中的sql语句

    
    
        select * from t_user where id = #{id}
    
6.2查询一个list集合

若查询出的数据有多条,可以用list接受,一定不能用实体类接受

    
    
        select count(*) from t_user
    
6.4查询一条数据为map集合
    
    
        select * from t_user
    

注意,此时每一条数据都会变成一个类似于6.4中的map集合,所以我们方法的返回值不能为Map
a)用List实体类进行接收

List> getAllUserToMap();

b)在mapper接口的方法上,使用MapKey注解

    @MapKey("id")//把查询出来的某个字段作为键,把对应的map作为值,这里就是以id作为键,放在同一个map集合中,注意,字段需要唯一
    Map getAllUserToMap();
7.特殊SQL的执行 7.1模糊查询
    
    
        
        select * from ${tableName}
    
7.4添加功能获取自增的主键

t_clazz(clazz_id,clazz_name)
t_student(student_id,student_name,clazz_id)
1、添加班级信息
2、获取新添加的班级的id
3、为班级分配学生,即将某学的班级id修改为新添加的班级的id

    
    
        insert into t_user values (null,#{username},#{password},#{age},#{sex},#{email})
    

测试代码

        User user = new User(null,"王五","123",23,"男","1234@qq.com");
        sqlMapper.insertUser(user);
        //此时自动递增的主键已经被放在了id属性中
        System.out.println(user.getId());
8.自定义映射resultMap

若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射

8.1resultMap处理字段和属性的映射关系

a)通过字段名别名

    
    
        select * from t_emp
    

d)通过级联属性赋值解决多对一的映射关系(第一种方式)
假设有两个类,emp与dept,一个emp对应一个dept,一个dept对应多个emp
emp中:

private Dept dept;

现在假设有一个方法getEmpAndDept,我们希望查询出一个emp对应的dept信息

    
    
        
        
        
        
        
        
        
        
    
    
    
        select * from t_emp left join t_dept on t_emp.did = t_dept.did where t_emp.eid=#{eid}
    

e)通过分步查询解决多对一的映射关系(第三种方式,重点掌握)

    
    
    
        
        
        
        
        
        
        
    
    
    
        select * from t_dept where did=#{did}
    

分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:
lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载(只访问员工就只查询员工,不会再执行第二步的查询部门信息),在settings标签下
aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。 否则,每个 属性会按需加载
此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时可通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType="lazy(延迟加载)|eager(立即加载)

延迟加载的效果如下

f)通过collection解决一对多映射关系
一个部门dept,对应多个员工emp,dept中如下

  private List emps;

查询一个部门和其所有员工的信息:

    
    
        
        
        
        
            
            
            
            
            
        
    
    
    
        select * from t_dept where did = #{did}
    

第二步查员工

    
    
        select * from t_emp where 1=1
        
            and emp_name = #{empName}
        
        
            and age = #{age}
        
        
            and sex = #{sex}
        
        
            and email = #{email}
        
    

假设我们的方法传入参数为:

List list = mapper.getEmpByCondition(new Emp(null,null,23,"男","123@qq.com"));

经过拼接的sql语句为

9.2where

where和if一般结合使用:
a>若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字
b>若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的and去掉
注意:where标签不能去掉条件最后多余的and

    
    
    
        select * from t_emp
        
        
            
                emp_name = #{empName} and
            
            
                age = #{age} or
            
            
                sex = #{sex} and
            
            
                email = #{email}
            
        
    
9.4choose、when、otherwise

choose、when、otherwise相当于if…else if…else