《JavaEE进阶》----17.<Mybatis基本操作【注解&XML】>

本篇博客详细讲解了:编写SQL语句

1.使用注释

2.使用XML

3.多表查询

前言:

Mybatis规范中方法名不能重复,即便参数不同。因为每一个方法名都是有一个唯一的ID标识的。因此不能重复。

我们会将数据库相关的接口放在Mapper包下面。

对,注意我们实现访问数据库的Mapper包下面创建的是接口。

只需要进行方法的声明。

而方法上面的注解/SQL语句才是方法的实现。

@Mapper
public interface UserInfoMapper {
    /**
     * 单纯返回数据列表
     * @return
     */
    @Select("select * from userinfo")  //通过注解的方式 进行 方法的实现 *代表Mybatis所有字段名称
    List<UserInfo> queryUserList(); //方法的声明
@Select("select * from userinfo")  
//通过注解的方式 进行方法的实现 *代表Mybatis所有字段名称
List<UserInfo> queryUserList(); 
//方法的声明

第三步:编写SQL语句

一、通过注解编写SQL语句

1.1查

项目,依赖,数据库,实体类等准备好之后,我们首先建包Mapper(代表操作数据库)(持久层)(因为我们用到Mapper注解)也可以放在dao下面。

新建一个UserInfoMapper类,将它定义成一个接口,我们不做它的实现,这个方法用于返回数据列表。新建一个

List<UserInfo> queryUserList方法来访问这个数据库。 

在类上添加@Mapper注解:用来标识它是操作数据库的。表示是MyBatis中的Mapper接口

在方法上添加@select注解:用来标识SQL语句,代表是select查询。对应方法的具体实现

在查的时候我们发现Java属性中下面蓝框字段为null。

由于Java属性和Mybatis字段不一样,因此不会赋值给Java属性。

最好的办法就是上文我们讲到的配置驼峰自动转换

注:ibatis就是mybatis

①单纯打印数据列表 (如上图就是)

SQL语句1   返回数据列表: 

select * From 表名

示例:

@Select("select * from userinfo")  
//通过注解的方式进行方法的实现 
List<UserInfo> queryUserList(); //方法的声明

使用@select(“select * From userinfo”)这样的方式来写SQL语句

*代表Mybatis所有字段名称。

此时我们就完成了数据库的查询。我们可以通过测试来试试,我们是否完成了数据库的查询。

如上图操作。

② 传递一个参数查询数据列表

SQL语句2   传递一个参数

select * From 表名 where 字段 = 参数;

示例:

select * From userinfo where id = #{userId}
@Select(“select * From userinfo where id = #{userId}”)

注:

当参数只有一个的时候,参数名称无所谓,改成别的也可以拿到值。 

③ 传递两个参数查询数据列表

SQL语句3   传递两个参数

select * From 表名 where 字段 = 参数 and 字段 = 参数;

示例:

@Select(“select * from userinfo where id = #{param1} and delete_flag = #{param2}”)

 我们发现如果按照下面这样写的话。就会报错。因为我使用的是aliyun引入的Mybatis框架。

因此当传递两个参数时,只能使用param1和param2。或者arg1和arg0。作为形参。

 1.若是通过aliyun引入的springframework依赖,那么不会帮我们生成可用的我们定义的参数。因此就会报错。可以用param1和param2。或者arg1和arg0

2.官方的依赖就可以,我们也可以手动修改依赖。也就能实现,自已定义参数名称了。

3.我们也可以进行参数的重命名,这样也可以自定义参数名称。也可以编译通过。

下一条就会讲到了


这样就不会报错,我们使用了param1和param2作为了形参。

④参数重命名@param注解

在方法传参列表的参数前使用@Param注解,我们可以通过参数命名来定义我们想要使用的参数名称。

参数绑定
1.默认是注解的参数名称,使用param1和param2等也可以
2.如果使用@param注解进行重命名,那么注解中的参数必须用重命名后的参数

1.2增

SQL语句4 增添数据表信息

insert into 表名(字段1,字段2,...)values(#{参数1},#{参数2},...)

示例:

intert into userinfo(username,password,age,gender,phone) values(#{username},#{password},#{age},#{gender},#{phone})
@insert("intert into userinfo(username,password,age,gender,phone) values(#{username},#{password},#{age},#{gender},#{phone})")

注:value前面的 username 是数据库字段,value后面的#{username} 是Java属性

使用对象来传参 

通过对象进传递参数
1.没有@Param重命名,那么 Java属性 直接使用属性名

注:

添加的数据在数据库中 id 这个字段是自动生成的。因此无需添加。当然还有时间字段也是自动生成。

@Insert("insert into userinfo(username,password,age,gender,phone)" +
        " values(#{username},#{password},#{age},#{gender},#{phone})")
Integer insert (UserInfo userInfo);

 

测试后我们发现完成添加操作。 

返回值默认是影响的条数。 

 2.使用@Param重命名,那么 Java属性 使用 对象.属性名 来获取参数

​@Options(useGeneratedKeys = true,keyProperty = "id")
//将自动生成的id的数给id这个属性
//此操作相当于setId 来给id赋值, 这样就可以getId,数据库那边不用传参id而是自动生成,而这边自动生成了这个数,但是没有指定给哪个属性。
@Insert("insert into userinfo(username,password,age,gender,phone)" +
" values(#{Info.username},#{Info.password},#{Info.age},#{Info.gender},#{Info.phone})")
Integer insertByParam (@Param("Info") UserInfo userInfo);

​

我们发现如果单纯通过注解重命名那么程序就会报错。会发生绑定异常,如何解决这个问题呢?

我们可以当做@Param(“新参数名”)注解重命名后,新名称的参数我们把它当做一个对象。这样在values()中。我们再绑定属性就需要用新参数名.属性来完成操作了。

@Insert("insert into userinfo(username,password,age,gender,phone)" +
" values(#{Info.username},#{Info.password},#{Info.age},#{Info.gender},#{Info.phone})")

通常我们还想获得数据库中生成的 id 字段。我们若想获得到这个 id 这个属性。就需要我们通过这个注解

@Options(useGeneratedKeys = true,keyProperty = "id")

//此操作相当于将数据库自动生成的 id 的值给id这个属性。相当于我们新建了id(java)属性。
//此操作相当于setId 来给id赋值, 这样就可以getId。

1.3删

SQL语句4:通过id删除

delete from 表名 where id = #{id}

示例:

@delete("delete from userinfo where id = #{id}")

Mapper

Test 

删除成功! 

1.4 改

1.通过传参的方式

SQL语句5:通过id更改数据库某字段值

update 表名 set 字段1 = #{参数1},字段2 = #{参数2},...... where id = #{id参数}

示例:

@Update("update userinfo set password = #{password} where id = #{id} ")

password = #{password}
password:数据库字段

#{password}: Java属性,严格来讲是Mybatis的参数名

​​    @Test
    void update() {
        userInfoMapper.update("nihao",6);
    }

成功修改 。

2.通过传递对象的方式

 

注:

若我们忘了写更新字段值的id,也就是若5已经被删掉了或者本就不存在。IDEA也不会报错,只是影响条数为0。因此没有对数据库进行修改。

二、通过XML方式编写SQL语句

注解和 xml 实现是可以共存的,同一个方法,实现方式选哪个都行。

xml的方式和注解方式的操作基本上是一样的。

操作步骤

1.引入依赖 : 同上

2.配置数据库连接: 同上

3.配置Mapper路径

mybatis:
  mapper-locations: classpath:mapper/**Mapper.xml 
# 配置mybatis xml的⽂件路径,在resources/mapper创建所有表的xml⽂件
# classpath对应resources这个目录,接下来说明在mapper这个文件夹下面,以Mapper.xml结束的都可以被加载

4.声明接口

注意加上Mapper注解。

5.使用xml来实现

数据持久成的实现,MyBatis 的固定 xml 格式:我们要实现的代码就在标签<mapper>中。

创建UserInfoXMLMapper.xml, 路径参考yml中的配置

<?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 namespace="com.example.demo.mapper.UserInfoMapper">
 
</mapper>

放在resource/mapper目录下面

下图是一些注意事项:

启动失败常见原因:

1.namespace写错了

2.方法名写错了

3.配置错了

2.1增

1.首先声明insert方法,我们使用传递对象的方式来新增数据。

2.在xml文件中,写SQL语句。我们使用传递对象的方式来新增数据。

因此上方我们不仅要设置id 值为对应方法名 以及 返回类型resultType的值为UserInfo(要写全)

 3.测试

通过xml方式拿到自增id

2.2删 

和增一样的三个步骤

1.声明方法

2.在xml文件中写sql语句 

3.Test测试 

2.3改

1.声明方法

2.在xml中写sql语句 

3.Test测试 

2.4查 

查的时候,在xml文件中,有一个resultType它进行了一个映射,把我们的mysql字段映射成java属性。一样的名字会映射,不一样的我们可以在下面的补充看到如何映射。

1.声明方法

2.写SQL语句 

 3.Test测试

 对通过xml+SQL语句查的补充:驼峰转换

1.改别名,和注解是类似的.

2.在xml文件中用resultMap标签进行映射

没写的自动映射,写了的按照我们定义的进行映射,id其实也可以不用写

通过resultMap进行时候用 

3.配置文件自动转换 

同上

三、多表查询

多表查询特点

慢SQL。

业务中使用多表查询比较少,是因为多表查询sql太长了导致性能不好。会造成慢SQL。:原因是

  • 多表查询,我们写一个SQL来查询,那么我们写的就是一个长SQL,这个长SQL是无法被优化的,只能统一交给数据库。可能进行多个表组装。因此大SQL一定会很慢。 影响到整个MySQL数据库集群。它们通过库隔离,但还是一个集群。整个数据库可能都阻塞了。
  • 而单表查询,相当于我们把大SQL拆成了多个小SQL,多个小SQL都是单独的,可以优化,比如多线程的方式,可以并行去查。也可以通过加机器的方式。分配到多个机器上。

建议

  • 如果业务对性能要求不高,那么使用多表查询比使用Java实现更加合适。(例如公司的内部系统,给员工用的)
  • 如果业务对性能要求高,那么使用Java实现更加合适。
  • 尽可能避免多表查询。因为每一个大SQL执行起来很慢,并且还可能影响到其他数据库,影响其他项目。而多个小SQL执行起来比较快。且影响小。

再创建一个表

3.1多表查询步骤:

我们再创建一个文章表:比如我们要返回文章标题、正文等信息就会用到这个表

-- 创建⽂章表
DROP TABLE IF EXISTS articleinfo;
CREATE TABLE articleinfo (
                             id INT PRIMARY KEY auto_increment,
                             title VARCHAR ( 100 ) NOT NULL,
                             content TEXT NOT NULL,
                             uid INT NOT NULL,
                             delete_flag TINYINT ( 4 ) DEFAULT 0 COMMENT '0正常, 1删除',
                             create_time DATETIME DEFAULT now(),
                             update_time DATETIME DEFAULT now()
) DEFAULT charset 'utf8mb4';
-- 插⼊测试数据
INSERT INTO articleinfo ( title, content, uid ) VALUES ( 'Java', 'Java正⽂', 1);

3.2 第一步:首先进行多表关联(sql语句如下)

3.2.1 SQL语句6(全部查询)

我们在数据库mybatis_test的查询控制台执行那么语句

select * from articleinfo ta
LEFT JOIN userinfo tb on ta.uid = tb.id
where ta.id = 1

解释:

ta:对表articleinfo进行重命名为ta(table a)

LEFT JOIN:左连接,也就是关联的意思

tb: 对表userinfo进行重命名为tb(table b)

on:使用on进行关联,表a的uid字段和表b的id字段

where:查询表a的id

执行后的结果为:

也可以指定查询(SQL语句如下)

3.2.2 SQL语句7(指定查询)

select ta.*,tb.username,tb.password,tb.age
from articleinfo ta
LEFT JOIN userinfo tb on ta.uid = tb.id

我们看到查询到了我们想要的数据。这就是进行多表同时查询。如何用Mybatis来实现这个功能呢。

3.3示例

1.多个表

如上已经添加

2..实体类

package com.qiyangyang.mybatisdemo.model;
import lombok.Data;
import java.util.Date;
@Data
public class ArticleInfo {
    private Integer id;
    private String title;
    private String content;
    private Integer uid;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;

}

3. Mapper包

4. Test包

运行结果(成功查询多表) 

四、通过URL来访问数据库

如果我们不想通过测试用例来访问,通过浏览器路径来访问数据库,那么我们首先一定要有Controller来写路由的映射,为了访问数据库相关内容,我们可以直接注入UserInofMapper。但是不符合我们企业开发的规范,因此我们为了规范像企业那样:

分三层架构表现层,业务层,持久层。

因此我们用Controller来调用Service。用Service来调用dao(也就是我们这里的UserInfoMapper)。

建包Controller,Service,分别在其中建类UserController,UserService。

在类UserController中创建public List<UserInfo> queryAllUser() 方法。

并在类上使用@RestController和@RequestMapping注解。在方法上使用RequestMapping注解

4.1UserController 

4.2UserService

我们用Service来调用Dao(也就是数据访问层)。 

4.3UserMapper

ok我们成功的在浏览器访问出来了。 

总结:

1.配置数据库

2.写Mapper

①加注解@Mapper

②方法声明+方法实现

获取参数:#{参数名称}

当只有一个参数时,参数名称叫什么都可以。

当有多个参数就需要与字段对应(使用默认的也可以,不过一般不用),重命名的话与重命名的名字对应。....................

注:

1.访问数据库的方法不能像java那样方法名称相同,参数不同而构成方法的重构。这是会报错的。这不符合Mybatis规范。方法名不可以重复(在xml文件中我们看到每一个方法都是会有一个id标识的因此不能重复)

2.若是通过aliyun引入的springframework依赖,那么不会帮我们生成可用的我们定义的参数。可以用param1和param2。 官方的依赖就可以,我们也可以手动修改依赖。也就能实现,自已定义参数名称了。将aliyun依赖换成官方的依赖。

aliyun的springframework依赖(传参不能自定义参数)

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

官方springframework依赖 (传参可以自定义参数)

<parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>2.7.17</version>

        <relativePath/>

</parent>

三层架构简单回顾

三层架构就是为了符合“高内聚,低耦合”思想,把各个功能模块划分为

三层架构

各层之间采用接口相互访问,并通过对象模型的实体类(Model)作为数据传递的载体,不同的对象模型的实体类一般对应于数据库的不同表,实体类的属性与数据库表的字段名一致。 

三层架构区分层次的目的是为了 “高内聚,低耦合”。开发人员分工更明确,将精力更专注于应用系统核心业务逻辑的分析、设计和开发,加快项目的进度,提高了开发效率,有利于项目的更新和维护工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

祁思妙想

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

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

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

打赏作者

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

抵扣说明:

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

余额充值