MyBatis笔记

一. mybatis简介

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

  1. mybatis架构图

二. mybatis环境搭建与入门程序

  1. 导包

  1. 新建SqlMapConfig.xml,此配置文件是mybatis 的全局配置文件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <?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>
    <!-- 和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/mybatis?characterEncoding=utf-8" />
    <property name="username" value="root" />
    <property name="password" value="root" />
    </dataSource>
    </environment>
    </environments>
    </configuration>
  2. 新建Mapper.xml和对应的pojo

    1
    2
    3
    4
    5
    6
    7
    <?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="test">
    </mapper>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.liweijian.pojo;
import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址

//.....getter setter
//.....
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex
+ ", birthday=" + birthdayq + ", address=" + address + "]";
}
}
  1. 在SqlMapConfig.xml加载映射文件

    1
    2
    3
    <mappers>
    <mapper resource="sqlmap/User.xml" />
    </mappers>
  2. 根据架构图,可以得知我们已经实现了配置文件那块内容,接下来我们只需要创建工厂并拿到session就可以了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //此处使用junit进行测试。
    private SqlSessionFactory sessionFactory;

    @Before
    public void init() throws IOException {
    //读取主配置文件 默认找classpath下的,也就是src下
    InputStream stream = Resources.getResourceAsStream("sqlMapConfig.xml");
    //创建工厂
    sessionFactory = new SqlSessionFactoryBuilder().build(stream);
    }
  3. 根据id查询用户,在User.xml中书写sql

    1
    2
    3
    4
    5
    6
    7
    8
    //id供sqlSession调用
    //parameterType:入参(形参)
    //resultType:返回类型
    //#{v} 取值
    <select id="findUserById" parameterType="Integer" resultType="com.liweijian.pojo.User">
    select * from user where id = #{v}
    }
    </select>
  4. 根据id查询用户

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //根据id查找用户
    @Test
    public void findUserById() throws IOException {
    //获得sqlSession
    SqlSession sqlSession = sessionFactory.openSession();
    //执行操作
    //第一个参数是User.xml中的对应sql的id,test是User.xml的namespace
    //第二个参数是sql需要的参数
    User user = sqlSession.selectOne("test.findUserById", 1);

    System.out.println(user);
    }

这样,我们就实现了mybatis的入门程序。
但是在实际开发中与入门程序的配置有所区别,后期会整合到spring中进行项目开发。

三. Mapper动态代理开发

Mapper动态代理开发简化了dao层的开发,传统的dao层一般需要创建一个dao接口,再提供一个实现类以及新建一个对应的pojo配置文件。
但是Mapper动态代理开发只需要提供一个接口和一个与pojo对应的mapper配置文件即可。具体步骤如下
原始Dao开发中存在以下问题:

  • Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法
  • 调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不得于开发维护。
  1. 还是以User为例,我们需要新建一个UserMapper接口。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package com.liweijian.mapper;
    import com.liweijian.pojo.User;
    import java.util.List;
    public interface UserMapper {

    //遵循四个原则
    //接口 方法名 == UserMapper.xml 中 id 名
    //返回值类型 与 Mapper.xml文件中返回值类型要一致
    //方法的入参类型 与Mapper.xml中入参的类型要一致
    //命名空间 绑定此接口

    //根据id查找用户
    public User findUserById(Integer id);
    }

要实现Mapper动态代理开发,需要遵循四个原则:

  • 接口 方法名 == UserMapper.xml 中 id 名
  • 返回值类型 与 Mapper.xml文件中返回值类型要一致
  • 方法的入参类型 与Mapper.xml中入参的类型要一致
  • 命名空间 绑定此接口
  1. 新建一个与UserMapper接口同名的xml文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?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="com.liweijian.mapper.UserMapper">
    <select id="findUserById" parameterType="Integer" resultType="com.liweijian.pojo.User">
    select * from user where id = #{v}
    </select>
    </mapper>

需要注意的是:namespace的值是接口的完成类名

  1. 在SqlMapConfig.xml加载映射文件

    1
    2
    3
    4
    5
    <mappers>
    <!--<mapper resource="com/liweijian/mapper/UserMapper.xml"></mapper>-->
    <!--此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。 -->
    <package name="com.liweijian.mapper"/>
    </mappers>
  2. 测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    private SqlSessionFactory sessionFactory;
    @Before
    public void init() throws IOException {
    //读取主配置文件 默认找classpath下的,也就是src下
    InputStream stream = Resources.getResourceAsStream("sqlMapConfig.xml");
    //创建工厂
    sessionFactory = new SqlSessionFactoryBuilder().build(stream);
    }

    @Test
    public void findUserById() throws IOException {

    //获得sqlSession
    SqlSession sqlSession = sessionFactory.openSession();
    //获取映射对象
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User user = mapper.findUserById(10);
    System.out.println(user);
    }
  3. 总结

    1. Mapper动态代理开发简化了dao层的开发步骤,需要的书写的代码量变少
    2. 使用这种方式,mymatis会自动根据接口的返回值自动调用selectOne或者selectList方法

四. sqlMapConfig.xml中的一些标签

  1. 配置内容
    properties(属性)
    settings(全局配置参数)
    typeAliases(类型别名)
    typeHandlers(类型处理器)
    objectFactory(对象工厂)
    plugins(插件)
    environments(环境集合属性对象)
    environment(环境子属性对象)

    transactionManager(事务管理)
    dataSource(数据源)
    

    mappers(映射器)

  2. properties配置如下:

    1
    2
    <!-- 读取src下jdbc.properties文件的参数 -->
    <properties resource="jdbc.properties" />

配置properties之后我们就可以在配置数据源的时候使用el表达式进行配置

  1. typeAliases(类型别名)配置如下:

    1
    2
    3
    4
    5
    6
    7
     <typeAliases>
    <!-- 单个定义别名 -->
    <!--<typeAlias type="com.liweijian.pojo.User" alias="user"/>-->

    <!-- 定义包别名,自动扫描子包。 建议使用-->
    <package name="com.liweijian.pojo"/>
    </typeAliases>
  2. mappers(映射器)配置如下:

    1
    2
    3
    4
    5
    6
    7
     <mappers>
    <!--<mapper resource="sqlmap/User.xml" />-->
    <!--<mapper resource="com/liweijian/mapper/UserMapper.xml"></mapper>-->

    <!--此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。 -->
    <package name="com.liweijian.mapper"/>
    </mappers>

面试题:mybatis与hibernate的区别

Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。

Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。

Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。
总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。


####感谢阅读本博客。

####欢迎关注我的博客:https://li-weijian.github.io/

####欢迎关注我的CSDN:https://blog.csdn.net/qq352642663

####需要联系请加QQ:352642663

####欢迎联系我共同交流