Mybatis框架

Mybatis

Mybatis

概述

Mybatis是对jdbc 的封装,为了简化JDBc 的开发,是一个工具(框架)

框架

工具(一堆工具的合集)\半成品软件

官网

Mybatis

三层架构

三层架构

Mybatis入门

  1. 数据库准备

  2. 新建项目(模块)

  3. 导入坐标

  4. logback.xml

    编码:

  5. 配置文件

    mybatis-config.xml

    UserMapper.xml

  6. 代码

    实体类

    编写代码查询

pom.xml

  <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--mybatis 依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.5</version>
        </dependency>


        <!--mysql 驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
            <scope>runtime</scope>
        </dependency>

        <!--junit 单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
        <!-- 添加slf4j日志api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.20</version>
        </dependency>
        <!-- 添加logback-classic依赖 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- 添加logback-core依赖 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
    </dependencies>

mybatis-config.xml

<?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:配置数据库连接环境信息。可以配置多个environment,通过default属性切换不同的environment
    -->
    <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:///mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--加载sql映射文件-->
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>

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

<!--
    namespace:名称空间
-->
<mapper namespace="test">

    <select id="selectAll" resultType="com.itheima.pojo.User">
        select * from tb_user;
    </select>

    <select id="selectById" resultType="com.itheima.pojo.User">
        select * from tb_user where id = #{id};
    </select>
</mapper>

Mybatis入门步骤

public static void main(String[] args) throws IOException {

        //1. 加载mybatis的核心配置文件,获取 SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);

        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2. 获取SqlSession对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3. 执行sql
        List<User> users = sqlSession.selectList("test.selectAll");
        System.out.println(users);
        //4. 释放资源
        sqlSession.close();
    }

Mybatis原理

Mybatis原理

接口开发

XXXXMapper.xml 注意事项

  1. Mapper.xml 的 namespace 必须和接口的名称保持一致

  2. Mapper.xml 的id 必须和 接口的方法名称保持一致

  3. 返回值resultType=“com.itheima.pojo.User” 必须和返回值类型一致(泛型类型一致)

  4. 请求参数类型必须课方法参数一致

  5. 为了方便加载: 配置文件名和接口的名称一致,并且编译后在同一个文件夹

    <mappers>
      <!--Mapper代理方式-->
      <package name="com.xxx.mapper"/>
    </mappers>
    
  6. 接口中的方法不允许重载

注意

在resources 文件夹创建 多级文件夹问题: 必须用斜杠 : 例如 com\xxx\mapper

核心配置文件

  1. 起别名

    默认 TypeAliasRegistry 有别名

  2. 可以使用 typeAliases 自定义别名(不区分大小写)

  3. environments 配置数据库链接

  4. mappers 加载 xml 映射文件

插件 MybatisX

帮助开发

MybatisX

Lombok 插件

简化实体类的Get,Set,toString…方法

  <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
  </dependency>

Lombok 插件

@Data // set,get,tostring
@AllArgsConstructor // 全参数构造
@NoArgsConstructor // 无参数构造

XXXMapper.xml

sql 片段

方便代码的编写,重复的sql 语句 (片段)只写一次即可

	<!-- 抽取 -->
   <sql id="sql2">
        id,bbrand_name,company_name,ordered
    </sql>
	<!-- 使用 -->
    <select id="selectAll" resultMap="brandResultMap" >
        select <include refid="sql2"/>  from tb_brand;
    </select>
     <insert id="insert"  >
        insert into tb_brand  (<include refid="sql2"/>) values (.....)
    </insert>

字段不一致问题

java 实体类属性和数据库字段名称不一致

字段不一致问题

解决方法1
起别名
  <select id="selectAll" resultMap="brandResultMap" >
        select id, brand_name as brandName, company_name as companyName, ordered, description, status from tb_brand
    </select>
缺点

可读性差,可维护性差

解决方案2
使用resultMap
 <resultMap id="map1" type="com.itheima.pojo.Brand">
        <id  property="id"  column="id" ></id>
        <result property="brandName" column="brand_anme"></result>
        <result property="companyName" column="company_name"></result>
        <result property="ordered" column="ordered"></result>
        <result property="description" column="description"></result>
        <result property="status" column="status"></result>
    </resultMap>
    <select id="selectAll"  resultMap="map1" >
        select * from tb_brand
    </select>

resultMap

特殊字符处理

    &lt; < 小于
    
    &gt; > 大于

    <![CDATA[
            xxxx
     ]]>

占位符#{},${} 区别

<select id="selectById1"  resultMap="brandResultMap">
        select *
        from tb_brand where id = #{id};
    </select>
#{}

执行SQL时,会将 #{} 占位符替换为?,将来自动设置参数值。底层使用的是 PreparedStatement (开启预编译后效率高)

${}

拼接SQL。底层使用的是 Statement,会存在SQL注入问题。

参数问题

  1. 当参数有一个时 #{任意}
  2. 当传递多个参数时

当参数是一个对象时 #{必须和参数对象的属性名保持一致}

当参数是一个map 集合时 #{必须和map 的key 保持一致}

传递多个参数使用@Param 注解

public Brand selectById4(@Param(“id”) int id,@Param(“brandName”) String brandName);

动态sql

:判断中的key 写法 和 #{} 一样
自动删除第一个无效的 连接符号,但是不会增加
单条件查询

   <select id="selectByCondition1" resultMap="brandResultMap">
        select *
        from tb_brand
        /* where 1 = 1*/
        <where>

            <if test="status != null">
                and status = #{status}
            </if>
            
            <if test="companyName != null and companyName != '' ">
                and company_name like #{companyName}
            </if>

            <if test="brandName != null and brandName != '' ">
                and brand_name like #{brandName}
            </if>
        </where>
    </select>
 <select id="selectByConditionSingle" resultMap="brandResultMap">
        select *
        from tb_brand
        <where>
            <choose><!--相当于switch-->
                <when test="status != null"><!--相当于case-->
                    status = #{status}
                </when>
                <when test="companyName != null and companyName != '' "><!--相当于case-->
                    company_name like #{companyName}
                </when>
                <when test="brandName != null and brandName != ''"><!--相当于case-->
                    brand_name like #{brandName}
                </when>
            </choose>
        </where>
    </select>

insert

 <!-- 返回主键-->
<insert id="insert" useGeneratedKeys="true" keyProperty="id" >
        insert into tb_brand (id,brand_name) values (#{id},#{brandName})
 </insert>

useGeneratedKeys

是否返回主键,默认为flase,只针对insert语句生效;

keyProperty

实体类的属性,返回的名称;

update

<update id="update"  >
       update tb_brand
           <set>
                <if test="companyName!=null">
                    company_name=#{companyName} ,
                </if>
                <if test="brandName!=null">
                     brand_name=#{brandName},
                </if>
           </set>
            where id =#{id}
    </update>

set

去除最后一个无效的“,”号

delete

 <delete id="delete">
        delete from tb_brand where id in
        <foreach collection="ids"  item="id" open="(" separator="," close=")">
                #{id}
        </foreach>
    </delete>

foreach

循环遍历

collection

循环遍历谁

item

循环便利的名称

open

遍历前加什么

separator

遍历每个数据加什么

close

遍历最后加什么

参数原理

POJO类型

Map集合 直接使用

其他类型

都会用map 封装,map 的key 建议使用 @Param注解 指定

MyBatis 参数封装

		* 单个参数:
            1. POJO类型:直接使用,属性名 和 参数占位符名称 一致

            2. Map集合:直接使用,键名 和 参数占位符名称 一致

            3. Collection:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
                map.put("arg0",collection集合);
                map.put("collection",collection集合);
            4. List:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
                map.put("arg0",list集合);
                map.put("collection",list集合);
                map.put("list",list集合);
            5. Array:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
                map.put("arg0",数组);
                map.put("array",数组);
            6. 其他类型:直接使用
        * 多个参数:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
            map.put("arg0",参数值1)
            map.put("param1",参数值1)
            map.put("param2",参数值2)
            map.put("agr1",参数值2)
            ---------------@Param("username")
            map.put("username",参数值1)
            map.put("param1",参数值1)
            map.put("param2",参数值2)
            map.put("agr1",参数值2)

注解开发

  1. @Select(“select * from tb_brand”)

    @ResultMap(“brandMap”)

  2. @Insert

  3. @Update

  4. @Delete

同一个方法不允许使用注解和xml 都存在

简单的sql 采用注解,复杂的建议使用 xml

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java白杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值