mybatis从入门到出山

mybatis从入门到出山

    • mybatis框架是什么?
    • Spring与mybatis的整合
    • Mybatis的标签
    • Mybatis一级缓存与二级缓存
    • Mybatis的批量操作

mybatis框架是什么?

mybatis框架是一个优秀的持久层框架,它支持定制化SQL,存储过程以及高级映射。简单点说,mybatis框架的作用就是对数据库的数据进行增删改查。然后相应的框架或者工具非常多,为什么我们要选择mybatis呢?一方面是因为mybatis上手比较简单,所以对于开发过程来说也简单很多。同时他也能与Spring进行较好的融合。

Spring与mybatis的整合

1.首先我们需要在pom.xml中引入所需要的jar包,如下所示:

<!--spring的三个核心依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
<!--mybatis依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.4</version>
        </dependency>
<!--mybatis整合spring依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.0</version>
        </dependency>
<!--数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.41</version>
        </dependency>        

首先解释一下各个jar包的作用:
Spring的三个核心依赖:是Spring框架必备的核心基础包;
mybatis依赖:是mybatis框架对应的jar包;
mybatis整合spring依赖:MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapper 和 SqlSession 并注入到 bean 中,以及将 Mybatis 的异常转换为 Spring 的 DataAccessException。最终,可以做到应用代码不依赖于 MyBatis,Spring 或 MyBatis-Spring。
数据库驱动:关于数据库驱动,我们都知道是需要连接数据库的必须jar包,之所以是必须,是因为该jar包本质上还是软件代码,其主要作用是计算机系统与硬件设备之间完成数据传送的功能,只有借助驱动程序,两者才能通信并完成特定的功能。

2.接下来我们就需要通过业务需求分析在mysql中创建我们的数据库表,完成我们的表设计。完成表设计以后我们就可以通过使用mybatis-generator工具来生成对应的entity、dao,以及dao对应的xml文件。

3.上述两步完成以后我们就要进行今天的核心内容,Spring与myatis的整合
我们一直讲Spring与mybatis的整合,那我们为什么要对spring与mybatis进行整合呢?有什么好处呢?整合的原理是什么呢?
在实际开发中我们一般是直接在service的impl代码中直接通过spring的DI注入mybatis 的dao对象既然要注入dao对象,那么dao就必须要在Spring容器中,也就是说需要Spring容器帮助我们去创建dao对象。我们知道mybatis框架创建代理对象,首先要加载主配置文件,构建sqlSessionFactory对象,只有创建的sqlSessionFactory对象mybatis才能进行后续的操作。也就是说我们进行Spring与mybatis的整合,需要的做的就是使Spring去创建sqlSessionFacetory对象。关于在Spring中创建sqlSessionFactory对象,如下所示:

<!--数据库连接池-->
    <!--加载配置文件-->
    <context:property-placeholder  location="classpath:conf/jdbc.properties"/>
    <!-- 配置数据源 -->
    <bean id="dataSource"
          class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="123456"/>
    </bean>

    <!-- 配置mybatis的sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 自动扫描mappers.xml文件 -->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
        <!-- mybatis配置文件 -->
        <property name="configLocation" value="classpath:conf/mybatis-config.xml"/>
    </bean>

    <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.myself.study.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>

首先,加载properties文件,即数据库的配置文件,然后进行数据源的配置;
第二步,配置mybatis的sqlSessionFactory,并配置相应的参数属性,其中包括数据源、dao对应的xml文件位置、mybatis的配置文件。
第三步,配置mybatis-spring的jar包下的MapperScannerConfigurer类的bean属性,spring会自动查找该配置下的类;配置的属性参数扫描dao包的位置,以及上述配置的sqlSessionFactory的bean对象;
至此,spring与mybatis 的整合就完成了;

Mybatis的标签

通过上述配置,我们就完成了Spring与mybatis 的整合;接下来就说一下mybatis中常用的一些标签;
select 标签的使用
   属性介绍:
     id :唯一的标识符.
     parameterType:传给此语句的参数的全路径名或别名 例:com.test.poso.User或user
     resultType :语句返回值类型或别名。注意,如果是集合,那么这里填写的
     是集合的泛型,而不是集合本身(resultType 与resultMap 不能并用)
   例子:
     sql:

<select id="userList" parameterType="user" resultType="User">
        select * from user where name =#{name}
      </select>

在select标签中返回结果除了使用resultType还有一个属性:resultMap,resultMap的作用是建立sql查询结果字段与实体属性的映射关系,查询的结果转换为Java对象方便进一步操作,栗子如下:

<resultMap id="getStudentRM" type="EStudnet">
  <id property="id" column="ID"/>
  <result property="studentName" column="Name"/>
  <result property="studentAge" column="Age"/>
</resultMap>
<select id="getStudent" resultMap="getStudentRM">
  SELECT ID, Name, Age
    FROM TStudent
</select>

column对应的属性为sql查询结果的列,而prperty对应的为对应对象的属性值
insert 标签的使用
    属性介绍:
      id :唯一的标识符
      parameterType:传给此语句的参数的全路径名或别名

delete 标签的使用

<delete id="deleteUser" parameterType="int">
      delete from user 
      where id = #{id} 
    </delete>

update 标签的使用
    类似于insert
    
if 标签的使用

<select id=" getStudentListLikeName " parameterType="StudentEntity" resultMap="studentResultMap">     
    SELECT * from STUDENT_TBL ST      
    <if test="studentName!=null and studentName!='' ">     
        WHERE ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
    </if>     
</select>    

foreach 标签的使用
forearch标签的使用我有一片专门的文章介绍用法;
mybatis传入多个参数以及List集合参数

where标签的使用

<!-- 查询学生list,like姓名,=性别 -->     
<select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap">     
    SELECT * from STUDENT_TBL ST      
    <where>     
        <if test="studentName!=null and studentName!='' ">     
            ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
        </if>     
        <if test="studentSex!= null and studentSex!= '' ">     
            AND ST.STUDENT_SEX = #{studentSex}      
        </if>     
    </where>     
</select>

sql标签的使用
sql元素标签用来定义可重复使用的SQL代码片段,使用时只需要用include元素标签引用即可,最终达到SQL语句重用的目的;同时它可以被静态地(在加载参数) 参数化,不同的属性值通过包含的实例变化,比如:

//建立sql片段
<sql id="query_user_where">
	<if test="id!=null and id!=''">
		and id=#{id}
	</if>
	<if test="username!=null and username!=''">
		and username like '%${username}%'
	</if>
</sql>
 
//使用include引用sql片段
<select id="findUserList" parameterType="user" resultType="user">
	select * from user
		<where>
			<include refid="query_user_where"/>
		</where>
</select>
 
//引用其它mapper.xml的sql片段
<include refid="namespace.sql片段"/>

属性值也可以被用在 include 元素的 refid 属性里

<include refid="${include_target}"/>

属性值也可以被用在include 内部语句中

<sql id="sometable">
  ${prefix}Table
</sql>
 
<sql id="someinclude">
  from
    <include refid="${include_target}"/>
</sql>
 
<select id="select" resultType="map">
  select
    field1, field2, field3
  <include refid="someinclude">
    <property name="prefix" value="Some"/>
    <property name="include_target" value="sometable"/>
  </include>
</select>

Mybatis一级缓存与二级缓存

  1. mybatis一级缓存
    mybatis的一级缓存是sqlsession级别的,也就是说sqlsession只能访问自己的一级缓存数据,一级缓存查询存在于sqlsession类的对象实例中,当第一次查询某一个数据的时候,sqlsession类的实例对象会将数据存入到一级缓存,这样就可以在没有收到改变数据的请求之前,我们所查询的数据都是从缓存中获取的,这样就大大减少了数据库的频繁查询。总结:(1)在同一个 SqlSession 中, Mybatis 会把执行的方法和参数通过算法生成缓存的键值, 将键值和结果存放在一个 Map 中, 如果后续的键值一样, 则直接从 Map 中获取数据;(2)不同的 SqlSession 之间的缓存是相互隔离的;(3)用一个 SqlSession, 可以通过配置使得在查询前清空缓存;(4)任何的 UPDATE, INSERT, DELETE 语句都会清空缓存。

  2. mybatis二级缓存
    MyBatis的一级缓存是默认开启的,不需要我们任何配置;当我们将spring与mybatis整合以后,mybatis的一级缓存就自动失效了;但是并不是真正的失效;而二级缓存默认关闭的,想要开启二级缓存,我们得去SqlConfig.xml文件配置setting属性,把name设置cacheEnable以及value设置为ture,因为由于二级缓存是mapper级别的,所以我还需要开启二级缓存,在具体的mapper.xml文件添加一个cache标签即可。
    原理如下:
    第一次调用mapper下的SQL去查询用户信息。查询到的信息会存到该mapper对应的二级缓存区域内。第二次调用相同namespace下的mapper映射文件中相同的SQL去查询用户信息。会去对应的二级缓存内取结果。如果调用相同namespace下的mapper映射文件中的增删改SQL,并执行了commit操作。此时会清空该namespace下的二级缓存。

默认二级缓存的粒度是Mapper级别的,但是如果在同一个Mapper文件中某个查询不想使用二级缓存的话,就需要对缓存的控制粒度更细。

默认设置

   * 当为select语句时:flushCache默认为false,表示任何时候语句被调用,都不会去清空本地缓存和二级缓存。useCache默认为true,表示会将本条语句的结果进行二级缓存。
   * 当为insert、update、delete语句时:flushCache默认为true,表示任何时候语句被调用,都会导致本地缓存和二级缓存被清空。useCache属性在该情况下没有。

默认配置解读

   *如果查询语句设置成true,那么每次查询都是去数据库查询,即意味着该查询的二级缓存失效。
   *如果增删改语句设置成false,即使用二级缓存,那么如果在数据库中修改了数据,而缓存数据还是原来的,这个时候就会出现脏读。

flushCache与useCache设置示例如下:

<selectid="findUserById"parameterType="int"
                   resultType="com.kkb.mybatis.po.User"useCache="true"flushCache="true">

                   SELECT * FROM user WHERE id =#{id}
</select>

Mybatis的批量操作

关于mybatis进行批量新增,目前常用的有三种方法:

  1. 使用for循环,多次调用dao接口进行批量inset、update、delete操作
  2. 使用list结构传入多个参数,然后在mybatis的xml文件中使用forEach标签拼装sql语句进行批量新增;
  3. 基于mybatis的SqlSession的ExecutorType做批量操作。
    三种方法,第一种的方法会耗费大量的数据库连接资源,性能肯定是最差的,并不适合做大批量的新增操作;而第二种方法,如果数据量过大,则会拼装过长的sql语句,造成CPU的飙升。而第三种方法的性能则优于第二种。

你可能感兴趣的:(mybatis)