zoukankan      html  css  js  c++  java
  • Mybatis第六篇【配置文件和映射文件再解读、占位符、主键生成与获取、Mapper代理】

    配置文件和映射文件再解读

    映射文件

    在mapper.xml文件中配置很多的sql语句,执行每个sql语句时,封装为MappedStatement对象,mapper.xml以statement为单位管理sql语句

    Statement的实际位置就等于namespace+StatementId

    配置文件

    别名

    typeAliases别名:

    这里写图片描述

    自定义别名:

    
        <!-- 定义 别名 -->
        <typeAliases>
            <!--
            单个别名的定义
            alias:别名,type:别名映射的类型  -->
            <!-- <typeAlias type="cn.itcast.mybatis.po.User" alias="user"/> -->
            <!-- 批量别名定义
            指定包路径,自动扫描包下边的pojo,定义别名,别名默认为类名(首字母小写或大写)
             -->
            <package name="cn.itcast.mybatis.po"/>
    
        </typeAliases>

    这里写图片描述

    Mapper加载

    
        <mappers>
            <!-- 通过resource引用mapper的映射文件 -->
            <mapper resource="sqlmap/User.xml" />
            <!-- <mapper resource="mapper/UserMapper.xml" /> -->
            <!-- 通过class引用mapper接口 
            class:配置mapper接口全限定名
            要求:需要mapper.xml和mapper.java同名并且在一个目录 中
            -->
            <!-- <mapper class="cn.itcast.mybatis.mapper.UserMapper"/> -->
            <!-- 批量mapper配置 
            通过package进行自动扫描包下边的mapper接口,
            要求:需要mapper.xml和mapper.java同名并且在一个目录 中
    
            -->
            <package name="cn.itcast.mybatis.mapper"/>
        </mappers>

    Mybatis解决JDBC编程的问题

    1、数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

    • 解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。

    2、Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。

    • 解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离

    3、向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。

    • 解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型

    4、对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。

    • 解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型

    占位符

    在Mybatis中,有两种占位符

    • #{}解析传递进来的参数数据
    • ${}对传递进来的参数原样拼接在SQL中

    主键生成策略

    如果我们在Hibernate中,当我们插入数据的时候,我们是可以选择是UUID策略的…

    那么在Mybatis是怎么做的呢??

    UUID

    
        <!-- mysql的uuid生成主键 -->
        <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
            <selectKey keyProperty="id" order="BEFORE" resultType="string">
                select uuid()
            </selectKey>
    
            INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})
        </insert> 

    主键返回

    如果我们一般插入数据的话,如果我们想要知道刚刚插入的数据的主键是多少,我们可以通过以下的方式来获取

    需求:

    • user对象插入到数据库后,新记录的主键要通过user对象返回,通过user获取主键值。

    解决思路:

    • 通过LAST_INSERT_ID()获取刚插入记录的自增主键值,在insert语句执行后,执行select LAST_INSERT_ID()就可以获取自增主键。

    mysql:

        <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
            <selectKey keyProperty="id" order="AFTER" resultType="int">
                select LAST_INSERT_ID()
            </selectKey>
            INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
        </insert>

    oracle:

    实现思路:

    • 先查询序列得到主键,将主键设置到user对象中,将user对象插入数据库。
    
        <!-- oracle
        在执行insert之前执行select 序列.nextval() from dual取出序列最大值,将值设置到user对象 的id属性
         -->
        <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
            <selectKey keyProperty="id" order="BEFORE" resultType="int">
                select 序列.nextval() from dual
            </selectKey>
    
            INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})
        </insert> 

    Mapper代理方式

    Mapper代理方式的意思就是:程序员只需要写dao接口,dao接口实现对象由mybatis自动生成代理对象。

    经过我们上面的几篇博文,我们可以发现我们的DaoImpl是十分重复的…

    1 dao的实现类中存在重复代码,整个mybatis操作的过程代码模板重复(先创建sqlsession、调用sqlsession的方法、关闭sqlsession)

    2、dao的实现 类中存在硬编码,调用sqlsession方法时将statement的id硬编码。


    以前的重复代码和硬编码如下

    
    public class StudentDao {
    
        public void add(Student student) throws Exception {
            //得到连接对象
            SqlSession sqlSession = MybatisUtil.getSqlSession();
            try{
                //映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
                sqlSession.insert("StudentID.add", student);
                sqlSession.commit();
            }catch(Exception e){
                e.printStackTrace();
                sqlSession.rollback();
                throw e;
            }finally{
                MybatisUtil.closeSqlSession();
            }
        }
        public static void main(String[] args) throws Exception {
            StudentDao studentDao = new StudentDao();
            Student student = new Student(3, "zhong3", 10000D);
            studentDao.add(student);
        }
    }

    Mapper开发规范

    想要Mybatis帮我们自动生成Mapper代理的话,我们需要遵循以下的规范:

    1、mapper.xml中namespace指定为mapper接口的全限定名

    • 此步骤目的:通过mapper.xml和mapper.java进行关联

    2、mapper.xml中statement的id就是mapper.java中方法名

    3、mapper.xml中statement的parameterType和mapper.java中方法输入参数类型一致

    4、mapper.xml中statement的resultType和mapper.java中方法返回值类型一致.

    再次说明:statement就是我们在mapper.xml文件中写sql指定的id

    Mapper代理返回值问题

    mapper接口方法返回值:

    • 如果是返回的单个对象,返回值类型是pojo类型,生成的代理对象内部通过selectOne获取记录
    • 如果返回值类型是集合对象,生成的代理对象内部通过selectList获取记录。
  • 相关阅读:
    h5学习
    python 基础(十五) socket编程
    python 基础(十四) 正则表达式
    python 基础(十三) time模块
    python 基础(十二) 图片简单处理
    python 基础(十一) pickle 序列化
    python 基础(十) 面向对象
    python 基础(九) 文件操作
    python 基础(八) os模块
    python 基础(七) 异常处理
  • 原文地址:https://www.cnblogs.com/zhong-fucheng/p/7554351.html
Copyright © 2011-2022 走看看