Mybatis简单入门

版权声明:其实并没有什么特别声明,多评论给博主提提意见就行啦! https://blog.csdn.net/qq_38982845/article/details/83003974

一. Mybatis 简述

MyBatis 本是 apache 的一个开源项目 iBatis, 2010 年这个项目由apache software foundation 迁移到了 google code, 并且改名为 MyBatis 。2013 年 11 月迁移到 Github。iBATIS 一词来源于“internet” 和“abatis” 的组合, 是一个基于 Java的持久层框架。

iBATIS 提供的持久层框架包括 SQL Maps 和 Data AccessObjects(DAO)MyBatis 是一个支持普通 SQL 查询, 存储过程和高级映射的优秀持久层框架。 MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索封装。 MyBatis 可以使用简单的 XML 或注解用于配置和原始映射, 将接口和 Java 的 POJO(Plain Old Java Objects, 普通的 Java 对象) 映射成数据库中的记录。

mybatis 不是一个完全的 orm 框架, Mybatis 需要程序员自己写 sql, 但是也存在映射(输入参数映射, 输出结果映射) , 学习门槛 mybatis 比hibernate 低; 同时灵活性高, 特别适用于业务模型易变的项目, 使用范围广。简单概括:更加简化 jdbc 代码,简化持久层,sql 语句从代码中分离,利用反射,将表中数据与 java bean 属性一一映射 即 ORM(Object RelationalMapping 对象关系映射)

使用范围:在日常的开发项目中, 如中小型项目, 例如 ERP,需求与关系模型相对固定建议使用 Hibernate, 对于需求不固定的项目, 比如: 互联网项目, 建议使用 mybatis, 因为需要经常灵活去编写 sql 语句。 总之, mybatis 成为当下必须学习掌握的一个持久层框架。

MyBatis 功能架构图:

从上面我们可以看到 mybatis 的功能架构分为三层:
                  API 接口层:提供给外部使用的接口 API,开发人员通过这些本地 API 来操纵数据库。接口层接收到调用请求就会调用数据处理层来完成具体的数据处理。

     数据处理层:负责具体的 SQL 查找、SQL 解析、SQL 执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。

   基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

MyBatis 框架体系结构:
 

扫描二维码关注公众号,回复: 3865859 查看本文章

 

二.Mybatis 环境搭建

1.新建 Maven 项目

新建 maven 项目 ,pom 文件添加依赖 jar

<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

    <!-- mybatis jar 包依赖 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.1</version>
    </dependency>
    <!-- 数据库驱动 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.39</version>
    </dependency>
    <!-- log4j 日志打印 -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.16</version>
    </dependency>

2.log4j 日志添加

在 src/main/resources 资源包下添加 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

3.resources 目录下主配置文件添加

新建 mybatis.xml 文件, 并加入配置信息如下(数据库名mybatis,表 user):

<?xml version="1.0" encoding="UTF-8" ?>
<!-- mybatis 框架头文件声明, 类似 spring 环境, 均需要加入头文件 -->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 添加数据库连接相关配置信息 -->
<configuration>

    <properties resource="jdbc.properties"></properties>

    <typeAliases>
        <!-- 配置别名 -->
        <!--形式:
        1. 通过xml
        2. 通过注解
        3. 扫描包
        -->
        <!-- 规则:
         以类名首字母小写进行命名, User -> user
         -->
        <package name="com.shsxt.vo"/>
    </typeAliases>

    <environments default="development">
<environment id="development">
<!-- 加入事务控制 -->
<transactionManager type="jdbc" />
<!-- 配置数据库连接信息 -->
<dataSource type="pooled">
<!--<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
<property name="username" value="root" />
<property name="password" value="root" />-->
    <!--里面的driver,url,username,password
        为框架规定的名字,不能自定义,后面的名字对应properties文件的名字
    -->
<property name="driver" value="${drive}"/>
<property name="url" value="${url}"/>
<property name="username" value="${user}"/>
<property name="password" value="${pwd}"/>

</dataSource>
</environment>
</environments>
    <!-- mapper 配置文件指定 文件数量可配置多个-->
<mappers>
    <!--基于xml配置-->
    <!--<mapper resource="com/shsxt/mapper/UserMapper.xml" />-->

    <!--基于注解-->
    <!--<mapper class="com.shsxt.mapper.UserMapper.xml"></mapper>-->
    <!--包扫描-->
    <package name="com.shsxt.mapper"/>

</mappers>
</configuration>
    

4.映射文件添加

新建 UserMapper.xml 配置文件
 

<?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">
<!--
1.命名空间配置 全局唯一 包名+文件名
2.配置 Mapped Statement
3. statement 配置
id 值声明 statement 编号 同一命名空间(同一文件)下不可重复
parameterType 输入参数即占位符的数据类型 类型可以是 基本数据类型,字符
串,java bean ,map,list 等
resultType 输出结果 类型可以是基本数据类型,字符串,java bean,map 等
statement 描述 即待执行的 sql
#{id} 占位符 变量名为 id/value 均可 ${value} 变量名必须为 value 字符
串拼接形式 无法避免 sql 注入
-->

<!--通过用户Id查询记录,where user_id=#{user_id}#里面的为形参,可为任意值-->
<mapper namespace="com.shsxt.mapper.UserMapper">

    <!--通过名字查询某条记录-->
    <select id="queryUserById" parameterType="int"
            resultType="com.shsxt.vo.User">
    select
       user_id, user_name ,user_pwd from tb_user where user_id=#{user_id}
    </select>

    <!-- 通过名字和id查找 -->
    <select id="queryUserByName" parameterType="string"
            resultType="user">
        select * from tb_user where user_name=#{user_name}
    </select>

    <!-- 通过用户查找 -->
    <select id="queryUserByNameAndId" parameterType="map"
            resultType="user">
        select * from tb_user where user_name=#{user_name} and user_id=#{user_id}
    </select>

    <!-- 查找用户总数-->
    <select id="queryUserByUser" parameterType="user">
        select * from tb_user where user_name=#{user_name} and user_id=#{user_id}
    </select>

    <!-- 添加不返回ID -->
    <select id="queryUserTotal" resultType="int">
        select count(1) from tb_user
    </select>

    <!-- 添加记录返回ID -->
    <insert id="addUser" parameterType="user" useGeneratedKeys="true" keyProperty="user_id">
        insert into tb_user (user_name, user_pwd, user_age)
        values (#{user_name}, #{user_pwd}, #{user_age})
    </insert>

    <!-- 添加一条记录返回ID -->
    <insert id="addUserReturnId" parameterType="list" useGeneratedKeys="true" keyProperty="user_id">
        insert into tb_user (user_name, user_pwd, user_age)
        values (#{item.user_name}, #{item.user_pwd}, #{item.user_age})
    </insert>

    <!-- 批量添加记录返回ID -->
    <insert id="addUserBatchReturnId" parameterType="list" useGeneratedKeys="true" keyProperty="user_id">
        insert into tb_user (user_name, user_pwd, user_age)
        values
        <foreach collection="list" item="item" separator=",">
            (#{item.user_name}, #{item.user_pwd}, #{item.user_age})
        </foreach>
    </insert>

    <!-- 更新 -->
    <update id="updateUser" parameterType="user" useGeneratedKeys="true" keyProperty="user_id">
        update tb_user set user_name=#{user_name}, user_pwd=#{user_pwd},user_age=#{user_age}
        where user_id=#{user_id}
    </update>

    <!-- 批量更新密码 -->
    <update id="updateUserPwdBatch">
        update tb_user set user_pwd=888888
        where user_id between
        <foreach collection="array" item="item" separator="and">
            #{item}
        </foreach>
    </update>

    <!-- 删除,根据Id -->
    <delete id="deleteUser" parameterType="int">
        delete from tb_user where user_id = #{user_id}
    </delete>

    <!-- 批量删除,根据Id -->
    <delete id="deleteUserBatch" parameterType="list">
        delete from tb_user where user_id in (
            <foreach collection="array" item="item" separator=",">
                #{item}
            </foreach>
        )
    </delete>

    <!--___________使用SQL片段方法_________________-->

    <resultMap id="userMap" type="user">
        <id column="user_id" property="user_id"></id>
        <result column="user_name" property="user_name"></result>
        <result column="user_pwd" property="user_pwd"></result>
        <result column="user_age" property="user_age"></result>
    </resultMap>

    <sql id="base">
        user_id, user_name, user_pwd, user_age
    </sql>
    <select id="queryUserByParams" parameterType="string" resultMap="userMap">
        select <include refid="base"/> from tb_user
        where user_name like concat('%',#{user_name},'%')
    </select>



</mapper>

修改 pom 配置,设置资源文件夹路径

<build>
      <resources>
          <resource>
              <directory>src/main/resources</directory>
          </resource>
          <resource>
              <directory>src/main/java</directory>
              <includes>
                  <include>**/*.properties</include>
                  <include>**/*.xml</include>
              </includes>
              <filtering>false</filtering>
          </resource>
      </resources>
  </build>

5.测试

//定义个UserMapperImpl类型的实例
    private UserMapperImpl userMapper;
    
    //before相当于全局变量,提前加载
    @Before
    public void before() throws IOException {
        
        //得到输入流
        InputStream inp = Resources.getResourceAsStream("mybatis.xml");

        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inp);
        //得到实例
        userMapper = new UserMapperImpl(sqlSessionFactory);
    }
    
    @Test
    public void queryUserById(){

        User user = userMapper.queryUserById(1);
        System.out.println(user);
    }

三.Mybatis 配置文件解释

1.typeAliases:

类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。例如:Configuration 标签下添加

<typeAliases>
    <typeAlias alias="User" type="com.shsxt.mybatis.vo.User" />
</typeAliases>

修改 UserMapper.xml 文件
 

<mapper namespace="com.shsxt.mybatis.mapper.UserMapper">
    <select id="queryUserById" parameterType="int "resultType="User">
        select id,userName,userPwd from user where id=#{id}
    </select>
</mapper>

也可以指定一个包名(大家最喜欢的方式),MyBatis 会在包名下面搜索需要的 JavaBean,也可以指定一个包名(大家最喜欢的方式),MyBatis 会在包名下面搜索需要的 JavaBean,比如:

<typeAliases>
<!-- <typeAlias alias="User" type="com.shsxt.mybatis.vo.User" /> -->
<package name="com.shsxt.mybatis.vo"/>
</typeAliases>

2.typeHandlers 类型处理器

无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java类型。下表描述了一些默认的类型处理器。

3.配置环境(environments) 配多个数据源(数据库)

MyBatis 可以配置成适应多种环境, 这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。 例如, 开发、 测试和生产环境需要有不同的配置; 或者共享相同 Schema 的多个生产数据库, 想使用相同的 SQL 映射。 许多类似的用例。不过要记住: 尽管可以配置多个环境, 每个 SqlSessionFactory 实例只能选择其一。所以, 如果你想连接两个数据库, 就需要创建两个 SqlSessionFactory 实例, 每个数据库对应一个。 而如果是三个数据库, 就需要三个实例, 依此类推, 记起来很简单:

<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>

<environment id="test">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver2}" />
<property name="url" value="${url2}" />
<property name="username" value="${username2}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>

## development
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&amp;characterEncodi
ng=utf8
username=root
password=root
## test
driver2=com.mysql.jdbc.Driver
url2=jdbc:mysql://127.0.0.1:3306/mybatis2?useUnicode=true&amp;characterEnco
ding=utf8
username2=root
password2=root

4.mappers 映射器(四种配置)

这里是告诉 mybatis 去哪寻找映射 SQL 的语句。可以使用类路径中的资源引用,或者使用字符,输入确切的 URL 引用。这些配置会告诉了 MyBatis 去哪里找映射文件,剩下的细节就应该是每个 SQL 映射文件。

<!— sqlmapper 配置文件路径 -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!—url 绝对路径形式-->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<!—接口 列表配置形式 注解 sql-->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!—映射包下所有接口-->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>

第四种最常用,做简单.

四.Mapper Xml 映射文件

1.Select 元素标签使用

<!--通过用户Id查询记录,where user_id=#{user_id}#里面的为形参,可为任意值-->
<mapper namespace="com.shsxt.mapper.UserMapper">

    <!--通过名字查询某条记录-->
    <select id="queryUserById" parameterType="int"
            resultType="com.shsxt.vo.User">
    select
       user_id, user_name ,user_pwd from tb_user where user_id=#{user_id}
    </select>

    <!-- 通过名字和id查找 -->
    <select id="queryUserByName" parameterType="string"
            resultType="user">
        select * from tb_user where user_name=#{user_name}
    </select>

</mapper>

2.Insert 元素标签使用

<mapper namespace="com.shsxt.mapper.UserMapper">

     <!-- 批量添加记录返回ID -->
    <insert id="addUserBatchReturnId" parameterType="list" useGeneratedKeys="true" keyProperty="user_id">
        insert into tb_user (user_name, user_pwd, user_age)
        values
        <foreach collection="list" item="item" separator=",">
            (#{item.user_name}, #{item.user_pwd}, #{item.user_age})
        </foreach>
    </insert>

</mapper>

3.Update 元素标签使用

<mapper namespace="com.shsxt.mapper.UserMapper">

     <!-- 批量更新密码 -->
    <update id="updateUserPwdBatch">
        update tb_user set user_pwd=888888
        where user_id between
        <foreach collection="array" item="item" separator="and">
            #{item}
        </foreach>
    </update>

</mapper>

4.Delete 元素标签使用

<mapper namespace="com.shsxt.mapper.UserMapper">

    <!-- 批量删除,根据Id -->
    <delete id="deleteUserBatch" parameterType="list">
        delete from tb_user where user_id in (
            <foreach collection="array" item="item" separator=",">
                #{item}
            </foreach>
        )
    </delete>

</mapper>

5.choose, when, otherwise 选择器使用

我们不想用到所有的条件语句,而只想从中择其一二。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句
 

select id="queryUserByParams" parameterType="map" resultType="user">
select id,userPwd
<choose>
<when test="nation!=null and nation!=''">
,userName
</when>
<otherwise>
,realName
</otherwise>
</choose>
from user
where userName like '%${userName}%'
<if test="phone!=null and phone!=''">
and phone like '%${phone}%'
</if>
</select>

6.trim, where, set

对于 update 语句, 我们采用<set></set>去设置值,去除最后一个条件的逗号:

<!--通过名字与年龄查询 __ set的使用-->
    <select id="updateUserByNameAndId_set" parameterType="list">
        update tb_user
            <set>
                <if test="@Ognl@isNotEmpty(user_name)">
                    user_name=#{user_name},
                </if>
                <if test="@Ognl@isNotEmpty(user_age)">
                    user_age=#{user_age},
                </if>
            </set>
        where user_id = #{user_id}
    </select>

where 元素知道只有在一个以上的 if 条件有值的情况下才去插入“WHERE”子句。 而且,若最后的内容是“AND”或“OR”开头的, where 元素也知道如何将他们去除。

<!--通过名字与年龄查询 __ where的使用-->
    <select id="queryUserByNameAndId_where" parameterType="user" resultMap="userMap">
        select * from tb_user
        <where>
            <if test="@Ognl@isNotEmpty(user_name)">
                user_name like concat('%',#{user_name},'%')
            </if>
            <if test="@Ognl@isNotEmpty(user_age)">
                and user_age like concat('%',#{user_age},'%')
            </if>
        </where>
    </select>

如果 where 元素没有按正常套路出牌, 我们还是可以通过自定义 trim 元素来定制我们想要的功能。 比如, 和 where 元素等价的自定义 trim 元素为:

<!--通过名字与年龄查询 __ trim的使用-->
    <select id="queryUserByNameAndId_trim" parameterType="user" resultMap="userMap">
        select * from tb_user
        <trim prefix="where" prefixOverrides="and|or">
            <if test="@Ognl@isNotEmpty(user_name)">
                user_name like concat('%',#{user_name},'%')
            </if>
            <if test="@Ognl@isNotEmpty(user_age)">
                and user_age like concat('%',#{user_age},'%')
            </if>
        </trim>
    </select>

功能性:trim>where and set(上面代码的@Ognl@isNotEmpty(user_name)为一个工具类,调用里面的静态方法),里面的if或foreach可以实现动态的SQL语句.





 

 


 


 


 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 


 


 

猜你喜欢

转载自blog.csdn.net/qq_38982845/article/details/83003974
今日推荐