MyBatis初识
发布日期:2021-07-27 04:56:15 浏览次数:7 分类:技术文章

本文共 14221 字,大约阅读时间需要 47 分钟。

一、 MyBatis简介

ORM : Object RelationShip Mapping

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(sDAO)

mybaits的代码由github.com管理,下载地址:

依赖信息

org.mybatis
mybatis
3.4.6

学习地址:

使用版本:3.4.6

1.1 概述

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

MyBatis主要就完成2件事情

  1. 封装JDBC操作
  2. 利用反射打通Java类与SQL语句之间的相互转换

MyBatis的主要设计目的就是让我们对执行SQL语句时对输入输出的数据管理更加方便,所以方便地写出SQL和方便地获取SQL的执行结果才是MyBatis的核心竞争力。

1.2 特点

  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
  • 解除sql与程序代码的耦合:通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供映射标签,支持对象与数据库的orm字段关系映射
  • 提供对象关系映射标签,支持对象关系组建维护
  • 提供xml标签,支持编写动态sql

1.3 体系结构

在这里插入图片描述

mybatis配置文件,包括Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的信息。

  • mybatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory,即会话工厂。
  • 通过SqlSessionFactory,可以创建SqlSession即会话。Mybatis是通过SqlSession来操作数据库的。
  • SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)。
  • Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括java的简单类型、HashMap集合对象、pojo对象类型。
  • 注意dao换成【mapper】并只设置接口即可,后面会讲到,domain换成【pojo】

二、MyBatis入门

2.1 下载MyBatis

使用Maven创建项目,此步可以省略,详见

2.2 搭建MyBatis环境

第一步:创建数据库

详见

第二步:创建java项目,并添加依赖
org.mybatis
mybatis
3.4.6
第三步:加入配置文件

在resources目录中添加Mybatis的核心配置mybatis-config.xml

第四步:创建POJO

domain

bean

entity

pojo

在不同的场合使用的对象的分类:

po : Persistent Object (持久化对象)

vo:View Object (视图对象 ,PageBean)

dto: Data Transfer Object (数据传输对象 ,系统与系统之间传递数据)

bo : Business Object (业务对象)

什么是POJO:

POJO是Plain Old Java Objects的缩写,POJO实质上可以理解为简单的实体类,顾名思义POJO类的作用是方便程序员使用数据库中的数据表,对于广大的程序员,可以很方便的将POJO类当做对象来进行使用,当然也是可以方便的调用其get,set方法。

用户个人信息类Profile

public class User {
private Integer id; //id号 private String name; //姓名 private Date birthday; //生日 private String gender; //性别 private String career; //职业 private String address; //地址 private String mobile; //手机号 private String picture; //图片链接 //getter和setter}
第五步:加入sql映射文件

resources目录下创建com.rj.mapper文件夹(注意要一个一个的创建),然后创建ProfileMapper.xml文件,注意,注解不能再sql语句标签中出现

select LAST_INSERT_ID();
insert into profile(name,birthday,gender,career,address,mobile,picture) values (#{name},#{birthday},#{gender},#{career},#{address},#{mobile},#{picture});
update profile set name=#{name},birthday=#{birthday},gender=#{gender},career=#{career},address=#{address},mobile=#{mobile},picture=#{picture} where id=#{id};
delete from profile where id=#{id};
第六步:MyBatisUtils工具类【重要】

注意Resources类不要导错包【import org.apache.ibatis.io.Resources;】

public class MyBatisUtils {
/** * 1.创建SqlSessionFactory,一个项目一个工厂,不能关闭 * 2.返回sqlSession的方法 */ private static SqlSessionFactory factory; static {
//创建一个流读取mybatis-config.xml try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); factory = new SqlSessionFactoryBuilder().build(is); System.out.println("SqlSessionFactory初始化成功"); } catch (IOException e) {
e.printStackTrace(); System.out.println("SqlSessionFactory初始化失败"); } } /*SqlSession全局不能唯一,线程可以唯一,而factory可以全局唯一*/ public static SqlSession openSession() {
return factory.openSession(); }}
第七步:对应dao层

注意,增删改必须是事务处理,使用sqlSession.commit()提交才有效

/*dao接口*/public interface ProfileDao {
List
findAll(); Profile findByID(Integer id); void add(Profile profile); void update(Profile profile); void delete(Integer id); List
findByName(String name);}/*dao的实现impl*/public class ProfileDaoImpl implements ProfileDao {
@Override public List
findAll() {
SqlSession sqlSession = MyBatisUtils.openSession(); List
profileList = sqlSession.selectList("test.findAll"); sqlSession.close(); return profileList; } @Override public Profile findByID(Integer id) {
SqlSession sqlSession = MyBatisUtils.openSession(); Profile profile = sqlSession.selectOne("test.findById", id); sqlSession.close(); return profile; } @Override public void add(Profile profile) {
SqlSession sqlSession = MyBatisUtils.openSession(); sqlSession.insert("test.add", profile); //必须提交事务 sqlSession.commit(); //这里可以直接获取自增后的id,因为myBatis中已经使用了selectKey标签 Integer id = profile.getId(); sqlSession.close(); } @Override public void update(Profile profile) {
SqlSession sqlSession = MyBatisUtils.openSession(); sqlSession.update("test.update", profile); sqlSession.commit(); sqlSession.close(); } @Override public void delete(Integer id) {
SqlSession sqlSession = MyBatisUtils.openSession(); sqlSession.delete("test.delete",id); sqlSession.commit(); sqlSession.close(); } @Override public List
findByName(String name) {
SqlSession sqlSession = MyBatisUtils.openSession(); List
profile = sqlSession.selectList("test.findByName", name); sqlSession.close(); return profile; }}
第八步:测试
public class ProfileTest {
@Test public void testFindAll() {
ProfileDao profileDao = new ProfileDaoImpl(); List
profiles = profileDao.findAll(); for (Profile profile : profiles) {
System.out.println(profile.toString()); } System.out.println("查询成功"); } @Test public void testFindById() {
ProfileDao profileDao = new ProfileDaoImpl(); Profile profile = profileDao.findByID(2); System.out.println(profile.toString()); System.out.println("根据id查找成功"); } @Test public void testAdd() {
ProfileDao profileDao = new ProfileDaoImpl(); Profile profile = new Profile(null, "龙在天", new Date(), "男", "外贸", "大明朝", "1566", null); profileDao.add(profile); System.out.println(profile.toString());//这里会打印出id号,因为在映射中获取了selectKey System.out.println("添加成功"); } @Test public void testDelete() {
ProfileDao profileDao = new ProfileDaoImpl(); profileDao.delete(6); System.out.println("删除成功"); } @Test public void testUpdate() {
ProfileDao profileDao = new ProfileDaoImpl(); Profile profile = new Profile(5, "不朽者", null, "未知", "机械兵种", "艾尔", "12357", null); profileDao.update(profile); System.out.println("更新成功"); } @Test public void testFindByName() {
ProfileDao profileDao = new ProfileDaoImpl(); List
profiles = profileDao.findByName("%张%"); for (Profile profile : profiles) {
System.out.println(profile.toString()); } System.out.println("模糊查询成功"); }}

三、MyBatis核心配置文件的操作

MyBatis的核心配置mybatis-config.xml中包含内容顺序如下:

properties(属性)    settings(全局配置参数)    typeAliases(类型别名)    typeHandlers(类型处理器)    objectFactory(对象工厂)    plugins(插件)    environments(环境集合属性对象)    environment(环境子属性对象)    transactionManager(事务管理)    dataSource(数据源)    mappers(映射器)

3.1 properties(属性)

  1. 我们可以自定义连接文件【db.properties】
jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/db_profile?useSSL=true&characterEncoding=utf8jdbc.username=rootjdbc.password=root
  1. mybatis-config.xml文件中直接引用,这样方便查找到文件并进行更改,必须主体语句第一行
MyBatis 将按照下面的顺序来加载属性:(1)在 properties 元素体内定义的属性首先被读取。 (2)然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性

3.2 typeAliases(类型别名)

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 map	         Map

3.3 mappers(映射器)

Mapper配置的几种方法:1. 
使用相对于类路径的资源(现在的使用方式)如:
2.
使用mapper接口类路径如:
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。3.
注册指定包下的所有mapper接口如:
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

具体实现案例

四、MyBatis常用开发方式——Mapper接口动态代理方式【重点】

Mapper接口动态代理方式(重点)

开发规范:

Mapper接口开发方法只需要程序员编写Mapper接口相当于Dao接口】,由MyBatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper接口开发需要遵循以下规范

  1. Mapper.xml文件中的namespace与mapper接口的类路径相同,test换成路径。
  2. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
  3. Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同(注意:mapper.xml中parameterType可不写,如果不写则由Mapper接口中的方法参数类型决定)
  4. Mapper接口方法的返回值类型和mapper.xml中定义的每个sql的resultType(输出参数类型)的类型相同

路径相同,方法名相同,参数名相同,返回值相同

第零步:向pom.xml文件导入java目录

前面讲解的操作步骤,映射文件Mapper都是放到了java下的【resources】中,这里我们将其放到mapper包下【相当于dao层】,但是maven无法找到对应的文件,所以要在pom.xml文件中导入如下内容:

src/main/java
**/*.xml
false
src/main/resources
**/*.xml
**/*.properties
false

mybatis-config.xml还是在resources中

第一步:编写映射文件

在com.rj.mapper包中添加ProfileMapper.xml文件

select LAST_INSERT_ID();
insert into profile(name,birthday,gender,career,address,mobile,picture) values (#{name},#{birthday},#{gender},#{career},#{address},#{mobile},#{picture});
update profile set name=#{name},birthday=#{birthday},gender=#{gender},career=#{career},address=#{address},mobile=#{mobile},picture=#{picture} where id=#{id};
delete from profile where id=#{id};
第二步: 创建DAO接口

在com.rj.mapper包中添加ProfileMapper.java接口

public interface ProfileMapper {
List
findAll(); Profile findById(Integer id); void add(Profile profile); void update(Profile profile); void delete(Integer id); List
findByName(String name);}
第三步:测试
public class ProfileMapperTest {
@Test public void testFindAll() {
SqlSession sqlSession = MyBatisUtils.openSession(); //获取ProfileMapper接口的代理的实现类,从而得到实现类 ProfileMapper profileMapper = sqlSession.getMapper(ProfileMapper.class); List
profiles = profileMapper.findAll(); for (Profile profile : profiles) {
System.out.println(profile.toString()); } sqlSession.close(); System.out.println("查询成功"); } @Test public void testFindById() {
SqlSession sqlSession = MyBatisUtils.openSession(); ProfileMapper profileMapper = sqlSession.getMapper(ProfileMapper.class); Profile profile = profileMapper.findById(2); System.out.println(profile.toString()); System.out.println("根据id查找成功"); } @Test public void testAdd() {
SqlSession sqlSession = MyBatisUtils.openSession(); ProfileMapper profileMapper = sqlSession.getMapper(ProfileMapper.class); Profile profile = new Profile(null, "打飞机", new Date(), "男", "用品", "日本", "2020", null); profileMapper.add(profile); //必须提交,否则不能到数据库 sqlSession.commit(); //必须关闭流 sqlSession.close(); System.out.println("添加成功"); } @Test public void testDelete() {
SqlSession sqlSession = MyBatisUtils.openSession(); ProfileMapper profileMapper = sqlSession.getMapper(ProfileMapper.class); profileMapper.delete(8); sqlSession.commit(); sqlSession.close(); System.out.println("删除成功"); } @Test public void testUpdate() {
SqlSession sqlSession = MyBatisUtils.openSession(); ProfileMapper profileMapper = sqlSession.getMapper(ProfileMapper.class); Profile profile = new Profile(5, "不朽者", null, "未知", "机械兵种", "艾尔", "12357", null); profileMapper.update(profile); sqlSession.commit(); sqlSession.close(); System.out.println("更新成功"); } @Test public void testFindByName() {
SqlSession sqlSession = MyBatisUtils.openSession(); ProfileMapper profileMapper = sqlSession.getMapper(ProfileMapper.class); List
profiles = profileMapper.findByName("%张%"); for (Profile profile : profiles) {
System.out.println(profile.toString()); } System.out.println("模糊查询成功"); }}

注意:

selectOne和selectList

动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。

namespace

MyBatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。

五、插件介绍

FreeMyBatis plugin,可以方便在mapper映射文件和接口之间进行转换和检查错误

在这里插入图片描述

转载地址:https://blog.csdn.net/qq_45337431/article/details/100995387 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Mybatis-高级应用
下一篇:Log日志(一)

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年09月21日 11时45分29秒