Mybatis简记

324 阅读10分钟

Mybatis简记

mybatis是ORMapping对象关系映射,是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术,其中对象指面向对象,关系指关系型数据库。

完整代码在Github上 https://github.com/KingHeBoy/MyBatis

使用方法

1.创建Mavenue工程

<dependencies>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.5</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.11</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.6</version>
    <scope>provided</scope>
</dependency>
</dependencies>
<build>
<resources>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.xml</include>
        </includes>
    </resource>
</resources>
</build>

2.创建数据库

3.新建数据表对应的实体类

4.创建Mybatis的配置文件config.xml

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> 
    <!--配置Mybatis运行环境-->
 <environments default="development">      
 <environment id="development"> 
     <!--配置JDBC-->
  <transactionManager type="JDBC"></transactionManager> 
   <dataSource type="POOLED">   
     <!--POOL配置连接池-->
   <property name="driver" value="com.mysql.cj.jdbc.Driver"></property> 
   <property name="url" value="jdbc:mysql://localhost:3306/mybatis?          useUnicode=true&amp;characterEncoding=UTF-8"></property>                <property name="username" value="XXX"></property>                        <property name="password" value="XXX"></property>                      </dataSource>       
   </environment>   
   </environments> 
   </configuration>

配置之后有两种使用方式

1.使用原生接口

1.mybatis框架需要开发者自定义sql语句,写在Mapper.xml中,为每个实体类创建对应的Mapper.xml,管理该对象数据的SQL

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
 <mapper namespace="com.southwind.mapper.AccoutMapper">
  <insert id="save" parameterType="com.southwind.entity.Account">   
  insert into t_account(username,password,age) values(#{username},# {password},#{age}) 
  </insert>
 </mapper>
  • namespace设置为该文件具体路径
  • mapper中可以加select、insert、update、delete操作
  • id是调用mybatis方法时需要用到的参数
  • parameterType参数的数据类型

2.在config.xml中注册该Mapper.xml

3.调用原生接口执行添加操作

public class Test {   
    public static void main(String[] args) {     
    InputStream inputStream =                                               Test.class.getClassLoader().getResourceAsStream("config.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new                 SqlSessionFactoryBuilder();      
    SqlSessionFactory sqlSessionFactory =                                   sqlSessionFactoryBuilder.build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();   
    String statement = "com.southwind.mapper.AccoutMapper.save";            Account account = new Account(1L,"小米","123123",22);                     sqlSession.insert(statement,account);       
    sqlSession.commit();    
  } 
  }

2.通过Mapper代理实现自定义接口

1.自定义接口

package com.southwind.repository;
import com.southwind.entity.Account;
import java.util.List;
public interface AccountRepository {   
public int save(Account account);   
public int update(Account account);   
public int deleteById(long id);   
public List<Account> findAll();   
public Account findById(long id); }

2.创建接口对应的Mapper.xml,定义接口方法对应的sql语句

Mybatis会根据规则自动创建接口实现类的代理对象

规则:

  1. Mapper.xml中namespace为接口的全类名
  2. Mapper.xml中statement的id为接口中对应的方法名
  3. Mapper.xml中statement的parameterType和接口对应方法的参数类型一致
  4. Mapper.xml中statement的resultType和接口中对应的返回值类型一致

3.在config.xml中注册

4.调用接口代理对象完成相关业务操作

级联查询

1.一对一

<mapper namespace="com.abc.StudentRepository">
    <resultMap id="studentMap" type="com.abc.entity.Student">  
    <id column="id" property="id"></id>    
    <result column="name" property="name"></result>     
    <association property="classes"                                          javaType="com.abc.entity.Classes">      
    <id column="cid" property="id"></id>     
    <result column="cname" property="name"></result>                        </association>    
    </resultMap>
    <select id="findById" parameterType="long" resultMap="studentMap">        select s.id,s.name,c.id as cid,c.name as cname from student                 s,classes c where s.id = #{id} and s.cid = c.id   
    </select>
    </mapper>
import com.southwind.entity.Classes;
  public interface ClassesRepository {    
  public Classes findById(long id);
}
  1. 一对一用association

  2. resultMap上下对应,column为数据库中的字段

  3. id为主关键字所以为id

  4. resultMap中的id与select的Id对应

  5. 该中为一个学生对应一个班级,**select s.id,s.name,c.id as cid,c.name as cname from student s,classes c where s.id = #{id} and s.cid = c.id **该sql语句

2.一对多

 <resultMap id="classesMap" type="com.abc.entity.Classes">     
 <id column="cid" property="id"></id>    

 <result column="cname" property="name"></result>    
 <collection property="students" ofType="com.southwind.entity.Student">   <id column="id" property="id"/>        
 <result column="name" property="name"/>    
 </collection>   
 </resultMap>

   <select id="findById" parameterType="long" resultMap="classesMap">       select s.id,s.name,c.id as cid,c.name as cname from student             s,classes c where c.id = #{id} and s.cid = c.id  
    </select>
    </mapper>
  1. 一对多用collection
  2. 该中为一个班级对应多个学生**select s.id,s.name,c.id as cid,c.name as cname from student s,classes c where c.id = #{id} and s.cid = c.id **

3.多对多

与一对多也是用collection,如顾客和商品在顾客类中加集合商品,在sql语句中在将顾客和商品关联起来

逆向工程

MyBatis框架需要:实体类、自定义Mapper接口、Mapper.xml

传统需要上述三个组件开发者手动创建,逆向工程可以自动创建

使用

<dependency>    
<groupId>org.mybatis.generator</groupId>     
<artifactId>mybatis-generator-core</artifactId>        <version>1.3.2</version> 
</dependency> 

mybatisgenerator是专门为Mybatis框架开发者定制的代码生成器,在maven pom.xml中加上

1.创建mybatisgenerator配置文件 generatorConfig.xml

  • ̵jdbcConnection配置数据库连接信息
  • ̵javaModelGenerator配置javaBean生成策略,及生成entity类存放位置
  • ̵sqlMapGenerator配置sql映射文件生成策略
  • javaClientGenerator配置mapper接口生成策略
  • table配置目标数据表(tableName:数据库表名,domainObjectName:javaBean类名,生成实体的类名)
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE generatorConfiguration    PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>    
<context id="testTables" targetRuntime="MyBatis3">   
<jdbcConnection   driverClass="com.mysql.cj.jdbc.Driver"                connectionURL="jdbc:mysql://localhost:3306/mybatis?                 useUnicode=true&amp;characterEncoding=UTF-8" 
  userId="root"  password="root"  >
</jdbcConnection>      
<javaModelGenerator targetPackage="com.southwind.entity"           targetProject="./src/main/java"></javaModelGenerator>     
<sqlMapGenerator targetPackage="com.southwind.repository"           targetProject="./src/main/java">
</sqlMapGenerator>        
<javaClientGenerator type="XMLMAPPER" targetPackage="com.southwind.repository" targetProject="./src/main/java"> 
</javaClientGenerator>     
<table tableName="t_user" domainObjectName="User">
</table>   
</context> 
</generatorConfiguration>

2.创建Generator执行类

MyBatis延迟加载

延迟加载也叫懒加载使用延迟加载可以提高程序的执行效率,针对于数据持久层的操作。在某些情况下可以不访问某些表

如用户表和订单表,用户表有多个用户,每个用户有多个订单, 某些时候,我们需要同时查看用户信息和用户的订单信息,这个时候用户的信息和订单的信息都需要显示。但如果我们只查看订单列表,就没必要把用户信息和用户的订单的数据全部查询出来,只显示订单信息就够了。

  • 在config.xml中开启延迟加载
  <settings> 
  <!-- 打印SQL-->  
  <setting name="logImpl" value="STDOUT_LOGGING" />
  <!-——开启延迟加载——>
  <setting name="lazyLoadingEnabled" value="true"/> 
  </settings>

将多表关联查询拆分成多个单表查询

Mybatis缓存

减少与数据库进行交互来提高程序的执行效率,比如查询出id=1的对象,第一次查询出之后会自动保存到缓存中,当下次查询时,直接从缓存中取出对象即可,无需再访问数据库。

Mybatis分类

1.一级缓存

sqlSesson级别,默认是开启的,并且不能关闭

  • 创建Sqlsession对象时,在对象中有一个HashMap用于存放缓存数据,不同的SqlSession之间缓存数据是互不影响的
  • 一级缓存的作用域SqlSession范围的
  • 如果SqlSession执行了DML操作(insert、update、delete),Mybatis必须将缓存清空一保证数据的准确性

二级缓存

Mapper级别,默认是关闭的,可以开启

  • 多个Sqlession使用一个Mapper的SQl语句操作数据库,得到的数据会存到二级缓存区也是用HashMap进行数据存储,相比一级缓存,二级缓存的范围更大。多个SqleSesion可以共用二级缓存,二级缓存是跨Sqlession的
  • 使用二级缓存时,多个Sqlession是共享的,其作用域是Mapper

Mybatis动态SQL

使用动态SQL可简化代码的开发,减少开发者的工作量,程序可以自动根据业务参数来决定SQL的组成

  • if标签

  • where标签,常于if使用

  • set标签

  • foreach标签,常于in使用