Java之MyBatis

5 篇文章 0 订阅
3 篇文章 0 订阅

ORM
    对象关系映射,这是一种思想.

JDBC开发步骤
    1)加载数据库的驱动
    2)通过DirverManager获取数据库链接
    3)通过Connection获取Statement/PreparedStatement
    4)将SQL语句绑定到上述对象,准备向数据库发起操作语句
    5)执行完sql语句后,返回对象的结果
    6)处理查询到的结果
    7)依次关闭ResultSet Statement Connection
    如果是非查询操作,记住开启事物支持
        conn.setAutoCommit(false);
        conn.commit()//conn.rollback()

Hibernate开发步骤
    1)加载Configuration对象
    2)加载实体映射文件
    3)通过Configuration对象获取重量级SessionFactory对象
    4)通过SessionFactory对象获取轻量级的session对象
    5)通过session对象创建trsaction对象
    6)执行操作
    7)事物提交
    8)关闭sesion

MyBatis
    这是一个基于JAVA的持久层框架,前身是IBatis。
    MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。
    MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs映射成数据库中的记录。
    
工作流程
    1)通过Reader对象读取src目录下的mybatis.xml配置文件
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
    2)通过SqlSessionFactoryBuilder对象创建SqlSessionFactory对象
        SqlSessionFactory sf = new SqlSessionFactorybuilder().build(reader);
    3)从当前线程中获取SqlSession对象
        SqlSession session = threadLocal.get();
        if(session == null){
            session = sf.openSession();
            threadLocal.set(session);
        }
    4)开启事物(无需操作,自动开启)
    5)通过SqlSession对象读取映射文件中的操作编号,从而读取sql语句
        session.insert("userNameSpace.add");
    6)事物提交
        session.commit();
    7)关闭session,分离SqlSession与当前线程的绑定
        SqlSession session = threadLocal.get();
        if(session != null){
            session.close();
            threadLocal.remove();
        }
mybatis细节:
    (1)在映射文件中书写的update delete insert标签只是一个模板可通用,但是select标签不能与其他的混用
    (2)当实体属性名和数据库字段名完全一致时,<resultMap>映射关系可以省略不写,不一致时,必须明确声明
    (3)当实体属性名和数据库字段名不一致时,返回值类型不能在使用resultType改用resultMap,其值为声明<resultMap>时的id值
    (4)在mybatis的sql中,
        #{id}表示占位符,其中的id表示参数名,如果输入的参数是简单类型,id可以是任意值
        ${value}表示拼接符,将接收到的参数的内容不加修饰的拼到sql中,此操作会引发sql注入问题,当输入的参数为简单类型时,{}中的值只能写为value
    (5)在SQL中,对于主键自增的数据来说,在执行插入语句之后,可以立即通过select LAST_INSERT_ID()获取新增数据的id
        所以在mybatis的insert中,可以利用这一点,再插入语句后,将生成的主键id设回pojo
        <insert parameterType="pojo.User">
            keyProperty将查询到主键的值设置到parameterType指定的pojo的对应属性中
            <selectKey keyProperty="id" resultType="int" order="AFTER">
                SELECT LAST_INSERT_ID()
            </selectKey>
            insert into user(username,sex)value(#{username},#{sex})
        </insert>
        对于非自增的主键使用uuid或者序列
        <selectKey keyProperty="id" resultType="string" order="BEFORE">
            SELECT uuid()
        </selectKey>

mybatis主配置文件:
    properties:加载外部文件
        文件读取优先级:外部文件  <  标签内属性  <  paramType传递过来的属性
    setting:全局参数配置
        mybatis框架可以在运行时调整运行参数
    typeAliases:别名定义
        主要是将映射文件中的输出、输入中的pojo类型参数配在此处,有两种方式:
        <typeAliases>
            <typeAlias type="" alias=""/>单个别名:指定对应的类或接口对应的别名
            <package name=""/>批量别名:mybatis会自动扫描包下的类或接口,将其类名声明为别名
            
        </typeAliases>
    typeHandlers:类型处理器
        mybatis利用typeHandlers完成java类型和jdbc类型之间的转换
    mappers:映射关系加载器,三种方式
        <mappers>
            <mapper resource="*Mapper.xml" />指定要加载xml文件
            <mapper class="*Mapper"/>前提是遵循mapper接口的开发方式,并将xml文件和类文件名称统一,置于同一个目录中
            <mapper package="*Mapper"/>如果想批量加载,只需要写出Mapper类的顶层包名即可
        <mapper>
输入输出映射
    输入输出映射时,可以使用基本类型,hashmap,pojo类
    resultType  VS  resultMap
        resultType只有当数据库字段名和实体属性名一一对应时,才能映射成功
        当数据库字段名和实体属性名不对应时,使用resultMap定义输出
        如果返回结果只有一行一列,可以使用简单类型接收
动态SQL
    (1)where
        select id,name,sal from students
        <where>
            <if test="name != null"> and name = #{name}</if>
            <if test="sal != null"> and sal = #{sal}</if>
        </where>
    (2)set
        update students
        <set>
            <if test="name != null"> name = #{name},</if>
            <if test="sal != null"> sal = #{sal},</if>
        </set>
    (3)foreach
        delete from students where id in
        <foreach collection="array" open="(" close=")"    separator="," item="ids">
            #{ids}
        </foreach>
    (4)sql片段和 trim
        <sql id="key">
        <trim suffixOverrides=",">
            <if test="id!=null">
                id,
            </if>
            <if test="name!=null">
                name,
            </if>
            <if test="sal!=null">
                sal,
            </if>
        </trim>
        </sql>
        <sql id="value">
            <trim suffixOverrides=",">
                <if test="id!=null">
                    #{id},
                </if>
                <if test="name!=null">
                    #{name},
                </if>
                <if test="sal!=null">
                    #{sal},
                </if>
            </trim>
        </sql>
        <insert id="dynaSQLwithInsert" parameterType="cn.itcast.javaee.mybatis.app14.Student">
            insert into students(<include refid="key"/>) values(<include refid="value"/>)
        </insert>

关系映射
    在mybatis中不像hibernate那样有明确的一对多,多对多关系,而是靠自己书写sql语句来完成的,
        这时如果需要在一个resultMap中引入另一个resultMap(两个对象存在关系)使用
        <association property="card" resultMap="cardNameSpace.cardMap" />

延迟加载
    使用resultMap可以完成高级映射,这里借助了association和colleaction,这两个就具备延迟加载的能力
    <association property="card" resultMap="cardNameSpace.cardMap" select="" column="">
    select表示被管理查询的statementId,column表示两个表之间的关联字段名
    mybatis延迟加载默认是关闭的,需要在setting中开启
        lazyLoadingEnabled设为true
        aggressiveLazyLoading设为false

查询缓存
    mybatis提供了查询缓存来减轻数据库的压力,分为一级缓存和二级缓存
    一级缓存:sqlSession级别缓存,在数据库构造sqlSession对象时,就在对象中准备了一个hashMap结构来存储缓存数据,系统默认开启
    二级缓存:mapper级别缓存,多个sqlSession去操作同一个Mapper的sql语句,多个sqlSession共享二级缓存中的数据
            每个mapper都有一个二级缓存,而这个区别是根据namespace来的,也就是说,如果两个mapper的namespace一样,则两个mapper公用一个二级缓存
            二级缓存默认是关闭的,要开启需要在setting中和mapper中都要开启,并且将实体实现序列化接口
    如果对数据库有写操作(更新 删除 新增),当立即执行sqlSession.commit()操作来更新缓存
mybatis的重要API
    sqlSessionFactory:
        重量级接口,单例模式
    sqlSession:
        线程不安全的,最佳应用场合是方法体内

mybatis开发方式:
    (1)原始dao开发方式
        问题:存在大量的模板方法
              调用sqlSession方法时,将statement的id硬编码了
              调用sqlsession方法时传入的变量,由于sqlSession方法使用Object接收参数,无法在编译时校验输入的参数是否有类型错误  
    (2)mapper代理开发方式
        在使用mapper代理开发时,需要遵循一些开发规范
            (1)*Mapper.xml中的namespace为mapper接口的全路径一致
            (2)接口方法的方法名要与xml中的statement的id一致
            (3)接口方法的参数值要与xml中的parameterType指定的类型一致
            (3)接口方法的返回值要与xml中的resultType指定的类型一致
            这样就可以自动生成代理类StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值