Mybatis(1) 初识

版权声明:转载需经同意,谢谢! https://blog.csdn.net/Big_KK/article/details/82193091

Mybatis实现入门级的简单增删改查

与Hibernate类似,MyBatis也是一个持久层的框架,关于该框架的类型,介绍有很多,这里就不再赘述。因为是初次接触,所以遵循一个循序渐进的过程,先使用该框架实现最基本的配置操作。对其中使用到的对象以及配置过程先做出简单的说明。后续随着学习的深入对特定知识再做出详细的总结。

本文仅使用一个简单的实体类User作为操作对象。仅包含两个属性:id以及name,并在数据库建立了与之对应的表。

1.准备

  1. 下载Mybatis框架,且框架的zip包里面已经包含了所需要的依赖包。新建工程进行导入。简单的常规流程。
  2. 建立实体类,以及数据库和对应表。

2.配置Mybatis属性文件

与Hibernate一样,对于Mybatis,也是需要进行配置文件的设置的。但是在Mybatis里面。对属性的文件名以及其存放位置并没有做硬性的要求。而Mybatis的属性配置,它决定了Mybatis与数据库的连接信息以及数据源等信息。同样的,所建立的映射文件也是需要在这个文件里面引入的。下面是一个简单的配置实例:

<?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>

  <environments default="development">
    <environment id="development">

        <!--使用JDBC事务管理,由Mybatis控制-->
      <transactionManager type="JDBC"/>

      <!--指定使用的数据源,由Mybatis管理,有以下的几个可选值 -->
      <!-- POOLED 表示支持JDBC数据源连接池 -->
      <!-- UNPOOLED 表示不支持数据源连接池 -->
      <!-- JNDI 表示支持外部数据源连接池 -->
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis_test"/>
        <property name="username" value="root"/>
        <property name="password" value="131421"/>
      </dataSource>

    </environment>
  </environments>

  <!--加载配置文件, resource属性是以src为开始路径, 此处对User的映射文件为UserMapper.xml-->
  <mappers>
    <!--添加一个具体的映射文件-->
    <mapper resource="config/sqlMap/UserMapper.xml"/>
    <!-- 指定目录,将自动添加该目录下的所有映射文件 -->
    <package name="config/sqlMap"/>
  </mappers>
</configuration>

3.配置实体类(User)的映射文件

在Mybatis里面,映射文件不是像Hibernate那样仅仅只是建立二者的关系而已。它可以用来建立一个针对一个特定接口的实现规则,描述其实现方法的具体形式。这里先侧重于了解如何编写方法的实现规则。对其映射关系先不做深入。

<?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代理的形式,所以先名为Test -->
<mapper namespace="Test">
       <!--
        建立一个指定功能(insert、update,delete,select)的标签,并设定其属性,后续在映射接口方法的时候,根据该标签调用SqlSession的不同方法
        然后该select标签体的SQL语句会被渲染为一个MappedStatement对象。
        该MappedStatement对象的引用标识就是select标签的id
        后续在SqlSession对象在进行查找等操作的时候,需要指定使用哪个MappedStatement对象来进行操作,指定方法:【命名空间.id名称】
        id : 
            该SQL语句将会封装到MappedStatement对象里面。id用于标识封装本SQL语句的对象
        #{ }
            表示一个占位符,传递进来的变量会首先尝试进行计算,然后在填充到语句里面,比如:#{ 3-1}
            其内部的变量名可以任意, 
            可以接收简单数据类型,实体类以及集合类
            传递实体类的话可以直接写为:#{ 属性 } 来获取这个实体类的某个属性
        ${ }
            仍表示一个拼接符,内部的变量名必须是value。在调用的时候,调用的值会原封不动的传递进来而不进行运算。
            如果传递的值要原封不动的应用在一个字符串内部,
            如果传递的是简单的数据类型,那么必须使用${ value } 
        parameterType:
            指定输入参数的类型, 可以是简单类型,也可以是实体类或集合
        resultType:
            指定【单条记录】的存储类型,即便查询语句得到的结果是多条信息,还是要使用单条信息的数据类型
            如果所查的信息是对象,则指定其全路径。
            以下的两个查询语句都可能会返回多条信息,但是每条信息都是一个User对象,所以resultType = User。
    -->

      <!--
        示例:
            针对User接口实现一个“方法”,名称为selectUserByName, 传递给其一个String类型的参数,它将返回一个User对象或一个包含User对象对的集合
      -->
      <select id="selectUserByName" resultType="domain.User" parameterType = "java.lang.String">
            select * from tb_user where name like '%${value}%' 
      </select> 
      <select id="selectUserById" resultType="domain.User" parameterType="int">
            select * from tb_user  where id = ${value}
      </select>

      <!-- 
                当传递的对象不再是简单的数据类型的时候,比如插入,传递的就是一个User实体类对象。
            那么可以使用下面的方法进行设置,其中占位符里面分别对应的是User里面的各个属性,
            后续在传入一个User对象的时候,占位符的会自动解析出该对象所包含的各个属性并添加到指定位置

                在进行插入操作的时候,可以获取插入之后该条记录的主键值,可以使用select LAST_INSERT_ID(); 
            但仅适用于主键自增的情况下。

                使用selectKey标签,来操作所传入实体类的。使用keyProperty选择要操作的具体属性
            order表示在何时执行。AFTER指的是在执行完insert标签体的insert语句之后再执行,BEFORE则是之前。
            resultType指的是操作完返回结果的类型。

                同样以下面的插入标签为例。在执行完insert插入的操作之后,再执行selectKey标签的内容,
            获取所传递的实体类,执行SELECT LAST_INSERT_ID()获取上次插入时所使用的主键值,并作为结果
            返回给所操作实体类的id属性,这样的话,在外部就可以使用getID()来获取本条语句插入时候所使用的主键。

                而对应非自增的主键,当要设置其主键的时候,可以选择在程序自己指定,也可以使用函数 UUID() 来生成一个主键。
            采用此方法的时候,主键的类型就需要调整为String类型。并且使用selectKey标签,设置order为BEFORE, 因为
            要在进行插入之前获取一个ID, 然后设置给传递进来的实体,最后再持久化到数据库。

                在其标签体内部使用 select UUID() 从数据库获取一个主键,并返回给所传递进来的User实体的id属性。
            然后再执行insert语句,此时所设置的id就是UUID() 获取到的主键了
         -->
        <insert id="insertUser"  parameterType = "domain.User">
                <selectKey keyProperty="id" order="AFTER" resultType="int">
                    SELECT LAST_INSERT_ID()
                </selectKey>
                insert into tb_User values (#{id}, #{name});
        </insert>

        <!--同样的步骤设置删除与更新的操作-->
        <delete id="deleteUser" parameterType = "java.lang.Integer">
            delete from tb_User where id =#{id};
        </delete>
        <update id="updateUser" parameterType = "domain.User">
            update tb_user set  name = #{name} where id = #{id}; 
        </update>
</mapper>

4.使用映射文件所定义的‘方法’进行操作

Mybatis进行操作时候,各个类之间的简单关系流程如下图所示,操作的时候,所进行的过程也与之相对应:
这里写图片描述

这里先不使用mapper代理对象的形式调用。

@Test
    public void test(){
        InputStream is = null;
        SqlSessionFactory sqlSessionFactory = null;
        SqlSession sqlSession = null;
            try {
                //获取配置文件
                is = Resources.getResourceAsStream("config/SqlMapConfig.xml");
                //构建工厂
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
                //获取SqlSession
                sqlSession = sqlSessionFactory.openSession();

                /*
                 * 查询一条结果,第一个变量用于确定所要执行哪个命名空间的哪个标签语句,
                 * 此处的Test.selectUserById就是为User接口实现的方法之一,这里是直接调用
                 * 第二个就是所指定的参数值,类型要与在标签建立语句时候指定的一致。
                 * selectOne()查询一条结果,返回的结果就是建立标签是所指定的结果类型
                 * */
                User user1 = sqlSession.selectOne("User.selectUserById", 1);
                System.out.println(user1.toString());

                /*
                 * 查询多条结果
                 * 参数同上,selectList()用于查询一个集合,结果集里面的每个对象与建立标签时候所指定的输出对象类型一致
                 * */
                List<User> list = sqlSession.selectList("Test.selectUserByName", "大");
                System.out.println(list);

                /*
                 * 删除信息
                 * */
                sqlSession.delete("Test.deleteUser", 14);
                sqlSession.commit();

                /*
                 * 插入信息
                 * */
                User user3 = new User();
                user3.setName("嘻嘻嘻");
                sqlSession.insert("Test.insertUser", user3);
                sqlSession.commit();
                System.out.println(user3.getId());

                /*
                 * 修改信息
                 * */
                User user4 = new User();
                user4.setId(5);
                user4.setName("嘿嘿");
                sqlSession.update("Test.updateUser", user4);
                sqlSession.commit();

            }catch(IOException e) {
                    throw new IOException();
            }finally {
                sqlSession.close();
            }
    }

简单总结下,在进行调用的时候,首先就是确定所要使用哪个命名空间下哪个操作,然后传入与设定标签所对应的操作,并进行接收。在进行除查询之外的操作后,需要进行提交。当然后续会直接使用mapper代理对象来调用所设置的方法。不需要这种形式的调用。此处只是为了描述映射文件的写法


Mybatis进行基本的映射文件编写大致如此。第一次接触,对一些概念性的问题还是更多的还是处于一知半解的状态,随着后续学习的深入,再对之前文章中存在疑问或理解错误的地方进行更改。

猜你喜欢

转载自blog.csdn.net/Big_KK/article/details/82193091