Mybatis学习笔记

ORM框架

ORM(Object Relational Mapping),即对象关系映射。在面向对象编程语言中,将关系型数据库中的
数据与对象建立起映射关系,进而自动的完成数据与对象的互相转换:

  1. 将输入数据(即传入对象)+SQL 映射成原生 SQL
  2. 将结果集映射为返回对象,即输出对象
    ORM 把数据库映射为对象:
    数据库表(table)–> 类(class)
    记录(record,行数据)–> 对象(object)
    字段(field) --> 对象的属性(attribute)
    一般的 ORM 框架,会将数据库模型的每张表都映射为一个 Java 类。

常见的ORM框架

Mybatis
Mybatis是一种典型的半自动的 ORM 框架,所谓的半自动,是因为还需要手动的写 SQL 语句,再由框
架根据 SQL 及 传入数据来组装为要执行的 SQL。其优点为:

  1. 因为由程序员自己写 SQL,相对来说学习门槛更低,更容易入门。
  2. 更方便做 SQL的性能优化及维护。
  3. 对关系型数据库的模型要求不高,这样在做数据库模型调整时,影响不会太大。适合软件需求变更
    比较频繁的系统,因此国内系统大部分都是使用如 Mybatis 这样的半自动 ORM 框架。
    其缺陷为:
    不能跨数据库,因为写的 SQL 可能存在某数据库特有的语法或关键词
    Hibernate
    Hibernate是一种典型的全自动 ORM 框架,所谓的全自动,是 SQL 语句都不用在编写,基于框架的
    API,可以将对象自动的组装为要执行的 SQL 语句。其优点为:
  4. 全自动 ORM 框架,自动的组装为 SQL 语句。
  5. 可以跨数据库,框架提供了多套主流数据库的 SQL 生成规则。
    其缺点为:
    学习门槛更高,要学习框架 API 与 SQL 之间的转换关系
    对数据库模型依赖非常大,在软件需求变更频繁的系统中,会导致非常难以调整及维护。可能数据
    库中随便改一个表或字段的定义,Java代码中要修改几十处。
    很难定位问题,也很难进行性能优化:需要精通框架,对数据库模型设计也非常熟悉。

Mybatis整体执行步骤

  1. 根据application.properties配置,初始化数据库连接(真实的其实是执行SQL时连接)
  2. Spring能扫描到的接口,如果是带@Mapper注解,会基于Mybatis框架,将接口生成代理类
    (为什么可以直接使用接口来调用方法:代理类会注册到容器中,注入或者装配时,接口父类引用指向代理子类对象)
#指定Mybatis表和实体映射关系xml配置文件,包含表与实体的映射,字段和属性的映射,及各个sql语句
mybatis.mapper-locations=classpath:mapper/**Mapper.xml
  1. 加载Mybatis的xml映射文件

调用Mapper接口的执行流程

  1. 查找xml映射文件中,namespace 命名空间和mapper全限定名一致的文件

  2. 根据调用的方法找文件中crud标签id相等的语句块,(id和mapper方法名一致的,作为要执行的sql语句)

  3. 替换占位符
    如果有多个参数,方法参数加@Param(“变量名”)注解
    如果是Java对象,作为方法参数,对象属性名绑定占位符变量名

    一个Java对象,不使用@Param注解,在xml中,占位符写法为#(属性名)
    多个方法参数,使用@Param注解作为Java对象变量名,xml占位符的写法为#(对象绑定的变量名.属性名)

  4. 根据查询语句返回值,和要返回的id的类型返回数据

Xml中的配置项
1) 命名空间要和mapper全限定名一致
2) Crud分别为
3) 结果集映射标签
:id的值要和标签的resultMap属性值一致

Mapper接口
1) 根据全限定名查找命名空间一致的xml文件
2) 根据方法名查找crud标签,方法名和id属性值一致的SQL语句
3) 方法参数对应要替换的占位符的值 (xml映射文件,不加parameterType)

接口方法的设计

1) 方法名绑定xml中,crud标签的id
2) 方法参数为要替换的占位符的值
3) 返回类型:如果是更新(新增,修改,删除),统一设计为int,
如果是查询,统一设计为一个对象或List<类型>

Mybatis占位符

1)#{变量名}:实现原理为,先替换为带?的预编译的SQL语句,然后再以jdbc中,操作命令对象,set类型(占位符的索引,替换的值):满足预编译的特性,防止sql注入,预编译提高性能;
2) 变 量 名 : 实 现 原 理 为 , 以 字 符 串 拼 接 的 方 式 , 拼 接 预 编 译 的 s q l 语 句 , {变量名}:实现原理为,以字符串拼接的方式,拼接预编译的sql语句, sql{变量名},组织为变量前的sql字符串+${变量名}字符串+变量后的sql字符串——整个作为带?的预编译sql——存在sql注入问题,及性能问题

查询的结果集数据,如果产生了不同表的关系映射,返回的结果集对应就是多种Java类型,并且包含对象间的关系

1) 希望返回的结果集对象的类型,添加关系的对象

1对1关系,添加属性:private关系对象属性 属性名

public class Article {
    private Integer id;
    private String title;
    private String content;
    private Integer viewCount;
    private Integer userId;
    private Date createTime;
//一个文章对象绑定一个用户对象
    private User user;
}

1对多关系,添加属性:private List<关系对象属性> 属性名

public class User {
    private Integer id;
    private String username;
    private String password;
    private String nickname;
    private Boolean sex;
    private Date birthday;
    private String head;
    private Date createTime;

    private List<Article> articles;
}

2) xml映射文件中,修改sql的内容

a) 表关联查询;
b) 返回的查询字段,当前命名空间的结果集字段沿用,关联字段,全部加上统一的字段别名及前缀

3) xml映射文件中,中添加映射标签

a) 1对1的映射为
b) 1对多的映射为
属性都是一样:
Property=”对象中关联的属性名”
columnPrefix=“字段前缀”
resultMap=”关联的Mapper命名空间id.结果集映射id”(外部结果集映射写全)

    <resultMap id="BaseResultMap" type="org.example.model.Article">
        <id column="id" property="id"/>
        <result column="title" property="title"/>
        <result column="content" property="content"/>
        <result column="view_count" property="viewCount"/>
        <result column="user_id" property="userId"/>
        <result column="create_time" property="createTime"/>
        <association property="user"
                     columnPrefix="u_"
                     resultMap="org.example.mapper.UserMapper.BaseResultMap"></association>
    </resultMap>
   <resultMap id="BaseResultMap" type="org.example.model.User">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="nickname" property="nickname"/>
        <result column="sex" property="sex"/>
        <result column="birthday" property="birthday"/>
        <result column="head" property="head"/>
        <result column="create_time" property="createTime"/>
        <collection property="articles"
                    columnPrefix="a_"
                    resultMap="org.example.mapper.ArticleMapper.BaseResultMap"/>
    </resultMap>
    <select id="selectById" resultMap="BaseResultMap">
        select
            a.id a_id,
            a.title a_title,
            a.content a_content,
            a.view_count a_view_count,
            a.user_id a_user_id,
            a.create_time a_create_time,
                u.id ,
                u.username ,
                u.password ,
                u.nickname,
                u.sex ,
                u.birthday ,
                u.head ,
                u.create_time
        from article a
            join user u on a.user_id=u.id
            where u.id=#{id}
    </select>

动态sql
1)
<if test=”变量名或者对象属性名 !=null”>
sql片段

满足某种条件,拼接sql的场景

    @Test
    public void selectByCondition(){
        User user = new User();
        user.setUsername("b");
//        user.setPassword("5");
        List<User> list = userMapper.selectByCondition(user);
        list.forEach(System.out::println);
    }
    <select id="selectByCondition" parameterType="org.example.model.User"
            resultMap="BaseResultMap">
        select * from user
        <where>
            <if test="username != null">
                and username=#{username}
            </if>
            <if test="password != null">
                and password=#{password}
            </if>
            <if test="nickname != null">
                and nickname=#{nickname}
            </if>
            <if test="sex != null">
                and sex=#{sex}
            </if>
            <if test="birthday != null">
                and birthday=#{birthday}
            </if>
            <if test="head != null">
                and head=#{head}
            </if>
            <if test="createTime != null">
                and create_time=#{createTime}
            </if>
        </where>
    </select>

2)
在这里插入图片描述

    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        insert into article
            <trim prefix="(" suffix=")" suffixOverrides=",">
                <if test="title != null">
                    title,
                </if>
                <if test="content != null">
                    content,
                </if>
                <if test="viewCount != null">
                    view_count,
                </if>
                <if test="userId != null">
                    user_id,
                </if>
                <if test="createTime != null">
                    create_time,
                </if>
            </trim>

            values
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="title != null">
                #{title},
            </if>
            <if test="content != null">
                #{content},
            </if>
            <if test="viewCount != null">
                #{viewCount},
            </if>
            <if test="userId != null">
                #{userId},
            </if>
            <if test="createTime != null">
                #{createTime},
            </if>
        </trim>
    </insert>

3)
=
CRUD中,只要可以使用条件语句的地方,都可以使用where
4)
=
用于update修改操作
5)
集合遍历
collection:绑定方法参数中的集合,如 List,Set,Map或数组对象
item:遍历时的每一个对象
open:语句块开头的字符串
close:语句块结束的字符串
separator:每次遍历之间间隔的字符串

    <delete id="deleteByIds">
        delete  from article where id in
        <foreach collection="list" item="i" open="(" close=")" separator=",">
            #{i}
        </foreach>
    </delete>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值