一、简介

  MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

  MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。
  每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。
    用xml文件构建SqlSessionFactory实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpath resource),但你可以使用任何Reader实例,包括用文件路径或file://开头的url创建的实例。MyBatis有一个实用类----Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。
 
 
注:mybatis和hibernate
  hibernate:是一个标准ORM框架(对象关系映射)。入门门槛较高的,不需要程序写sql,sql语句自动生成了。

对sql语句进行优化、修改比较困难的。

应用场景:

适用与需求变化不多的中小型项目,比如:后台管理系统,erp、orm、oa。。

mybatis:专注是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全 的ORM框架,虽然程序员自己写sql,mybatis 也可以实现映射(输入映射、输出映射)。

应用场景:

适用与需求变化较多的项目,比如:互联网项目。

二、执行过程与原理
 
 
 三、HelloWorld案例
  po类
package cn.mycookies.mybatis.demo.po;

import java.util.Date;

public class User {
    private int id;
    private String username;
    private String sex;
    private Date birthday;
    private String address;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date date) {
        this.birthday = date;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", sex=" + sex
                + ", birthday=" + birthday + ", address=" + address + "]";
    }
}
 
  1.配置全局配置文件(数据源、实务等)
<?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>
    <!-- 加载数据库配置文件 -->
    <properties resource="db.properties">
    </properties>
         <!-- 配置数据库运行环境 -->
        <environments default="development">
            <environment id="development">
                <!-- 使用jdbc实务管理  实务和数据库连接池都是由mybatis -->
                <transactionManager type="JDBC"></transactionManager>
                <!-- 数据库 -->
                <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driver}" />
                    <property name="url" value="${jdbc.url}" />
                    <property name="username" value="${jdbc.username}" />
                    <property name="password" value="${jdbc.password}" />
                </dataSource>
            </environment>
        </environments>
    <!-- 加载映射文件 -->
    <mappers>
          <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
</configuration>

2.配置映射文件

<?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="cn.mycookies.mybatis.demo.mapper.UserMapper">
     <!--根据id查询User-->
    <select id="findUserById" parameterType="int"
        resultType="cn.mycookies.mybatis.demo.po.User">
        SELECT * FROM USER WHERE id=#{id}
    </select>
</mapper>

3.编写mapper.java接口在全局配置文件中加载映射文件

public interface UserMapper {

	 //根据id查询
	 public User findUserById(int id) throws Exception;
}

4.编写测试类

public class UserMapperTest {
    private SqlSessionFactory sqlSessionFactory= null;
    @Before
    public void setUp() throws Exception {
               //把配置文件加载到流中
        InputStream config = Resources.getResourceAsStream("SqlMapConfig.xml");
               //创建SqlSessionFactory对象
        sqlSessionFactory=new  SqlSessionFactoryBuilder().build(config);
    }

    @Test
    public void testFindUserById() throws Exception {
        //通过factory获取SqlSession对象
        SqlSession session = sqlSessionFactory.openSession();

        //创建mapper对象
        UserMapper userMapper = session.getMapper(UserMapper.class);
         User user = userMapper.findUserById(1);
        System.out.println(user);
    }

}
        

注:在xxxmapper.xml配置文件中parameterType指定输入参数类型,resultType指定输出结果类型

四、mybatis的两种开发模式

1mybatis的原始dao开发(麻烦,程序员需要写dao接口和dao的实现类)

  思路:写出dao接口和实现类,并向dao中注入SqlSessionFactory,在执行CRUD操作前需要通过SqlSessionFactory对象创建SqlSession

  dao接口

public interface UserDao {

    //根据id查询
    public User findUserById(int id) throws Exception;

    //添加用户
    public int  insertUser(User user ) throws Exception;

    //删除用户信息
    public void deleteUser(int id )throws Exception;
}

  实现类

注:当执行删除添加修改时需要手动提交实务

public class UserDaoImpl implements UserDao {
    //向dao注入SqlSessionFactory
    //通过构造方法注入
    private SqlSessionFactory factory;

    public UserDaoImpl(SqlSessionFactory factory) {
        super();
        this.factory = factory;
    }

    @Override
    public User findUserById(int id) throws Exception {
        SqlSession session = factory.openSession();
        //第一个参数为名称空间和id第二个参数为查询传入的参数
        User user = session.selectOne("test.findUserById",id);
        session.close();
        return user;
    }

    @Override
    public int  insertUser(User user) throws Exception {
        SqlSession session = factory.openSession();

         session.insert("test.addUser", user);
         session.commit();
         session.close();
         return user.getId();
    }

    @Override
    public void deleteUser(int id) throws Exception {
        SqlSession session = factory.openSession();

         session.delete("test.deleteUser", id);
         session.commit();
         session.close();
    }

}

  测试代码

public class UserDaoImplTest {
    private SqlSessionFactory sqlSessionFactory= null;

    @Before
    public void setUp() throws Exception {
        InputStream config = Resources.getResourceAsStream("SqlMapConfig.xml");
        sqlSessionFactory=new  SqlSessionFactoryBuilder().build(config);
    }

    @Test
    public void test() throws Exception {
        //创建userdao对象
        UserDao dao  = new UserDaoImpl(sqlSessionFactory);
        User user = dao.findUserById(1);
        System.out.println(user);
    }

}

总结

1、dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。

2、调用sqlsession方法时将statement的id硬编码了

3、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。

 
2.mybatis的mapper代理方式(简单易用,只需要mapper接口即可实现功能)
  思路:根据一定地开发规范编写接口类和mapper.xml配置文件,无需实现类具体操作
开发规范:
  a.在mapper.xml配置文件中namespace等于mapper借口的地址

<mapper namespace="cn.mycookies.mybatis.demo.mapper.UserMapper">

  b.mapper.java接口类中的方法名和mapper.java中对应的statement的id一致

  c.mapper.java接口 中的返回值和参数与mapper.xml中的resultType和parameterType一致

 注:当遵守以上开发规范时mybatis会对具体类的实现自动生成

五、MyBatis的开发使用

  mapper.xml配置文件

  1.自增主键返回

  场景:数据库表设置主键自增长,当插入一个新的对象时,执行insert之前自动生成一个自增主键,要求返回该主键。

可用此函数来获取: LAST_INSERT_ID()。想要完成此功能需要在mapper.xml

配置文件中对sql操作进行配置

<insert id="addUser" parameterType="cn.mycookies.mybatis.demo.po.User">
        <!-- 插入之后返回主键(自动生成)只适用于自增主键
        key+Property指的是将查询到的主键设置到parameType指定对象的那个属性
        resultType:指定结果类型
         -->
        <selectKey keyProperty="id" resultType="java.lang.Integer" order="AFTER">
            SELECT LAST_INSERT_ID()
        </selectKey>
        <!-- 使用mysql的uuid()生成主键
        首先查询uuid得到主键 将主键设置到user对象中

        <selectKey keyProperty="id" resultType="String" order="BEFORE">
            SELECT uuid()
        </selectKey> -->
        INSERT INTO USER(id,username,birthday,sex,address) values(#{id},#{username},#{birthday},#{sex},#{address})
    </insert>

  2.模糊查询 

  mapper.xml配置文件中statement的配置 

    <select id="findUserByName" parameterType="String" resultType="cn.mycookies.mybatis.demo.po.User">
        <!-- SELECT * FROM USER WHERE username like #{value}
        $符号表示拼接字符串,将接受到的内容不加任何修饰的拼接到sql中
            可能会引起sql注入
            大括号内只能使用value
        -->
        SELECT * FROM USER WHERE username like '%${value}%'
    </select>

  3.#{}和${}的区别

#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。

如果接收简单类型,#{}中可以写成value或其它名称。

#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

${}表示一个拼接符号,会引用sql注入,所以不建议使用${}。

${}接收输入参数,类型可以是简单类型,pojo、hashmap。

如果接收简单类型,${}中只能写成value。

${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

4.selectOne 和selectList(指的是mapper.java接口中返回值类型的配置)

selectonse表示查询一条记录进行映射,如果selectOne映射成功,selectList也可以映射。

selectList表示查询多天记录进行映射。如果使用selectList查询多条记录,不能使用selectOne.

SqlMapConfig.xml-mybatis的全局配置文件

mybatis的全局配置文件SqlMapConfig.xml配置文件包括一下内容

  properties:属性

setting:全局参数设置

typeAliases:类型别名

typeHandlers:类型处理器

objectFactory:对象工厂

environments:环境集合属性对象

  environment:环境子属性对象

    transactionManager:实务管理

    dataSource:数据库源的配置

mappers:映射器

1.properties

  场景:将数据库参数单独提取出来配置到db.properties的配置文件中,只需要使用properties将db.properties里面的属性值加载到SqlMapConfig.xml中即可!方便对参数的统一管理,其他的配置文件都可以引用此配置文件。

db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis2
jdbc.username=root
jdbc.password=password

SqlMapConfig.xml

    <!-- 加载数据库配置文件 -->
    <properties resource="db.properties">
    </properties>

    <!-- 配置数据库运行环境 -->
        <environments default="development">
            <environment id="development">
                <!-- 使用jdbc实务管理  实务和数据库连接池都是由mybatis -->
                <transactionManager type="JDBC"></transactionManager>
                <!-- 数据库 -->
                <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driver}" />
                    <property name="url" value="${jdbc.url}" />
                    <property name="username" value="${jdbc.username}" />
                    <property name="password" value="${jdbc.password}" />
                </dataSource>
            </environment>
        </environments>

注:MyBatis将按照下面的顺序来加载属性

  》在properties元素体内定义的属性》properties元素中通过resource或url引用的属性》parameterType传递的属性

在加载过程中会覆盖同名属性,建议不要在properties元素内添加任何属性值,直接爱那个属性值定义在properties文件中,为了防止命名重复,在properties文件中定义属性名要有一定地特殊性,如:jdbc.url (尽量不要直接定义为url)

2.settiong

 mybatis框架运行时可以调整一些默认的运行参数,通过该属性配置后进而影响mybatis的运行行为。

如:开启二级缓存,开启延迟加载。

3.typeAliases

  场景:在mapper.xml中的statement中需要配置parameterType和resultType(参数类型和结果类型),在配置中通常需要指定类型的全路径,优化这一现象,通过在mapper.xml定义别名即可。

a.对于基本数据类型以及他们的封装类mybatis已经进行了定义直接引用即可

别名

映射的类型

_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

b.自定义别名

  b.1单个别名定义

    <typeAliases>
                 <!--type:表示类的路径,alias:类的别名-->
         <typeAlias type="cn.mycookies.mybatis.demo.po.User" alias="user"/>
    </typeAliases>    

    b.2批量定义别名(常用)

    <typeAliases>
     <!--name指定包名,该包下的所有类都被定义了别名,为类名,首字母大小写都可以--> <package name="cn.mycookies.mybatis.demo.po"/> </typeAliases>

    别名的引用:在需要使用的地方直接通过定义的别名直接引用即可。

  

4.typeHandlers

  该标签用来处理jdbc类型和java类型之间的转换,但是通常情况下mybatis默认进行的转换已经满足日常开发,不需要自定义

类型处理器

Java类型

JDBC类型

BooleanTypeHandler

Boolean,boolean

任何兼容的布尔值

ByteTypeHandler

Byte,byte

任何兼容的数字或字节类型

ShortTypeHandler

Short,short

任何兼容的数字或短整型

IntegerTypeHandler

Integer,int

任何兼容的数字和整型

LongTypeHandler

Long,long

任何兼容的数字或长整型

FloatTypeHandler

Float,float

任何兼容的数字或单精度浮点型

DoubleTypeHandler

Double,double

任何兼容的数字或双精度浮点型

BigDecimalTypeHandler

BigDecimal

任何兼容的数字或十进制小数类型

StringTypeHandler

String

CHAR和VARCHAR类型

ClobTypeHandler

String

CLOB和LONGVARCHAR类型

NStringTypeHandler

String

NVARCHAR和NCHAR类型

NClobTypeHandler

String

NCLOB类型

ByteArrayTypeHandler

byte[]

任何兼容的字节流类型

BlobTypeHandler

byte[]

BLOB和LONGVARBINARY类型

DateTypeHandler

Date(java.util)

TIMESTAMP类型

DateOnlyTypeHandler

Date(java.util)

DATE类型

TimeOnlyTypeHandler

Date(java.util)

TIME类型

SqlTimestampTypeHandler

Timestamp(java.sql)

TIMESTAMP类型

SqlDateTypeHandler

Date(java.sql)

DATE类型

SqlTimeTypeHandler

Time(java.sql)

TIME类型

ObjectTypeHandler

任意

其他或未指定类型

EnumTypeHandler

Enumeration类型

VARCHAR-任何兼容的字符串类型,作为代码存储(而不是索引)。

5.mapper

  该标签用于加载mapper.xml配置文件,可以单个加载也可以个批量加载。

  

    <!-- 加载映射文件 -->
    <mappers>
        <!-- <mapper resource="sqlmap/User.xml" /> -->
        <!-- <mapper resource="mapper/UserMapper.xml"/> -->
        <!--
            通过mapper接口加载配置文件
            遵守一些规范:需要将mapper.java接口类名称和mapper.xml文件保持一致
            ,且在一个目录中
            前提:使用mapper代理的方式
        <mapper class="cn.mycookies.mybatis.demo.mapper.UserMapper"/>
         -->
        <!-- 批量加载 推荐使用 name:指定mapper.xml配置文件所在的包名 -->
        <package name="cn.mycookies.mybatis.demo.mapper"/>

    </mappers>

框架学习笔记之Mybatis(一)的更多相关文章

  1. 框架学习笔记之Mybatis(二)

    一.动态sql 通过mybatis提供的标签,实现sql语句的拼接. 1.where <select id="findUserList" parameterType=&quo ...

  2. Spring框架学习笔记(8)——spring boot+mybatis plus+mysql项目环境搭建

    之前写的那篇Spring框架学习笔记(5)--Spring Boot创建与使用,发现有多小细节没有提及,,正好现在又学习了mybatis plus这款框架,打算重新整理一遍,并将细节说清楚 1.通过I ...

  3. SSM框架学习笔记_第1章_SpringIOC概述

    第1章 SpringIOC概述 Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架. 1.1 控制反转IOC IOC(inversion of controller)是一种概念 ...

  4. Spring框架学习笔记(5)——Spring Boot创建与使用

    Spring Boot可以更为方便地搭建一个Web系统,之后服务器上部署也较为方便 创建Spring boot项目 1. 使用IDEA创建项目 2. 修改groupid和artifact 3. 一路n ...

  5. phalcon(费尔康)框架学习笔记

    phalcon(费尔康)框架学习笔记 http://www.qixing318.com/article/phalcon-framework-to-study-notes.html 目录结构   pha ...

  6. Yii框架学习笔记(二)将html前端模板整合到框架中

    选择Yii 2.0版本框架的7个理由 http://blog.chedushi.com/archives/8988 刚接触Yii谈一下对Yii框架的看法和感受 http://bbs.csdn.net/ ...

  7. JavaSE中Collection集合框架学习笔记(2)——拒绝重复内容的Set和支持队列操作的Queue

    前言:俗话说“金三银四铜五”,不知道我要在这段时间找工作会不会很艰难.不管了,工作三年之后就当给自己放个暑假. 面试当中Collection(集合)是基础重点.我在网上看了几篇讲Collection的 ...

  8. JavaSE中Collection集合框架学习笔记(3)——遍历对象的Iterator和收集对象后的排序

    前言:暑期应该开始了,因为小区对面的小学这两天早上都没有像以往那样一到七八点钟就人声喧闹.车水马龙. 前两篇文章介绍了Collection框架的主要接口和常用类,例如List.Set.Queue,和A ...

  9. JavaSE中Map框架学习笔记

    前言:最近几天都在生病,退烧之后身体虚弱.头疼.在床上躺了几天,什么事情都干不了.接下来这段时间,要好好加快进度才好. 前面用了三篇文章的篇幅学习了Collection框架的相关内容,而Map框架相对 ...

随机推荐

  1. Linux如此“自私”?

    Linux如此“自私”? “如果当时我真的知道从头建立一个操作系统的难度,肯定是不会有勇气去做的.”1991年8月25日,随着林纳斯·托瓦兹(Linus Torvalds)这句“天真”的描述,Linu ...

  2. Java运行时内存划分

    这篇文章可以说是摘抄自周志明的<深入理解Java虚拟机>,但是加上了自己的理解,印象可以更深些. Java虚拟机在执行Java程序的时候会把他所管理的内存划分为若干个不同的数据区域,各个区 ...

  3. Kotlin——从无到有系列之高级篇(一):Lambda表达式

    如果您对Kotlin很有兴趣,或者很想学好这门语言,可以关注我的掘金,或者进入我的QQ群大家一起学习.进步. 欢迎各位大佬进群共同研究.探索 QQ群号:497071402 进入正题 经过前面一系列对K ...

  4. Redis查询,设置超时时间

    1.定义 Redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted ...

  5. 【Bootstrap】 bootstrap-table表格组件

    [Bootstrap-table] 顾名思义,这个组件专注于bootstrap风格的表格的设计,并且提供了很多表格的基础和进阶的功能,给我们开发前端的表格省下很多力气. 本文主要参考这位博主的系列文章 ...

  6. C语言博客作业--嵌套循环

    一.PTA实验作业 题目1:7-4 换硬币 2 .设计思路 第一步:定义3个整型变量i,j,k用于循环,定义3个整型变量x,count,total分别用于储存零钱数额,换法个数,硬币数量: 第二步:输 ...

  7. 【iOS】单元测试

    iOS单元测试(作用及入门提升) 字数1704 阅读16369 评论26 喜欢247 由于只是一些简单实用的东西,学学还是挺不错的.其实单元测试用的好,开发起来也会快很多.单元测试对于我目前来说,就是 ...

  8. MobileNet_v2

    研究动机: 神经网络彻底改变了机器智能的许多领域,实现了超人的准确性.然而,提高准确性的驱动力往往需要付出代价:现代先进网络需要高度计算资源,超出许多移动和嵌入式应用的能力. 主要贡献: 发明了一个新 ...

  9. 使用 VSCode 编写 .NET Core 项目之初体验

    注:本文在根据 微软官方文档指导下,根据自己的学习中整理,并不完全照搬文档,但也大体和文档学习路线相似,主要为记录学习过程. 官方学习地址: https://code.visualstudio.com ...

  10. JAVA_SE基础——7.常量&变量

    上一篇,我讲了标识符&关键字    这篇我来解释下变量&常量~~~ 变量与常量这两个概念相信大家都不会感到陌生,在数学中就已经涉及了变量与常量.理解变量与常量,可以举这样一个例子: 例 ...