MyBatis

MyBatis logo

简介(来自维基百科)

    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对象并返回。

功能概况

    与其他的对象关系映射框架不同,MyBatis并没有将Java对象与数据库表关联起来,而是将Java方法与SQL语句关联。MyBatis允许用户充分利用数据库的各种功能,例如存储过程、视图、各种复杂的查询以及某数据库的专有特性。如果要对遗留数据库、不规范的数据库进行操作,或者要完全控制SQL的执行,MyBatis是一个不错的选择。
    与JDBC相比,MyBatis简化了相关代码:SQL语句在一行代码中就能执行。MyBatis提供了一个映射引擎,声明式的把SQL语句执行结果与对象树映射起来。通过使用一种内建的类XML表达式语言,或者使用Apache Velocity集成的插件,SQL语句可以被动态的生成。
    MyBatis与Spring Framework和Google Guice集成,这使开发者免于依赖性问题。
    MyBatis支持声明式数据缓存(declarative data caching)。当一条SQL语句被标记为“可缓存”后,首次执行它时从数据库获取的所有数据会被存储在一段高速缓存中,今后执行这条语句时就会从高速缓存中读取结果,而不是再次命中数据库。MyBatis提供了基于 Java HashMap 的默认缓存实现,以及用于与OSCache、Ehcache、Hazelcast和Memcached连接的默认连接器。MyBatis还提供API供其他缓存实现使用。

MyBatis入门

更详细内容参考官方教程

使用JDBC操作数据库的弊端

使用JDBC操作数据库的流程见附件word文档
通常使用JDBC操作数据库的代码如下
弊端如下
  • 数据库连接资源的创建、释放频繁造成系统资源浪费,从而影响系统性能。如果使用数据库连接池可解决此问题。
  • SQL语句在代码中硬编码,造成代码不易维护,实际应用中sql变化的可能较大,sql变动需要改变java代码。
  • 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
  • 结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。

MyBatis的架构

其中Mapper1.xml、Mapper2.xml...Mappern.xml是SQL映射文件(一般数据库中有多少个表就有多少个映射文件)
MyBatis配置
  • SqlMapConfig.xml,此文件作为MyBatis的全局配置文件,配置了mybatis的运行环境等信息
  • mapper.xml文件即SQL映射文件,文件中配置了操作数据库的SQL语句。此文件需要在SqlMapConfig.xml中加载
  • 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
  • 由会话工厂创建SqlSession即会话,操作数据库需要通过SqlSession进行
  • MyBatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器
  • Mapped Statement也是MyBatis一个底层封装对象,它包装了MyBatis配置信息及SQL映射信息等,mapper.xml文件中一个SQL对应一个Mapped Statement对象,SQL的id即是Mapped Statement的id
  • Mapped Statement对SQL执行输入参数进行定义,包括HashMap、基本类型、POJO,Executor通过Mapped Statement在执行SQL前将输入的java对象映射至SQL中,输入参数映射就是JDBC编程中对PreparedStatement设置参数
  • Mapped Statement对SQL执行输出结果进行定义,包括HashMap、基本类型、POJO,Executor通过Mapped Statement在执行SQL后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程

快速入门

通常MyBatis由Maven构建,此处快速入门是手动构建的方式
环境搭建
步骤
  1. 创建项目,导入依赖jar包
  2. 加入核心配置文件和log4j的配置文件
  3. 创建POJO
  4. 创建SQL映射文件
  5. 加载映射文件
  6. 在核心配置文件中加载映射文件
导入依赖jar包
首先在GitHub上下载所需版本的MyBatis
其目录结构如下
导入 MyBatis的核心包 与lib目录下的 MyBatis的依赖包 以及 数据库驱动包 到项目中
如下
创建资源文件夹并在其中创建配置文件(log4j.properties和SqlMapConfig.xml文件)
*IDEA中创建名为config的资源目录/文件夹
加入log4j.properties
内容如下
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

MyBatis默认使用log4j作为输出日志工具

加入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>
    <!-- 和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>

SqlMapConfig.xml是mybatis核心配置文件,配置文件内容为数据源、事务管理

创建POJO
POJO类作为mybatis进行sql映射使用,po类通常与数据库表对应
创建SQL映射文件
在config目录下创建sqlmap目录并创建sql映射文件User.xml
内容如下
此处未编写任何SQL语句, 日后操作User表 的SQL语句将编写在此处
<?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>

 

其中命名空间是用于区分不同的映射文件的同名SQL语句的
如命名空间为test,若SQL功能名称为findUserById,引用方式应该为user.findUserById
此时项目目录结构如下
在SqlMapConfig文件中引入SQL映射文件
创建测试类测试环境搭建情况
完整测试代码见这个部分最末
往User.xml中添加SQL语句
如下
测试根据id查询单个User
测试代码如下
package com.zella.test;

import com.zella.mybatis.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.InputStream;

public class MyBatisTest {
    @Test
    public void testMyBatis() throws Exception {
        // 加载核心配置文件
        String resource = "sqlMapConfig.xml";
        InputStream in = Resources.getResourceAsStream(resource);
        // 创建SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
        // 创建SqlSession
        SqlSession session = sqlSessionFactory.openSession();
        // 执行SQL语句
        User user = session.selectOne("test.findUserById", 10);

        System.out.println(user);
    }
}

 

运行结果如下
说明框架基本搭建成功
测试根据用户名模糊查询对应用户列表
映射文件新增
注意
若为'%#{v}%'则实际SQL语句为'%'xxx'%',语法错误,所以字符串拼接需要使用${v}
实际上此处应该用'%${value}%'测试才不报错
但是使用$会有SQL注入的问题,可以用以下的方式使用#{v}
即用双引号包围%符来使用#{v},可以防止SQL注入
测试插入数据
映射文件如下
另外测试代码需要手动提交事务
测试插入用户后返回id
业务上可能需要在插入用户后返回i:
如:需要同时插入用户和订单,订单数据需要用到用户id,而 用户id是插入表后才生成的
希望插入数据后更新POJO对象的id属性,即在插入User后更新User的id属性,然后就可以直接通过user.getId()来获取id值了
可以通过在映射文件添加selectKey标签来定义返回id,如下
测试代码如下
执行结果
测试更新用户
映射文件如下
测试代码
测试删除用户
映射文件如下
测试代码

使用MyBatis解决了JDBC操作数据库的弊端

  • 数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解决此问题
    • 解决:在SqlMapConfig.xml中配置数据连接池,使用连接池管理数据库链接
  • SQL语句写在代码中造成代码不易维护,实际应用SQL变化的可能较大,SQL变动需要改变Java代码
    • 解决:SQL语句配置在XXXXmapper.xml文件中与Java代码分离
  • SQL语句传参数麻烦,因为SQL语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应
    • 解决:MyBatis自动将Java对象映射至SQL语句,通过statement中的parameterType定义输入参数的类型
  • 对结果集解析麻烦,SQL变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成POJO对象解析比较方便
    • 解决:MyBatis自动将SQL执行结果映射至Java对象,通过statement中的resultType定义输出结果的类型
*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需要具有很强的经验和能力才行。
    总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。

使用MyBatis开发Dao层

使用MyBatis开发Dao,通常有两种方式
  • 原始/传统Dao开发方法
  • Mapper动态代理开发方法

MyBatis的主要API的使用范围

  • SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等
  • SqlSession通过SqlSessionFactory创建
  • SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建
SqlSessionFactoryBuilder
  • SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory创建的
  • 所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围即方法体内局部变量
SqlSessionFactory
  • SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory
SqlSession
  • SqlSession是一个面向用户的接口,sqlSession中定义了数据库操作方法
  • 每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的
  • 因此最佳的范围是请求或方法范围,绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中
  • 每打开一个SqlSession使用完毕就要关闭它,通常把这个关闭操作放到finally块中以确保每次都能执行关闭

传统Dao开发方法

传统Dao开发方法需要程序员编写Dao接口及Dao实现类
步骤
  1. 编写映射文件
  2. 编写Dao接口
  3. 编写Dao接口实现类
  4. 测试
详细步骤见附件word文档
原始Dao开发方法存在的问题
  • Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法
  • 调用SqlSession的数据库操作方法(如selectOne("xxx.xxx",id))需要指定statement的id,这里存在硬编码,不得于开发维护
此时可以考虑由程序反射生成重复的代码,仅编写特定的非重复代码

Mapper动态代理方式开发Dao

Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由MyBatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法
Mapper接口开发需要遵循以下规范
  • Mapper.xml文件中的namespace与Mapper接口的类路径相同
  • Mapper接口方法名和mapper.xml中定义的每个statement的id相同 
    • 这样省去了传入id的操作了,MyBatis会自动由方法名匹配对应的statement
  • Mapper接口方法的输入参数类型和mapper.xml中定义的每个SQL的parameterType的类型相同
  • Mapper接口方法的输出参数(返回值)类型和mapper.xml中定义的每个SQL的resultType的类型相同
符合以上四个规范就可以将Mapper接口与映射文件一一对应、绑定,可以使用Mapper动态代理的方式开发Dao了
测试
根据以上四个规范编写定义好映射文件和Mapper接口之后,就可以编写测试代码测试Mapper接口了
可见Mapper动态代理方式编写Dao十分简便易用
两个小细节
selectOne和selectList
动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是 根据mapper接口方法的返回值决定
  • 如果返回list则调用selectList方法
  • 如果返回单个对象则调用selectOne方法
namespace
MyBatis官方推荐使用Mapper代理方法开发 Mapper 接口,程序员 不用编Mapper接口实现类 ,使用Mapper代理方法时,输入参数可以使用POJO包装对象或Map对象,保证Dao的通用性

SqlMapConfig.xml配置文件

SqlMapConfig文件的标签(配置内容)

SqlMapConfig.xml中配置的内容和顺序如下:
  1. properties(属性)
  2. settings(全局配置参数)
  3. typeAliases(类型别名)
  4. typeHandlers(类型处理器)
  5. objectFactory(对象工厂)
  6. plugins(插件)
  7. environments(环境集合属性对象)
    1. environment(环境子属性对象)
      1. transactionManager(事务管理)
      2. dataSource(数据源)
  8. mappers(映射器)
properties(属性)
SqlMapConfig.xml可以引用java属性文件中的配置信息
MyBatis将按照下面的顺序来加载属性:
  • 在properties元素体内定义的属性首先被读取。
  • 然后会读取properties元素中resource或url对应的properties文件加载的属性,它会覆盖已读取的同名属性
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

自定义别名
注意:
  • 别名大小写不敏感
  • 批量定义别名只需要定义父包,将扫描父包下所有类,包括子包内
    • 但最好保证这个父包下所有类都是POJO
mappers(映射器)
映射器配置的几种方法
<mapper resource=""/>
使用相对于类路径的资源
如:<mapper resource="sqlmap/User.xml" />
<mapper class=""/>
使用mapper接口类路径
如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
注意: 这种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
<package name=""/>(常用)
注册指定包下的所有mapper接口
如:<package name="cn.itcast.mybatis.mapper"/>
注意:这此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
需要这样同名同路径
<mapper url=""/>
需要书写绝对路径,不推荐

MyBatis深入

输入映射和输出映射

Mapper.xml映射文件中定义了操作数据库的sql,每个SQL是一个statement,映射文件是MyBatis的核心
输入映射-parameterType
传递简单类型
使用#{}占位符,或使用${}进行SQL拼接
传递POJO
MyBatis使用OGNL表达式解析对象字段的值,#{}或者${}括号中的值为POJO属性名称
传递POJO包装对象
开发中通过可以使用 POJO传递查询条件。
查询条件可能是 综合的查询条件(如多表查询),不仅包括用户查询条件还包括其它的查询条件(比如查询用户信息的时候,将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。
包装对象: POJO类中的一个属性是另外一个POJO
示例详见附件
输出映射-resultType
简单输出类型
如查询条目数,resultType为int
 
输出POJO
输出POJO列表
输出resultMap类型
resultType可以指定将查询结果映射为POJO,但需要 POJO的属性名和SQL查询的列名一致方可映射成功
如果 SQL查询 字段名和POJO的 属性名 不一致,可以通过resultMap将字段名和属性名作一个对应关系,resultMap实质上还需要将查询结果映射到 POJO对象中
resultMap可以实现将查询结果映射为复杂类型的 POJO,比如在查询结果映射对象中包括 POJO和list实现一对一查询和一对多查询
示例
Orders表字段名与POJO属性名称不一致,使用resultMap类型
首先定义POJO对象
  
编写Mapper接口并配置映射文件(不使用resultMap作为输出类型)
最后测试
发现userId为null
由于上边的mapper.xml中sql查询列(user_id)和Order类属性(userId)不一致,所以查询结果不能映射到pojo中。
需要定义resultMap,把orderResultMap将sql查询列(user_id)和Order类属性(userId)对应起来
解决方案就是定义并使用resultMap作为输出类型
修改映射文件,定义并使用resultMap
此后用同样的测试代码就可以得到需要的结果了

动态SQL

动态SQL是MyBatis提供的使用各种标签方法实现动态拼接SQL语句的功能
静态的SQL的弊端
其一:
当一条SQL有多个条件时,若传入的POJO提供部分条件,未传入的条件为空,将默认这个SQL语句为空的条件where子句为不满足,从而使SQL查询得不到需要的结果
详见附件day02 3.1
if标签
示例:
可以活用where 1 = 1 这个条件
where标签
上面活用小技巧虽然可以解决问题,但不够简介
可以使用where标签解决
where标签可以自动去掉第一个有效(非空)条件前的and
SQL片段
可以将重复的SQL语句提取出来,作为SQL片段,使用include标签引用,达到SQL抽取重用的效果
示例
例如可以将上文例子的id,username,birthday等属性/字段提取作为SQL片段
如果需要引用其他映射文件配置的SQL片段,需要加上对应的namespace
foreach标签
可以向SQL传递 数组List对象或有这两种类型作为属性的 QueryVo/POJO,MyBatis可以通过foreach标签解析
示例
通过多个id查询用户信息
查询SQL:select * from user where id in (1,10,24)
首先需要修改POJO中QueryVo的代码,增加ids属性用于存储多个用户id(getter/setter)
在映射文件中定义
测试代码如下
执行结果
注意
MyBatis在映射文件中是通过 类名而不是当前传入变量名来识别的,当 直接传递数组(或List)而不是传递QueryVo时,映射文件中参数类型应该是 array(或list)而不是变量名
原理:在传递User对象时,我们不直接使用User对象而是使用User对象内部的属性,如user.username,同理,直接传递数组时,使用的是数组内部的属性

关联查询

示例
在这种表的关系下,由用户查询订单是一对多关联查询,由订单查询用户是一对一关联查询
一对一查询
有多种方式使用一对一关联查询
方式一 创建新的POJO并使用resultType来作为输出类型
示例
由订单查询该订单对应用户
新建POJO如下
SQL如下
Mapper接口方法
测试代码
执行结果
方式一 定义专门POJO作为输出类型,其中定义了SQL查询觉过集的所有字段,这种方法较为简单,企业中使用普遍
方式二
使用resultMap作为输出类型,定义专门的resultMap用于映射一对一的查询结果
首先改造POJO类
在Orders类中加入类型为User的属性,用于存储关联查询的用户信息,因为是一对一,所以使用单个User对象作为属性
修改映射文件,定义resultMap并使用
注意:关联查询不可以省略同名的属性/字段定义,否则无法映射
具体为当resultMap标签中出现association或collection标签时不可以省略同名属性/字段定义
最后测试,得到结果为
一对多查询
示例:查询所有用户信息以及用户关联的订单信息
用户信息对订单信息是一对多关系
映射文件如下(重要)
修改User类,增加Orders类属性
注意上文修改Orders类增加了user属性,但若在这个一对多查询中,ordersList内的Orders对象中user属性是null的,应该避免出现NPE
测试结果如下
*总结resultMap通常的标签组成
而resultMap需要根据具体SQL来确定每个column的名称,若使用了别名,则使用别名

MyBatis整合Spring

整合思路
  • SqlSessionFactory对象应该放到Spring容器中作为单例存在
  • 传统Dao的开发方式中,应该从Spring容器中获得SqlSession对象
  • Mapper代理形式中,应该从Spring容器中直接获得Mapper的代理对象
  • 数据库的连接以及数据库连接池事务管理都交给Spring容器来完成
整合步骤
导入需要的依赖
  • Spring的jar包
  • MyBatis的jar包
  • Spring+MyBatis的整合包。
  • MySql的数据库驱动jar包。
  • 数据库连接池的jar包
创建配置文件
  • 数据库连接及连接池
  • 事务管理(暂时可以不配置)
  • SqlSessionFactory对象,配置到Spring容器中
  • Mapper接口代理对象或者是Dao实现类配置到Spring容器中
整合步骤详见附件
整合完毕后继续查看下面的内容
Spring与MyBatis整合后Dao的开发
有两种Dao的开发方式
  • 传统的Dao开发方式
  • 使用Mapper代理的方式
    • 直接配置Mapper代理
    • 使用扫描包配置Mapper代理
传统Dao开发方式
通过编写Dao接口和其实现类来完成
Dao实现类 必须继承SqlSessionDaoSupport类来通过Spring注入SqlSessionFactory依赖
在applicationContext文件配置Dao的bean注入
然后编写/配置POJO、Mapper映射文件和Mapper接口最后配置核心配置文件后,测试是否整合成功
详见附件
直接配置Mapper代理方式式开发Dao
这种方式通过在applicationContext文件中配置Mapper接口来提供接口的代理实现类
测试代码
注意测试向Spring获取对象时可以使用类.class类型也可以使用id来获取
package com.zella.mybatis.test;

import com.zella.mybatis.mapper.UserMapper;
import com.zella.mybatis.pojo.User;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Date;
import java.util.List;

public class UserMapperTest {
    private ApplicationContext context;

    @Before
    public void setUp() {
        this.context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    }

    @Test
    public void testQueryUserById() {
        UserMapper userMapper = this.context.getBean(UserMapper.class);
        System.out.println(userMapper.queryUserById(1));
    }

    @Test
    public void testQueryUserByUsername() {
        // 获取Mapper
        UserMapper userMapper = this.context.getBean(UserMapper.class);

        List<User> list = userMapper.queryUserByUsername("张");

        for (User user : list) {
            System.out.println(user);
        }
    }
    @Test
    public void testSaveUser() {
        // 获取Mapper
        UserMapper userMapper = this.context.getBean(UserMapper.class);

        User user = new User();
        user.setUsername("曹操");
        user.setSex("1");
        user.setBirthday(new Date());
        user.setAddress("三国");

        userMapper.saveUser(user);
        System.out.println(user);
    }
}

使用扫描包形式配置Mapper方式开发Dao

这种方法通过在applicationContext文件配置扫描Mapper接口所在包来自动配置Mapper接口获取其代理类对象
这种方式的优点在于当Mapper接口很多时不再需要一个一个配置Mapper接口
注意:id就是Mapper类的类名
使用前一个方式的测试代码测试即可

MyBatis逆向工程

当数据库中表的数量很多时,手动编写POJO、映射文件和Mapper接口的工作就变得十分繁复
而MyBatis逆向工程可以方便的从数据库中将表自动映射到Java POJO类,并同时生成Mapper.xml和Mapper接口
详见附件,或自查网络资源
可以参考

*拓展内容

各种类型类的定义

PO与VO
 
 
 
 
DO
domain object持久对象
就是从现实世界中抽象出来的有形或无形的业务实体。
PO
persistant object持久对象
最形象的理解就是一个PO就是数据库中的一条记录。
好处是可以把一条记录作为一个对象处理,可以方便的转为其它对象。
BO
business object业务对象
主要作用是把业务逻辑封装为一个对象。这个对象可以包括一个或多个其它的对象。
比如一个简历,有教育经历、工作经历、社会关系等等。
我们可以把教育经历对应一个PO,工作经历对应一个PO,社会关系对应一个PO。
建立一个对应简历的BO对象处理简历,每个BO包含这些PO。
这样处理业务逻辑时,我们就可以针对BO去处理。
VO
Value Object值对象
View Object表现层对象
主要对应界面显示的数据对象。对于一个WEB页面,或者SWT、SWING的一个界面,用一个VO对象对应整个界面的值。
DTO
Data Transfer Object数据传输对象
主要用于远程调用等需要大量传输对象的地方。
比如我们一张表有100个字段,那么对应的PO就有100个属性。
但是我们界面上只要显示10个字段,
客户端用WEB service来获取数据,没有必要把整个PO对象传递到客户端,
这时我们就可以用只有这10个属性的DTO来传递结果到客户端,这样也不会暴露服务端表结构.到达客户端以后,如果用这个对象来对应界面显示,那此时它的身份就转为VO
POJO
plain ordinary java object 简单ava对象
个人感觉POJO是最参见最多变的对象,是一个中间对象,也是我们最常打交道的对象。
一个POJO持久化以后就是PO
直接用它传递、传递过程中就是DTO
直接用来对应表示层就是VO
DAO
data access object数据访问对象
这个大家最熟悉,和上面几个O区别最大,基本没有互相转化的可能性和必要.
主要用来封装对数据库的访问。通过它可以把POJO持久化为PO,用PO组装出来VO、DTO

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

 
 
 
 

附件列表

转载于:https://www.cnblogs.com/zella1996/p/9550474.html

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐