Mybatis学习总结一

1.MyBatis简介

  MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进。  

  MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

  Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

  MyBatis架构图如下:

  (1)mybatis配置

  SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。

  mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。

  (2) 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂。

  (3) 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。

  (4)mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。

  (5) Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sqlid即是Mapped statementid

  (6) Mapped Statementsql执行输入参数进行定义,包括HashMap、基本类型、pojoExecutor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。

  (7) Mapped Statementsql执行输出结果进行定义,包括HashMap、基本类型、pojoExecutor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

2.映射文件

<mapper namespace="user">
     <select id="findUserById" parameterType="int" resultType="com.luchao.mybatis.first.po.User">
         select * from user where id = #{id}
     </select>
</mapper>

namespace :命名空间,对sql进行分类化管理,用于隔离sql语句。

id:和namespace 一起标识statement。

parameterType:定义输入到sql中的映射类型,#{id}表示使用preparedstatement设置占位符号并将输入变量id传到sql

 resultType:定义结果映射类型。

3.#{}与${}
     #{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。

    ${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value

4.添加并返回主键

如果mysql是自增主键,映射文件如下:

insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
        <!-- selectKey将主键返回,需要再返回 -->
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            select LAST_INSERT_ID()
        </selectKey>
       insert into user(username,birthday,sex,address)
        values(#{username},#{birthday},#{sex},#{address});
</insert>
添加selectKey实现将主键返回

keyProperty:返回的主键存储在pojo中的哪个属性

orderselectKey的执行顺序,是相对与insert语句来说,由于mysql的自增原理执行完insert语句之后才将主键生成,所以这里selectKey的执行顺序为after

resultType:返回的主是什么类型

LAST_INSERT_ID():mysql的函数,返回auto_increment自增列新记录id值。

如果mysql是UUID实现,映射文件如下:

<insert  id="insertUser" parameterType="cn.luchao.mybatis.po.User">
	<selectKey resultType="java.lang.String" order="BEFORE" keyProperty="id">
		select uuid()
	</selectKey>
	insert into user(id,username,birthday,sex,address) 
         values(#{id},#{username},#{birthday},#{sex},#{address})
</insert>

注意这里使用的order是“BEFORE”。
Oracle使用序列实现,映射文件如下:

<insert  id="insertUser" parameterType="cn.luchao.mybatis.po.User">
	<selectKey resultType="java.lang.Integer" order="BEFORE" keyProperty="id">
		SELECT 自定义序列.NEXTVAL FROM DUAL
	</selectKey>
	insert into user(id,username,birthday,sex,address) 
         values(#{id},#{username},#{birthday},#{sex},#{address})
</insert>

注意这里使用的order是“BEFORE”。

5.MyBatis与Habernate的比较

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

    Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。专注是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全 的ORM框架,可以简单理解为SQL Mapper,虽然程序员自己写sqlmybatis 也可以实现映射(输入映射、输出映射)。应用场景:适用与需求变化较多的项目,比如:互联网项目。 

    Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。是一个标准ORM框架(对象关系映射)。入门门槛较高的,不需要程序写sqlsql语句自动生成了,sql语句进行优化、修改比较困难的。应用场景:适用与需求变化不多的中小型项目,比如:后台管理系统,erpormoa

6.Mapper动态代理方式

(1)实现原理

  Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。这样通过动态代理就实现了将模板方法进行封装,只需要实现具体的实现即可。 

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

a、 Mapper.xml文件中的namespacemapper接口的类路径相同。

b、 Mapper接口方法名和Mapper.xml中定义的每个statementid相同 。

c、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql parameterType的类型相同。

d、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sqlresultType的类型相同。

(2)Mapper.xml(映射文件)

映射文件与原始Dao开发的映射文件相似,只需要将namespace定于为mapper接口全路径。

<?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="com.luchao.mybatis.first.mapper.UserMapper">
    <!-- 根据id获取用户信息 -->
    <select id="findUserById" parameterType="int" resultType="user">
        select * from user where id = #{id}
    </select>
    <!-- 根据username模糊查询用户信息 -->
    <select id="findUserByName" parameterType="java.lang.String" resultType="com.luchao.mybatis.first.po.User">
        select * from user where username like '%${value}%'
    </select>
    <!-- 添加用户信息 -->
    <insert id="insertUser" parameterType="com.luchao.mybatis.first.po.User">
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            select LAST_INSERT_ID()
        </selectKey>
        insert into user(username,birthday,sex,address) value (#{username},#{birthday},#{sex},#{address});
    </insert>
    <!-- 根据id删除用户信息 -->
    <delete id="deleteUser" parameterType="int">
        delete from user where id=#{id}
    </delete>
    <!-- 修改用户信息 -->
    <update id="updateUser" parameterType="com.luchao.mybatis.first.po.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
        where id=#{id}
    </update>
</mapper>
(3)Mapper.java(接口文件)
public interface UserMapper {
    //根据ID查询用户信息
    public User findUserById(int id) throws Exception;
    //添加用户信息
    public void insertUser(User user) throws Exception;
    //删除用户信息
    public void deleteUser(int id) throws Exception;
    //更新用户信息
    public void updateUser(User user) throws Exception;
    //根据用户名模糊查找
    public List<User> findUserByName(String user) throws Exception;
}
接口定义有如下特点:

a、 Mapper接口方法名和Mapper.xml中定义的statement的id相同。

b、 Mapper接口方法的输入参数类型和mapper.xml中定义的statement的parameterType的类型相同。

c、 Mapper接口方法的输出参数类型和mapper.xml中定义的statementresultType的类型相同。

Mapper动态代理总结:

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

b、使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。在系统中,dao层的代码是被业务层公用的。即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。

注意:持久层方法的参数可以包装类型、 map 等, service 方法中建议不要使用包装类型(不利于业务层的可扩展)。

  mybatis开发dao的方法有两种:原始Dao开发和Mapper动态代理开发,这两种各有优点。原始Dao开发:程序员要写Dao和Dao实现,需要些较多的代码,但是比较好理解。Mapper动态代理:程序员只需要写Mapper接口,然后按照规范进行配置,MyBatis就会自动实现类似Dao实现,减少模板方法。mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值