mybatis

Mybatis

(本篇为mybaits基本概括)

 

一、概念

1.mybatis是什么

Mybatis:MyBatis 本是apache的一个开源项目iBatis,优秀的持久层框架对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身。

 

2.为什么使用mybatis

首先看看有哪些持久层框架:Hibernate,jdbc,SpringDAO ,有这些为什么还要使用mybatis?

对比如下:

Hibernate:老旧的框架,不用写语句但处理复杂业务时,灵活度差, 复杂的HQL难写难理解,例如多表查询的HQL语句。

jdbc:固定模式,开发麻烦

 

二、基本Demo

1.导包

  • mybatis-3.1.1.jar
  • commons-logging-1.1.1.jar
  • log4j-1.2.16.jar
  • cglib-2.2.2.jar
  • asm-3.3.1.jar

导入mysql/oracle开发包:mysql-connector-java-5.1.7-bin.jar

2.创建数据库表和实体类stu

 3.MyBati主配置文件:src下创建:SqlMapConfig.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">
<configuration>
  <!-- typeAliases  标签 :。。。。 -->
    <!-- 和spring整合后 environments配置将废除 -->

<environments default="development">
        <environment id="development">
            <!-- 使用jdbc事务管理 -->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url"
                    value="jdbc:mysql://localhost:3306/hibernatetest?characterEncoding=utf-8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>
    
<!-- 映射配置 -->
<mappers>
<mapper  resource="test/mapper/Stu.xml"/>
</mappers>
    

 

主配置中相关标签说明:

(1)typeAliases  :简化书写,l例如 配置后在mapper.xml配置中resultType="test.entity.Stu"  可以直接写为  resultType="Stu" 

<typeAliases>
<package name="test.entity"></package>

</typeAliases>

(2)mapper 标签 另一种写法

<mappers>
<mapper  resource="test/mapper/Stu.xml"/>
</mappers>

改为            使用条件:stuMapper.xml 和StuMapper接口类 都在Mapper文件夹下,并且两个都同名为StuMapper

<mappers>
<package name="test.mapper.StuMapper"/>
</mappers>

(3)延迟加载:

<!-- 全局配置参数 -->
    <settings>
        <!-- 延迟加载总开关 -->
        <setting name="lazyLoadingEnabled" value="true" />    
        <!-- 设置按需加载 -->
        <setting name="aggressiveLazyLoading" value="false" />
    </settings>

 

 4.配置实体与表的映射文件:stuMapper.xml              (路径:test/mapper/Stu.xml)

配置:   CRUD

<?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">
<!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,后面会讲 -->

<mapper namespace="stu">

<!-- 添加
resultMap标签
--> <!-- findById --> <select id="findById" parameterType="Integer" resultType="test.entity.Stu"> select * from stu where id=#{v} </select>

<!-- 模糊查询 findByName -->
<select id="findByName" parameterType="String" resultType="test.entity.Stu">
select *from stu where name like '%${value}%'
</select>

 

<!-- 添加 insert -->
<select id="InsertStu" parameterType="String" resultType="test.entity.Stu">
insert into stu (name,age) values(#{name},#{age})
</select> 


<!-- 更新 -->
<update id="updateById" parameterType="String" resultType="test.entity.Stu">
update stu
set name=#{name},age=#{age}
where id=#{ijklkd}
</update>

 

<!--删除-->

<delete id="deleteById" parameterType="Integer">
delete from stu
where id=#{idddd}
</delete>


</mapper>

补充:resultMap标签

当我们数据表的字段和JavaBean的属性名称不是相同时,我们就需要使用resultMap设置一下。取代resultType

写法:
<resultMap id="userListResultMap" type="Stu" >
<!-- 列名
当实体类是id_ ,而数据库中是id时

当实体类是username_,而数据库中是username时

当实体类是birthday_ ,而数据库中是birthday时

-->
<id column="id_" property="id"/>
<result column="username_" property="username"/>
<result column="birthday_" property="birthday"/>
</resultMap>

 resultMap和resultType区别

resultType :指定输出结果的类型(pojo、简单类型、hashmap..),将sql查询结果映射为java对象 。(<select id="InsertStu" parameterType="String" resultType="Stu">)

resultMap:将sql查询结果映射为java对象。(<select id="InsertStu" parameterType="String" resultType="userListResultMap">)

  • 如果sql查询列名和最终要映射的pojo的属性名不一致,使用resultMap将列名和pojo的属性名做一个对应关系 (列名和属性名映射配置)

 

5.Test

@Test
    public void tes() throws IOException {
        String resource = "sqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        // ID查询        
         Stu selectOne = sqlSession.selectOne("stu.findById",1);
         System.out.println(selectOne); //结果: Stu [id=1, name=a, age=aa]
        
        // 模糊查询
        List<Stu> selectOne2 = sqlSession.selectList("stu.findByName", "b");
        for (Stu s : selectOne2) {
            System.out.println(s);
        }

        //添加 insert
        Stu s=new Stu();
        s.setName("adsaasd");
        s.setAge("sddsad");
        sqlSession.insert("stu.InsertStu", s);
        sqlSession.commit();
         
        //更新
        Stu s1=new Stu();
        s1.setId(6);
        s1.setName("cccscscsc");
        s1.setAge("aaasds");
        sqlSession.update("stu.updateById", s1);
        sqlSession.commit();
          
        //删除
        sqlSession.delete("stu.deleteById",5);
        sqlSession.commit();
        
              
        inputStream.close();
        sqlSession.close();

 

 6.工作流程:

(1)通过Resources对象读取Mybatis映射文件       ( String resource = "sqlMapConfig.xml";)

(2)通过SqlSessionFactoryBuilder对象创建SqlSessionFactory对象  ( SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);)

(3)获取当前线程的SQLSession ( SqlSession sqlSession = sqlSessionFactory.openSession();)

(4)事务默认开启
(5)通过SQLSession读取映射文件中的操作编号,从而读取SQL语句

(6)提交事务 (sqlSession.commit();)

(7)关闭资源测试类test(inputStream.close(); sqlSession.close();)

 

7.分页测试

分页操作:

当需要接收多个参数的时候,我们使用Map集合来装载!
1.映射文件中添加
<select id="listCategory" resultType="Category">
select * from category_
<if test="start!=null and count!=null">
limit #{start},#{count}
</if>
</select>

2.test
public class Test {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();

xmlWay(session);

session.commit();
session.close();
}
private static void xmlWay(SqlSession session) {
Map<String,Object> params = new HashMap<>();
params.put("start", 0);
params.put("count", 5);
List<Category> cs =session.selectList("listCategory", params);
for (Category c : cs) {
System.out.println(c);
}

 

 三、优化

1.Mapper动态代理

使用接口类

(1)创建一个 接口类 :StuMapper  (路径:test.mapper.StuMapper)

package test.mapper;

import test.entity.Stu;

public interface  StuMapper {

    public Stu findById(Integer id);
    
    public Stu findByName(String name);
    
    public void InsertStu(Stu stu);
    
    public void  updateById(Stu stu);
    
    public void deleteById (Integer id);
    
}

 

(2)修改:把stu。xml中配置name改为  Stumapper的路径  (<mapper namespace="test.mapper.StuMapper">)

(3)stu.xml不变,主配置文件不变

(4)test   

@Test  
  public void testMapper() throws IOException{
String resource
= "sqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); StuMapper mapper = sqlSession.getMapper(StuMapper.class); /* 1. Stu s = mapper.findById(2); System.out.println(s);*/ /* 2. Stu s = mapper.findByName("b"); System.out.println(s);*/ /*3.
Stu s1=new Stu(); s1.setId(6); s1.setName("aaaaaaaascsc"); s1.setAge("aaasds"); mapper.updateById(s1); sqlSession.commit();*/ /*4. mapper.deleteById(7); sqlSession.commit();*/ inputStream.close(); sqlSession.close();

 

2.动态SQL

(1)if where

<!-- 通过name和age查找 -->
<select id="selectStuByAgeAndName" parameterType="Stu"  resultType="Stu">

select *from stu <where> <if test="name!=null and name!=''"> name=#{name} and </if> <if test="age!=null and age!=''"> age=#{age} </if> </where> </select>

(2)SQL片段  (提取重复语句)

<sql id= "selectSql">
select *from stu
</sql>

<select id="findById" parameterType="Integer" resultType="Stu">

<include refid="selectSql"/>

where id=#{v}
</select>

(3)foreach

   delete from students where id in
         <foreach collection="array" open="(" close=")" separator="," item="ids">
             #{ids}
         </foreach>

 

3.一对多、多对多

参考:https://segmentfault.com/a/1190000013690643#articleHeader6

 

4.缓存

  • mybatis一级缓存是一个SqlSession级别,sqlsession只能访问自己的一级缓存的数据。一级缓存默认开启。
  • 二级缓存是跨sqlSession,是mapper级别的缓存,对于mapper级别的缓存不同的sqlsession是可以共享的。

二级缓存 :

(1)mybatis二级缓存需要将查询结果映射的pojo实现 java.io.serializable接口

(2)开启

 <!-- 全局配置参数 -->
    <settings>
        <!-- 开启二级缓存 -->
        <setting name="cacheEnabled" value="true"/>
    </settings>

(3)禁用

在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。、、

<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">

5.逆向工程

使用工程包

 

posted @ 2018-10-19 15:34  StingLon  阅读(148)  评论(0)    收藏  举报