Mybatis使用入门,这一篇就够了

mybatis中,封装了一个sqlsession 对象(里面封装有connection对象),由此对象来对数据库进行CRUD操作。

运行流程

mybatis有一个配置的xml,用于配置数据源、映射Mapping,xml的文件名可以任取,为了方便,我们还是起mybatis-config.xml

我们读取此配置的xml,获得一个sqlsession,之后由此对象类进行数据库的CRUD操作

Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSession sqlSession = factory.openSession();

入门使用

1. 创建实体类和Dao类

2. 配置mybatis-config.xml文件,配置数据源




    
    

    
    
        
            
            
            
            
                
                
                
                
                
            
        
    

3. 定义连接数据库工具,可以获得sqlsession对象

Dao类中每次进行CRUD操作,都要执行一次openSession方法来获得SqlSession对象,造成资源的浪费和代码的重复

所以,和之前的JdbcUtil工具类一样,我们也定义定义一个工具类MyBatisUtil,用来返回SQLSession对象

static SqlSessionFactory sqlSessionFactory = null;

static {
    try {
        // 加载mybatis配置文件,并创建SqlSessionFactory实例
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //这个build方法可以接受几种不同的参数,如Reader/InputSteam等
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    } catch (IOException e) {

    }
}

public static SqlSession getSqlSession() {
    return sqlSessionFactory.openSession();
}

public static void closeSqlSession(SqlSession sqlSession){
    if (sqlSession != null) {
        sqlSession.close();
    }
}

4. sql语句写在mapper中

mapper文件放在了resources下面

Mybatis使用入门,这一篇就够了_第1张图片

Mybatis中,sql语句则是写在了xml文件中,这些xml文件也称为mapper映射文件

mapper标签如果带有xmln属性,IDEA会报解析xml错误,得把xmln属性删除





    
    

5. 在mybatis-config.xml文件中注册mapper




    
    
        
        
    

6. dao类通过sqlsession进行查询

SqlSession sqlSession = MybatisUtil.getSqlSession();
// 调用语句,如果有参数,传入参数 
//参数为命名空间namespace+id,执行xml中的sql语句
List list = sqlSession.selectList("employeeMapper.selectAll");

PS:如果是插入、更新和删除操作,还需要提交操作,默认是不会自动提交的

sqlSession.commit();

补充

1.typeAliases标签

resultType属性需要全类名,我们可以使用typeAliases标签来简化输入

typeAliases标签需要在mybatis-config.xml文件中进行设置




    
    
    
        
    
    

之后我们的mapper文件中就可以这样写


我这里只介绍用法,详解请看下面的参考链接

参考 MyBatis 配置 typeAliases 详解

2.引入mapper的四种方法

1. 文件路径注册


    

2. 包名扫描注册


    

使用这种,必须保证xxxMapper.java和xxxMapper.xml两者名字一模一样!而且是要在同一包里

3. 类名注册


    

4. url注册


    

参考:配置MyBatis时报错信息的解决方案

SQLSession方法说明

方法名 说明
insert 插入
delete 删除
update 更新
selectOne 查找单行结果,返回一个Object
selectList 查找多行结果,返回一个List

使用和之前一样,第一个参数传入一个namespce+id,就可以找到指定的mapper文件里面的sql语句,并执行

CRUD

查询

Employee中,属性名和表的列名对应

如果属性和表的列名不一致,可以使用列名映射resultMap标签,(也就是自动转为别名)



    
    
    
    
    
    
    
    
    


带条件查询



//使用
Employee e = sqlsession.selectOne("employeeMapper.selectById",7369);

上面的select语句相当于一个预编译语句

String s = "SELECT * FROM employee WHERE empno=?";
PreparedStatement ps = conn.prepareStatement(s);
ps.setInt(1,empno);

多条件查询

可以使用where标签,当然,之前的单条件也可以使用where标签,where标签好处是会自动删除多余的and

大小比较条件

条件中有大小比较,<号得通过CDATA存放条件

#与$区别:

${}用在我们能够确定值的地方,也就是我们程序员自己赋值的地方。
#{}一般用在用户输入值的地方!!

参考:
MyBatis中#{}和\({}的不同和\){}的妙用

模糊查询:

模糊查询中需要使用%等通配符,我们可以在xml中定义好,自动拼接通配符

动态查询

Mybatis中提供了if标签用来实现动态查询,和JSTL标签库使用类似

插入

主键为序列

某个主键是由oracle中的序列生成的


    
    
    
        select EMP_SEQ.nextval from dual
    
    
    
    insert into EMPLOYEE
    values (#{empno},#{ename},#{job},#{mgr,jdbcType=INTEGER},#{hiredate,jdbcType=DATE},#{sal,jdbcType=DOUBLE},#{comm,jdbcType=DOUBLE},#{deptno,jdbcType=INTEGER})

复用sql语句

把insert要插入的列名和数值写在sql标签里,之后方便重用,之后重用的时候需要使用include子标签拼接sql语句




    
    
        empno,
        ENAME,
        JOB,
        MGR,
        HIREDATE,
        SAL,
        COMM,
        DEPTNO,
    



    
        #{empno},
        #{ename},
        #{job},
        #{mgr},
        #{hiredate},
        #{sal},
        #{comm},
        #{deptno},
    



    
        select EMP_SEQ.nextval from dual
    
    insert into EMPLOYEE 
    
     
    

更新


    update EMPLOYEE
    
        ENAME=#{ename},
        JOB=#{job},
        MGR=#{mgr},
        HIREDATE=#{hiredate},
        SAL=#{sal},
        COMM=#{comm},
        DEPTNO=#{deptno},
    
   
   where EMPNO=#{empno}

    update EMPLOYEE
    
        ENAME=#{ename},
        JOB=#{job},
        MGR=#{mgr},
        HIREDATE=#{hiredate},
        SAL=#{sal},
        COMM=#{comm},
        DEPTNO=#{deptno},
    
   
   where EMPNO=#{empno}

删除


    delete EMPLOYEE EMPNO=#{empno}
    

w3c select标签、delete标签等详解

高级使用

1.动态代理

我们之前,上面都是在Dao类中写上一段sqlsession.selectOne/selectList,还是比较麻烦

所以mybatis提供了一种简单的方法,使用动态代理(接口类)可以简化步骤

Mybatis中有这样的约定:

  1. 接口方法名与mapper中的id相同
  2. 接口方法参数与parameterType类型相同
  3. 接口方法的返回值类型与resultType类型相同

满足上面的条件,Mybatis就会将接口类中的方法和mapper中的sql语句一一对应起来,而不需要再次新建一个Dao,在Dao类里面编写方法

具体步骤:

1. 实体类编写

2. 新建接口类

如果方法的返回值为void,则mapper中就不需要定义resultType属性

如果方法返回值是List,mapper中的resultType为泛型T

package com.wan.mapping;

import com.wan.bean.Employee;

import java.util.List;

/**
 * @author StarsOne
 * @date Create in  2019/9/16 0016 20:38
 * @description
 */
public interface EmployeeMapper {
    List selectAll();
}

2. 编写mapper.xml




    
    

3. 注册mapper

这里我们由于使用了package注册mapper,一定保证xxmapper.java和xxmapper.xml两个名字相同,大小写都要一样

保证Mapper.xml和接口的那个Mapper在相同的包路径,在mybatis配置xml文件指定




    ...
    
    
        
        
    

4. 使用

使用还是和之前一样,获得SqlSession对象,此对象有个getMapper方法,把接口类传入,就可以回调接口的方法了

Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSession sqlSession = factory.openSession();

EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
List employees = mapper.selectAll();

接口类中的方法名与EmployeeMapper.xml中的对应

使用:

EmployeeMapper mapper = sqlsession.getMapper(EmployeeMapper.class);
mapper.selectById(7369);

2.遍历列表

Mybatis中提供了foreach标签,用于遍历

如果方法参数传入了一个List,可以使用此标签遍历,例子如下:


foreach标签的属性主要有 item,index,collection,open,separator,close,使用和JSTL标签里面的foreach标签差不多

属性名 说明
item 表示集合中每一个元素进行迭代时的别名
index 指定一个名字,用于表示在迭代过程中,每次迭代到的位置,
open 表示该语句以什么开始,
separator 表示在每次进行迭代之间以什么符号作为分隔 符,
close 表示以什么结束。

关键属性:collection

  1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
  2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
  3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key

参考:mybatis 中 foreach collection的三种用法

3.考虑线程安全

使用ThreadLocal对象,保证每个线程取出的SqlSession是同一个对象

方法 说明
void set(Object value) 设置当前线程的线程局部变量的值。
public Object get() 该方法返回当前线程所对应的线程局部变量。
public void remove() 将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。
protected Object initialValue() 返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。
static ThreadLocal threadLocal = new ThreadLocal();
//设置
threadLocal.set(sqlsession);
//取出
SqlSession s = threadLocal.get();

4.嵌套查询



    
    
    
    
    
    
    
    
    




    
        
        
        
        
    








    




5.分页查询

分页的话,像以前那样使用三层嵌套查询也可以实现。

不过,有开发者为Mybatis开了个一个插件PageHelper,可以用来更为简单地使用分页查询

1.添加jar包


    com.github.pagehelper
    pagehelper
    
    REALSE

2.配置拦截器插件



    
    
        
        
    

3.代码使用

只有在查询之前调用过startPage或者是offsetPage方法,后面的查询出来的List结果就会进行分页查询

下面的两个都是查询第一页,每一页有10条数据

//第二种,Mapper接口方式的调用,推荐这种使用方式。

PageHelper.startPage(1, 10);
List employees = employeeMapper.selectAll();

//第三种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.offsetPage(1, 10);
List employees = employeeMapper.selectAll();

这里提一下,这个插件还带有一个PageInfo类,里面有可以记录各种信息

刚开始,我以为是和我之前自己封装的Page一样,详情请看Jsp学习笔记(4)——分页查询

但是,其实不一样的,这个PageInfo就是一个封装而已,只是用来存放数据而已,里面有各种信息

属性 说明
pageNum 当前页号(第几页)
pageSize 每页的显示的数据个数
size 当前页的显示的数据个数
startRow 当前页面第一个元素在数据库中的行号
endRow 当前页面最后一个元素在数据库中的行号
pages 总页数
prePage 上一页的页号
nextPage 下一页页号
isFirstPage 是否为第一页
isLastPage 是否为最后一页
hasPreviousPage 是否有前一页
hasNextPage 是否有下一页
navigatePages 导航页码数
navigatepageNums 所有导航页号
navigatePages 导航条上的第一页
navigateFirstPage 导航条上的第一页
navigateLastPage 导航条上的最后一页

有个getTotal方法,可以获得查询结果的总记录数

PageHelper.startPage(1, 10);
List employees = mapper.selectAll();
PageInfo pageInfo = new PageInfo<>(employees);

你可能感兴趣的:(Mybatis使用入门,这一篇就够了)