mybatis 入门(转载老师讲义,博主只图查看方便)

Mybatis

引言

一、介绍

   MyBatis 的前身是 iBATIS , 是 Clinton Begin 在 2001 年发起的一个开源项目,最初侧重于密码软件的开发 , 后来发展成为一款基于 Java 的持久层框架。 2 004 年, C linton 将 iBATIS 的名字和源码捐赠给了 Apache 软件基金会,接下来的 6 年中,开源软件世界发生了巨大的变化, 一切开发实践、基础设施、许可,甚至数据库技术都彻底改变了 。 2010 年,核心开发团队决定离开 Apache 软件基金会,井且将 iBATIS 改名为 MyBatis oMyBatis 是一款优秀的支持自定义 SQL 查询、存储过程和高级映射的持久层框架,消除了几乎所有的 JDBC 代码和参数的手动设置以及结果集的检索 。 MyBatis 可以使用 XML 或注解进行配置和映射, MyBatis 通过将参数映射到配置的 S QL 形成最终执行的 S QL 语句 ,最后将执行SQL 的 结果映射成 Java 对象返回。与其他的 ORM (对象关系映射)框架不同, MyB atis 并没有将 Java 对象与数据库表关联起来,而是将 Java 方法与 SQL 语句关联。 MyBatis 允许用户充分利用数据库的各种功能,例如存储过程、视图、各种复杂的查询以及某数据库的专有特性 。如果要对遗留数据库、不规范的数据库进行操作 , 或者要完全控制 SQL 的执行, MyBatis 将会是一个不错的选择。与 JDBC 相比, MyBatis 简化 了相关代码, S QL 语句在一行代码中就能执行 。 MyBatis 提供了一个映射引擎 , 声明式地将 SQL 语句的执行结果与对象树映射起来。通过使用 一种内建的类XML 表达式语言, SQL 语句可以被动态生成。MyBatis 支持声明式数据缓存( declarative data caching ) 。当 一条 SQL 语句被标记为“可缓存”后,首次执行它时从数据库获取的所有数据会被存储在高速缓存中,后面再执行这条语句时就会从高速缓存中读取结果,而不是再次命中数据库 。 MyBatis 提供了默认情况下基于 Java HashMap 的缓存实现,以及用于与 OS Cache 、 Eh cache 、 Haze least 和 Memcached 连接的默认连接器,同时还提供了 API 供其他缓存实现使用。

1执行原理

 

  • l mybatis配置文件,包括Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的 信息。

  • l mybatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory,即会话工厂。

  • l 通过SqlSessionFactory,可以创建SqlSession即会话。Mybatis是通过SqlSession来操作数据库的。

  • l SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)。

  • l Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括java的简单类型、HashMap集合对象、POJO对象类型。

二、快速入门

1 准备数据库 ( mybaits )

CREATE TABLE `tb_employee` (
  `emp_no` int(11) NOT NULL AUTO_INCREMENT,
  `emp_name` varchar(50) DEFAULT NULL,
  `emp_tel` varchar(50) DEFAULT NULL,
  `emp_address` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`emp_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2 创建maven工程 ( 引入依赖 )

 
  
    
      junit
      junit
      4.11
      test
    
    
      mysql
      mysql-connector-java
      5.1.46
    
    
      org.mybatis
      mybatis
      3.4.5
    
  

3配置Mapper文件

配置 MyBatis 有多种方式,本节使用最基础最常用的 XML 形式进行配置 。




   

4配置 mybaits核心配置文件


        


    
        
        
            
            
            
            
        
    


    

5测试

    @Test
    public  void test(){
        try {
            // 创建并获得 mybaits核心配置文件 的Reader流
            Reader reader = Resources.getResourceAsReader("configer/mybatis.xml");
            // 创建 SqlSessionFactory (回话工厂) 对象,需要一个Reader流
            SqlSessionFactory  sessionFactory = new SqlSessionFactoryBuilder().build(reader);
            // 创建一个SqlSession (会话)
            SqlSession session = sessionFactory.openSession();
            // 查询数据
            List list = session.selectList("selectAll");
            System.out.println(list);
            // 关闭会话
            session.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    } 
  

三、核心配置文件

1、基础配置 说明




    

     
    
       
        
        
        
            
            
            
            
            
        
    



     
    

2、properties配置

使用 标签把数据库连接信息分离到 db.properties中单独维护

3、settingp配置


  
   

详细配置参考 http://www.mybatis.org/mybatis-3/zh/configuration.html#settings

4、typeAliases配置

类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。

  • 单个配置

    
      
      
    
  • 包配置(推荐 ,别名就是简单类名)

    
      
    
  • 注解配置( 前提必须开启 包别名配置 )

    @Alias("Emp")
    public class EmpModel {
    }

这是一些为常见的 Java 类型内建的相应的类型别名。它们都是大小写不敏感的,需要注意的是由基本类型名称重复导致的特殊处理。

别名 映射的类型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator

四、Mapper映射文件





     
     
 

      SELECT * FROM tb_employee;    

  • 测试

@Test
    public void test(){
        try {
            // 创建并获得 mybaits核心配置文件 的Reader流
            Reader  reader = Resources.getResourceAsReader("configer/mybatis.xml");
            // 创建 SqlSessionFactory (回话工厂) 对象,需要一个Reader流
            SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
            // 创建一个SqlSession (会话)
            SqlSession session = sessionFactory.openSession();
​
            EmpMapper mapper = session.getMapper(EmpMapper.class);
            //List list = mapper.list();
            //System.out.println(list);
​
            int row= mapper. add (  new EmpModel(108,"六六","北京","19939399")  );
            System.out.println("================="row+"====================");
            
            session.commit();
            session.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

六、动态SQL

MyBatis 的强大特性之一便是它的动态 SQL 。使用过 JDB C 或其他类似框架的人都会知道,根据不同条件拼接 SQL 语句时不仅不能忘了必要的空格,还要注意省略掉列名列表最后的逗号,处理方式麻烦且凌乱。 MyBatis 的动态 SQL 则能让我们摆脱这种痛苦。在 MyBatis 3 之前的版本中,使用动态 SQL 需要学习和了解非常多的标签,现在 MyBatis采用了功能强大的 OGNL ( Object-Graph Navigation Language )表达式语言消除了许多其他标签,以下是 MyBatis 的动态 SQL在 XML 中支持的几种标签。

  • if

  • choose (when 、 oterwise)

  • where 、 set

  • trim

  • foreach

  • bind (了解)

1 if 标签

  • 查询         select * from   tb_employee where 1=1                     and emp_no=#{empNo}                             and emp_name=#{empName}                             and emp_tel=#{empTel}            

       EmpModel md=new EmpModel();
                md.setEmpNo(123);
                //md.setEmpName("java");
                // md.setEmpTel("188xx");
                md.setEmpAddress("北京");
                mapper.getEmpWithCondition(md);
    ​
    ​
    ==>  Preparing: select * from tb_employee where 1=1 and emp_no=? 
    ==> Parameters: 123(Integer)
    <==      Total: 0
  • 更新中使用 if

     
              update  tb_employee set
              
                    emp_name=#{empName},
              
              
                    emp_tel=#{empTel},
              
              
                    emp_address=#{empAddress},
              
            emp_no=#{empNo}
            where emp_no=#{empNo}
        
     EmpModel   md=new EmpModel();
                md.setEmpNo(101);
                md.setEmpName("java");
                md.setEmpTel("188xx");
               // md.setEmpAddress("北京");
    ​
                mapper.updateWithModel(md);
    ==>  Preparing: update tb_employee set emp_name=?, emp_tel=?, emp_no=? where emp_no=? 
    ==> Parameters: java(String), 188xx(String), 101(Integer), 101(Integer)
    <==    Updates: 1
  • 插入中使用 if

     
              insert  into tb_employee(emp_no,emp_name
                 
                       ,emp_tel
                 
                 
                      ,emp_address
                 
              )
             values(
                #{empNo},#{empName}
             
                 ,#{empTel}
             
             
                 ,#{empAddress}
             
             )
         
                EmpModel  md=new EmpModel();
                md.setEmpNo(404);
                md.setEmpName("小张");
                //md.setEmpTel("188xx");
                md.setEmpAddress("北京");
                mapper.insertWidthModel(md);
    ​
    ==>  Preparing: insert into tb_employee(emp_no,emp_name ,emp_address ) values( ?,? ,? ) 
    ==> Parameters: 404(Integer), 小张(String), 北京(String)
    <==    Updates: 1

2 choose-when-therwise标签

EmpModel  md=new EmpModel();
            //md.setEmpNo(404);
            md.setEmpName("小张");
            mapper.getEmpByIdOrName(md);
==>  Preparing: select * from tb_employee where emp_name=? 
==> Parameters: 小张(String)
<==    Columns: emp_no, emp_name, emp_tel, emp_address
<==        Row: 404, 小张, null, 北京
<==      Total: 1

3 where 标签

where 标签的作用:如果该标签包含的元素中有返回值,就插入一个 where ;如果 where后面的字符串是以 AND 和 OR 开头的,就将它们剔除。

 
EmpModel  md=new EmpModel();
            //md.setEmpNo(404);
            //md.setEmpName("小张");
            md.setEmpTel("188xx");
            mapper.getEmpWithCondition(md);
<==    Columns: emp_no, emp_name, emp_tel, emp_address
<==        Row: 101, java, 188xx, 重庆
<==      Total: 1

5 set标签

set 标签的作用:如果该标签包含的元素中有返回值,就插入一个 set :如果 set 后面的字符串是 以逗号结尾的,就将这个逗号剔除 。

 
          update  tb_employee 
        
          
                emp_name=#{empName},
          
          
                emp_tel=#{empTel},
          
          
                emp_address=#{empAddress},
          
        
        where emp_no=#{empNo}
    
EmpModel  md=new EmpModel();
            md.setEmpNo(404);
            md.setEmpName("小红");
            md.setEmpTel("110");
            //md.setEmpAddress("重庆");
            mapper.updateWithModel(md);
==>  Preparing: update tb_employee SET emp_name=?, emp_tel=? where emp_no=? 
==> Parameters: 小红(String), 110(String), 404(Integer)
<==    Updates: 1

6 trim标签


          update  tb_employee
        
          
                emp_name=#{empName},
          
          
                emp_tel=#{empTel},
          
          
                emp_address=#{empAddress},
          
        
        where emp_no=#{empNo}
    

7 foreach标签

   
        delete from tb_employee where emp_no in
        
             #{id}
       
    
 List ids=new ArrayList<>();
            ids.add(101);
            ids.add(202);
            ids.add(404);
            mapper.deleteMany( ids );
​
==>  Preparing: delete from tb_employee where emp_no in ( ? , ? , ? ) 
==> Parameters: 101(Integer), 202(Integer), 404(Integer)
<==    Updates: 3

七、关联查询

1 对 1 关联映射

 
               
                
                
                
                 
                 
                        
                        
                        
                 
    
​
    

:用于配置聚合属性

property:聚合属性

javaType:聚合和的类型【别名 或 全类名】

1 对 n 关系映射

       
            
            
            
            
                
                
                
                
            
      
      

n 对1关联映射:和1 对1 相同 使用 聚合属性

n 对n 关联映射 : 和 1 对n 相同使用 聚合集合

nb(牛逼) hashmap映射

 public  List>  getEmpBymaplist() throws  Exception;
  
  // 测试
        SqlSession session = sqlSessionFactory.openSession();
        EmpMapper mapper = session.getMapper(EmpMapper.class);
        List> data = mapper.getEmpBymaplist();
        System.out.println(data);
        session.commit();
        session.close();

hashmap 映射就是不把数据映射到模型,而是映射到hashmap ,此处此种方法灵活,少配置

八、缓存

使用缓存可以使应用更快地获取数据,避免频繁的数据库交互 ,尤其是在查询越多 、缓存命中率越高的情况下,使用缓存的作用就越明显 。 MyBatis 作为持久化框架 , 提供了非常强大的查询缓存特性,可以非常方便地配置和定制使用 。一般提到 MyB atis 缓存 的时候,都是指二级缓存。 一级缓存( 也叫 本地缓存〉默认会启用,并且不能控制,因此很少会提到 。

mybaits 一级缓存

mybatis一级缓存是 回话级别的缓存,也就是在同一个sqlsession 会话中的相同查询,会使用缓存数据,并不会在从新发送sql到数据库,除非缓存中没有数据才会重新发送sql重新查询。

缓存原理: MyBatis 会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个 Map对象中。如果同一个 SqlSession 中执行的方法和参数完全一致,那么通过算法会生成相同的键值,当 Map 缓存对象中己经存在该键值时,则会返回缓存中的对象。

mybaits一级缓存失效的集中情况:

  • 第二次查询前 调用 session.clearCache()

  • 两次查询 之间执行了更新操作 (INSERT UPDATE DELETE

  • select 标签 flushCache="true"

  • session 关闭

mybatis 二级缓存

mybatis 二级缓存是 namespace 空间级别的缓存,跟session 无关,即便在不同的session回话中,调用同一命名空间(namespace)下的方法做相同条件的查询,都可以使用到缓存数据。所以二级缓存是跨 session的。mybatis 默认是不启用二级缓存的,用户可以自行开启,同时还可以配置第三方的 缓存框架。

关于二级缓存,mybaits框架本身也有响应的实现,只是比较简单,通常开发中使用的第三方缓存技术包括

  • ehcache

  • memcached

  • redis

开启 mybatis的方法

mybatis.xml 主配置文件

mapper.xml 映射配置文件


      
  • 映射语句文件中的所有 select 语句将会被缓存。

  • 映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。

  • 缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。

  • 根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序 来刷新。

  • 缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。

  • 缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而 且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

 

 

model 实体类 实现序列化接口

public class GroupModel  implements Serializable {
    
}

 

 

配置第三方 缓存技术

这里以ehcache为例,添加依赖

    
    
      net.sf.ehcache
      ehcache-core
      2.6.8
    
    
    
      org.mybatis.caches
      mybatis-ehcache
      1.1.0
    

ehcache.xml 核心配置文件( classpath下)



    
    
        
    

引用

 

九、mybatis-generate插件

   
          org.mybatis.generator
          mybatis-generator-maven-plugin
          1.3.5
          
            true
            true
          
    



    
    
        
        
​
        
            
            
        
​
        
        
​
        
             
        
​
        
​
        
        
              
        
   

十、PageHeper 插件

1、介绍

pageHeper是过国内的一个大神基于基于mybatis开发的一款分页插件,目前这个开源项目托管到GitHub上,项目地址https://github.com/pagehelper/Mybatis-PageHelper。

2、使用(使用5.x版本)

① Pom文件中添加依赖

   
      com.github.pagehelper
      pagehelper
      5.1.2
    

②mybaits配置文件中集成


        
            
            
        

详细参数设置参考:https://pagehelper.github.io/docs/howtouse/

③代码中使用

@Controller
@Scope("prototype")
public class StrutsAction  extends ActionSupport {
     //依赖服务层
    @Autowired
    private EmpService empService;
    public   String  hello(){
        try {
            PageHelper.startPage(2,7,true);
            List list = empService.getAll();
            //输出数据
            for (TbEmployee emp :list){
                System.out.println(emp);
            }
            //获得详细的分页信息
            PageInfo pageInfo = new PageInfo<>(list);
            System.out.println(pageInfo);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  "hello";
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(java0基础)