Mybatis操作数据库

MyBatis查询数据库

一.MyBatis是什么?

MyBatis是一款优秀的持久层框架,它支持自定义SQL,存储过程以及高级映射.MyBatis去除了几乎所有的JDBC代码以及设置参数和获取结果集的工作.MyBatis可以通过简单的XML注解来配置和映射原始类型,接口和Java POJO(Plain Old Java Object,普通老式Java对象)为数据库中的记录.

简单来说,MyBatis是更简单完成程序和数据库交互的工具,也就是更简单的操作和读取数据库工具.

支持存储过程,存储sql,但(无法调试无debug,可维护性差)

二.为什么要学习MyBatis?

对于后端开发来说,程序是由以下两个重要的部分组成的:

1.后端程序

2.数据库
在这里插入图片描述而这个两个重要的组成部分要通讯,就要依靠数据连接工具,那数据库连接工具有哪些?比如之前所学习的JDBC,还有现在的MyBatis.那么既然已经有JDBC 了,为什么还要用 MyBatis 呢?因为 JDBC 太繁琐了…用过都懂,写个简单的查询都要写一堆繁琐的代码.

三.MyBatis的学习

MyBatis学习只分为两部分:

● 配置MyBatis开发环境

● 使用MyBatis模式和语法操作数据库

四.第一个MyBatis查询

开始搭建MyBatis之前,先看一下MyaBatis在整个框架中的定位,

框架交互流程图:

在这里插入图片描述

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

1.将输入数据(即传入对象)+SQL映射成原生SQL

2.将结果集映为返回对象,即输出对象

ORM把数据库映射为对象:

  • 数据库表(table) --> 类(class)

  • 记录(record,行数据) --> 对象(object)

  • 字段(field) --> 对象的属性(attribute)

一般的ORM框架,会将数据库模型的每张表都映射为一个Java类.

也就是说使用MyBatis可以像操作对象一样来操作数据库中的表,可以实现对象和数据库表之间的转换,关于MyBatis的使用:

1.创建数据库和表

-- 创建数据库
drop database if exists mycnblog;
create database mycnblog DEFAULT CHARACTER SET utf8;

-- 使用数据数据
use mycnblog;

-- 创建表[用户表]
drop table if exists userinfo;
create table userinfo(
    id int primary key auto_increment,
    username varchar(100) not null,
    password varchar(32) not null,
    photo varchar(500) default '',  -- 默认值为空
    createtime datetime default now(), -- 默认是值是当前的日期
    updatetime datetime default now(),
    `state` int default 1 -- 默认为1
);

-- 创建文章表
drop table if exists  articleinfo;
create table articleinfo(
    id int primary key auto_increment,
    title varchar(100) not null,
    content text not null,-- longtext
    createtime datetime default now(),-- 默认值now()
    updatetime datetime default now(),
    uid int not null,
    rcount int not null default 1,
    `state` int default 1
);

-- 创建视频表
drop table if exists videoinfo;
create table videoinfo(
  	vid int primary key,
  	`title` varchar(250),
  	`url` varchar(1000),
		createtime datetime default now(),
		updatetime datetime default now(),
  	uid int
);

-- 添加一个用户信息
INSERT INTO `mycnblog`.`userinfo` (`id`, `username`, `password`, `photo`, `createtime`, `updatetime`, `state`) VALUES 
(1, 'admin', 'admin', '', '2021-12-06 17:10:48', '2021-12-06 17:10:48', 1);

-- 文章添加测试数据
insert into articleinfo(title,content,uid)
    values('Java','Java正文',1);
    
-- 添加视频
insert into videoinfo(vid,title,url,uid) values(1,'java title','http://www.baidu.com',1);

2.MyBatis使用流程

1)添加MyBatis框架支持

有两种情况:

①老项目添加MyBatis

②创建新项目的时候直接添加MyBatis

在这里插入图片描述
如果没有这个插件,setting一下就得了
在这里插入图片描述

2)配置MyBatis相关的配置文件(连接字符串和MyBatis的XML文件设置)
①配置数据库连接信息
- 连接数据库服务器地址
- 数据库用户名
- 数据库密码
- 数据库的驱动(数据库的类型)
# 开发环境
spring.datasource.url=jdbc:mysql://localhost:3306/oj_databases1?characterEncoding=utf8&useSS=false
spring.datasource.username=root
spring.datasource.password=109614
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver (MySQL版本8.0以后用这个)
②MyBatis的XML文件位置

在这里插入图片描述
在这里插入图片描述

③添加代码步骤:(查询)

在这里插入图片描述

根据这个流程来,(以查询用户为例)

添加实体类:

在这里插入图片描述在这里插入图片描述

添加mapper(数据持久层)接口Interface方法定义:

在这里插入图片描述

mapper(数据持久层)xxx.xml,方法实现:(此处添加UserMapper.xml)

数据持久层的实现,MyBatis的固定 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">
<mapper namespace="com.example.demo.mapper.UserMapper">
    <select id="getAll" resultType="com.example.demo.model.UserInfo">
        select * from userinfo
    </select>
</mapper>

在这里插入图片描述

添加Service层(服务层):

在这里插入图片描述

添加Controller(控制器层):

在这里插入图片描述

查询结果:在这里插入图片描述

注:pom.xml自带默认的版本,例如mysql8.x(当前我使用的是5.7,所以得自己指定下版本)

五.增,删,改操作

1.关于xml中的两种写法:

由于userInfo实体类同数据库的userInfo表中的用户名字定义的名称不同,导致我们无法访问到
在这里插入图片描述

<?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.UserMapper"> <!-- namespace指定了xml实现接口的完整路径 -->
<!--  写法一:返回类型resultType  -->
    <select id="getAll" resultType="com.example.demo.model.UserInfo">
        select * from userinfo
    </select>
    <!-- id为接口中的方法名,resultType则是指返回的一个类型,起到映射作用 -->
</mapper>

除了之前查询的时候所使用的的第一种返回类型之外(上面这种),还有另外一种方式,那就是返回字典映射,让实体类的属性和对应的数据库中的表的列名一一对应.

<?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.UserMapper">   
    <!--  写法二:返回字典映射 resultMap -->
  	<resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
        <!-- 映射主键的(表中主键和程序实体类中的主键) -->
        <id column="username" property="name"></id>
        <!-- 普通列的映射 -->
        <result column="username" property="name"></result>
        <result column="password" property="password"></result>
        <result column="photo" property="photo"></result>
        <result column="createtime" property="createtime"></result>
        <result column="updatetime" property="updatetime"></result>
    </resultMap>
    <select id="getAll" resultMap="BaseMap">
        select*from userinfo
    </select>
</mapper>

再次访问

在这里插入图片描述

这样就能保证一一对应上了

Mybatis中xml查询返回类型的两种设置的比较:
  1. resultType(返回结果类型)
  2. resultMap(返回映射)

共同点:这两种设置方式的功能是相同的,都是用来指定结果类型

不同点:

  • resultType用法简单,但如果实体类中的属性名和表中的字段名不一致那么将查询不出结果(null)
  • resultMap用法相对麻烦,要实现多个列的映射,但是他可以实现属性和字段即便是名字不同,也能够进行映射,能够查询出正确的数据.

2.添加操作:

这里也不嫌麻烦,再放出逻辑图:在这里插入图片描述

注意:之前新建用户表的时候,除了用户名称以及用户密码没有指定值之外,其他都有默认或者是一个自增主键.所以我们在对用户表进行插入的时候,只需要插入这两条数据即可.

Controller控制器层添加代码:

//调用是在service服务器进行调用的
//Controller会调用service
@RestController
@RequestMapping("/user")
public class UserController {
    //在controller要先注入service(下层类),这里采用属性注入
    @Autowired
    private UserService userService;
	/**
     * 添加用户(返回受影响的行数)
     * @param userInfo
     * @return
     */
    @RequestMapping("/add")
    public int add(UserInfo userInfo){
        //参数校验 - > 调用业务逻辑层
        if(userInfo == null || userInfo.getName() == null
        || userInfo.getPassword() == null
        || userInfo.getName().equals("")
        || userInfo.getPassword().equals("")){
            //非法参数
            return 0;
        }
        return userService.add(userInfo);
    }
}

Service服务层添加代码:

/**
 * 进行数据组装,调用dao层
 */
@Service
public class UserService {
    //属性注入,将下层类注入到这
    @Autowired
    private UserMapper userMapper;
    
     public int add(UserInfo userInfo) {
        //服务(方法编排)
        return userMapper.add(userInfo);
    }
}

Mapper层添加代码(接口和xml):

InterFace:

@Mapper
public interface UserMapper {
    //接口中进行声明,而实现是在xml里面的
    int add(UserInfo userInfo);
}

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">
<mapper namespace="com.example.demo.mapper.UserMapper"> 
	<resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
        <!-- 映射主键的(表中主键和程序实体类中的主键) -->
        <id column="username" property="name"></id>
        <!-- 普通列的映射 -->
        <result column="username" property="name"></result>
        <result column="password" property="password"></result>
        <result column="photo" property="photo"></result>
        <result column="createtime" property="createtime"></result>
        <result column="updatetime" property="updatetime"></result>
    </resultMap>
    <!-- 添加方法 -->
    <insert id="add">
        insert into userinfo(username,password)
        value(#{name},#{password})
    </insert>
    <!--  这里的#{列名/类的属性名}就相当于之前jdbc构造sql语句的?,表示替换符,
	当这个请求是GET的时候,通过?后面的键值对,也就是queryString传递参数
  	例如name=java&password=java,如果是POST,则需要通过body -->
    
</mapper>

注意:这里传进来的参数的 key 要和 #{} 里面的要对应,不如无法插入

到这里,代码都写完了,接下来就是进行插入测试:

在这里插入图片描述
在这里插入图片描述

可以看到,插入成功了.

特殊的添加:

默认情况下,返回的是受影响的行号,如果想要返回自增id

    /**
     * 添加方法2,返回用户自增id
     * @param userInfo
     * @return
     */
    @RequestMapping(value = "/add2")
    public int add2(UserInfo userInfo){
        //参数校验 - > 调用业务逻辑层
        if(userInfo == null || userInfo.getName() == null
                || userInfo.getPassword() == null
                || userInfo.getName().equals("")
                || userInfo.getPassword().equals("")){
            //非法参数
            return 0;
        }
        //调用数据库执行添加操作,执行完之后会将自增id设置到userinfo的id属性
        userService.add2(userInfo);
        return userInfo.getId();
    }

添加过程和前面可以说基本一样,在对应层改一下复制一下add,改成add2()即可.

xml的实现:

    <!-- 添加方法2:返回自增的id -->
    <insert id="add2" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        insert into userinfo(username,password)
        value(#{name},#{password})
    </insert>

mapper.xml会将自增的id插入到当前项目对象类中指定的主键属性上.

  • useGeneratedKeys: 这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键 (比如: 像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段,默认值: false)
  • keyColumn: 设置生成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列不是表中的第一列的时候,是必须设置的.如果生成列不止一个,可以用逗号分隔多个属性名称.
  • keyProperty: 指定能够唯一识别对象的属性,MyBatis 会使用 getGeneratedKey 的返回值或 insert 语句的 selectKey 子元素来设置它的值,默认值:未设置(unset).如果生成列不止一个,可以用逗号分隔多个属性名称.

在这里插入图片描述

3.修改操作

/**
 * 修改操作
 * @param id
 * @param password
 * @return
 */
@RequestMapping("/update")
public int update(int id,String password){
    if(id <= 0 || password == null || password.equals("")){
        return 0;
    }
    return userService.update(id,password);
}
<!-- 修改操作 -->
<update id="update">
    update userinfo set password = #{password}
    where id = #{id}
</update>

在这里插入图片描述

4.删除操作

Controller层,剩余层直接快速生成即可.

@RequestMapping(value = "/del")
public Integer del(Integer id){
    if(id <= 0){
        return 0;
    }
    return userService.del(id);
}
<!-- 实现删除操作 -->
<delete id="del">
    delete from userinfo where id = #{id};
</delete>

测试:在这里插入图片描述

在这里插入图片描述

5.关于参数占位符#{}和${}

1)#{}和${}
  • #{}:预编译处理
  • ${}:字符直接替换

预编译处理是指: MyBatis 在处理 #{} 时,会将 SQL 中的 #{} 替换为 ? 号,使用 PreparedStatement 的 set 方法来赋值.

直接替换: 是 MyBatis 在处理 ${} 时,就是把 ${} 替换成变量的值.

我举个例子即可,username 为 varchar类型(java中String)

select * from userinfo where username = #{name};
select * from userinfo where username = ${name};

然后发送get请求http://localhost:8080/user/select?username=admin

可以看到我们传递了username 为 admin的参数

上面那两局转换为 sql 分别为:

select * from userinfo where username = ‘admin’;

select * from userinfo where username = admin;

直接替换罢了,改成 '${name}'就一样了

既然如此,那么只要#{}不就得了,为什么还要有${}呢?

别急,下面来说说 #{} 的优点,也就是说说他的使用场景

2)${}的优点

在这里插入图片描述

/**
 * ${}的使用
 * @param order
 * @return
 */
@RequestMapping("/sort")
public List<UserInfo> sort(String order){
    return userService.sort(order);
}
<!-- ${}的使用 -->
<select id="sort" resultMap="BaseMap">
    select * from userinfo order by id ${sort}
</select>

使用 ${sort} 可以实现排序查询,而使用 #{sort} 就不能实现排序查询了,因为当使用 #{sort}查询时,如果传递的值为 String 则会加单引号,就会导致sql错误

{}里的值可以随意指定

测试:在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis 是一个开源的持久层框架,它可以帮助开发者简化数据库操作。下面是使用 MyBatis 操作数据库的一般步骤: 1. 配置数据库连接:在 MyBatis 的配置文件中,设置数据库连接信息,包括数据库驱动、URL、用户名和密码等。 2. 定义数据模型:创建 Java 类来表示数据库中的表,每个类对应一个表,类的属性对应表的列。 3. 编写 SQL 映射文件:创建一个 XML 文件,定义 SQL 语句和映射关系。在文件中,可以使用 MyBatis 提供的标签来编写 SQL 语句,还可以使用动态 SQL 来实现条件查询等功能。 4. 配置 SQL 映射文件:在 MyBatis 的配置文件中,引入 SQL 映射文件,告诉 MyBatis 哪些 SQL 语句对应哪些方法。 5. 创建 SqlSessionFactory:通过 MyBatis 提供的 SqlSessionFactoryBuilder 类,读取配置文件并创建 SqlSessionFactory 对象。SqlSessionFactory 是一个线程安全的类,用于创建 SqlSession。 6. 创建 SqlSession:通过 SqlSessionFactory 的 openSession 方法创建 SqlSession 对象。SqlSession 是一个用于执行 SQL 语句的接口,它提供了多种方法来操作数据库。 7. 执行 SQL 语句:通过 SqlSession 对象调用相应的方法,执行 SQL 语句。例如,可以使用 selectOne 方法执行查询操作,使用 insert、update 或 delete 方法执行增删改操作。 8. 提交事务和关闭资源:在操作完成后,需要调用 SqlSession 的 commit 方法提交事务,并调用 close 方法关闭资源。 以上是使用 MyBatis 操作数据库的一般步骤,具体的实现方式可以根据项目的需求进行调整和扩展。希望对你有帮助!如果有其他问题,请继续提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值