MyBatis操作数据库

1.MyBatis是什么?

(1)MyBatis是⼀款优秀的持久层框架,⽤于简化JDBC的开发。

--JDBC(Java DataBase Connectivity),即Java数据库连接。

(2)MyBatis本是 Apache的⼀个开源项⽬iBatis,2010年这个项⽬由apache迁移到了google code,并且改名为MyBatis 。2013年11⽉迁移到Github。(所以引包的时候ibatis和mybatis是一回事)

(3)持久层:指的就是持久化操作的层, 通常指数据访问层(dao), 是⽤来操作数据库的.

Dao和Mapper是数据层的 

2.MyBatis的操作步骤

2.1 创建项目

(1)project type记得改为maven

(2)引包

Mybatis 是⼀个持久层框架, 具体的数据存储和数据操作还是在MySQL中操作的, 所以需要添加
MySQL驱动

(3)删掉不需要的文件

(4)更改相对应得包版本

并不需要记住对应的mybatis的版本,我们可以用edit starters直接导入。

2.2 数据准备

创建用户表, 并创建对应的实体类User

-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;
-- 使⽤数据数据
USE mybatis_test;
-- 创建表[⽤⼾表]
DROP TABLE IF EXISTS userinfo;
CREATE TABLE `userinfo` (
 `id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
 `username` VARCHAR ( 127 ) NOT NULL,
 `password` VARCHAR ( 127 ) NOT NULL,
 `age` TINYINT ( 4 ) NOT NULL,
 `gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-⼥ 0-默认',
 `phone` VARCHAR ( 15 ) DEFAULT NULL,
 `delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
 `create_time` DATETIME DEFAULT now(),
 `update_time` DATETIME DEFAULT now(),
 PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; 
-- 添加⽤⼾信息
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

在ideal中创建对应的实体类 UserInfo

package com.example.demo.model;

import lombok.Data;

import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 吉祥瑞
 * Date: 2024-03-23
 * Time: 20:20
 */
@Data
//交由spring创造set和get语句
public class UserInfo {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

2.3 配置数据库连接字符串 

Mybatis中要连接数据库,需要数据库相关参数配置
• MySQL驱动类
• 登录名
• 密码
• 数据库连接字符串
如果是application.yml⽂件, 配置内容如下:

# 数据库连接配置
spring:
 datasource:
 url: jdbc:mysql://127.0.0.1:3306/mybatis_test?
characterEncoding=utf8&useSSL=false
 username: root
 password: root
 driver-class-name: com.mysql.cj.jdbc.Driver

注意事项:
如果使用 MySQL 是 5.x 之前的使⽤的是"com.mysql.jdbc.Driver",如果是⼤于 5.x 使⽤的
是“com.mysql.cj.jdbc.Driver”.

2.4 写持久层代码 

Mybatis的持久层接口规范⼀般都叫 XxxMapper
@Mapper注解:表示是MyBatis中的Mapper接⼝
• 程序运⾏时, 框架会自动⽣成接⼝的实现类对象(代理对象),并给交Spring的IOC容器管理
• @Select注解:代表的就是select查询,也就是注解对应⽅法的具体实现内容

2.4 单元测试

在创建出来的SpringBoot⼯程中,在src下的test⽬录下,已经⾃动帮我们创建好了测试类 ,我们可以直接使⽤这个测试类来进⾏测试.

(1)

package com.example.demo;

import com.example.demo.mapper.UserInfoMapper;
import com.example.demo.model.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;


import java.util.List;

@SpringBootTest
class Mybatis03ApplicationTests {

	@Autowired
	private UserInfoMapper userInfoMapper;
	@Test
	void contextLoads(){
		List<UserInfo> userInfoMappers=userInfoMapper.queryAllUser();
		System.out.println(userInfoMappers);
	}
}

测试类上添加了注解 @SpringBootTest,该测试类在运⾏时,就会⾃动加载Spring的运⾏环境.
我们通过@Autowired这个注解, 注⼊我们要测试的类, 就可以开始进⾏测试了

(2)自动生成

选择要测试的⽅法, 点击 OK

package com.example.demo.mapper;

import com.example.demo.model.UserInfo;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
/**
* Created with IntelliJ IDEA.
* Description:
* User: 吉祥瑞
* Date: 2024-03-23
* Time: 20:31
*/
@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void queryAllUser() {
        List<UserInfo> userInfos=userInfoMapper.queryAllUser();
        System.out.println(userInfos);
    }
}

结果:

 记得加 @SpringBootTest 注解, 加载Spring运⾏环境

3.MyBatis的基础操作

3.1 打印日志

mybatis:
 configuration: # 配置打印 MyBatis⽇志
 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

重新运⾏程序, 可以看到SQL执⾏内容, 以及传递参数和执⾏结果 

①: 查询语句
②: 传递参数及类型
③: SQL执⾏结果

3.2 参数传递 

SQL语句中的id值不能写成固定数值,需要变为动态的数值
解决⽅案:在queryById⽅法中添加⼀个参数(id),将⽅法中的参数,传给SQL语句
使⽤ #{} 的⽅式获取⽅法中的参数
    @Select("select username, `password`, age, gender, phone from userinfo where id=#{id}}")
    UserInfo queryById(Integer id);
如果mapper接⼝⽅法形参只有⼀个普通类型的参数,#{…} ⾥⾯的属性名可以随便写,如:#{id}、# {value}。建议和参数名保持⼀致。
测试用例:
    @Test
    void queryById() {
        UserInfo userInfoss=userInfoMapper.queryById(4);
        System.out.println(userInfoss);
    }

3.3 增(Insert)

USE mybatis_test;

insert into userinfo (username, `password`, age, gender, phone) values ("zhaoliu","zhaoliu",19,1,"18700001234")
把SQL中的常量替换为动态的参数Mapper接⼝
@Insert("insert into userinfo (username, `password`, age, gender, phone) 
values (#{username},#{password},#{age},#{gender},#{phone})")
Integer insert(UserInfo userInfo);

测试代码

    @Test
    void insert() {
        UserInfo userInfo=new UserInfo();
        userInfo.setPassword("zhaoliu121");
        userInfo.setGender(2);
        userInfo.setAge(21);
        userInfo.setUsername("www");
        userInfo.setPhone("18612340005");
        userInfoMapper.insert(userInfo);

    }

成功

注意:

Insert 语句默认返回的是 受影响的⾏数 

但有些情况下, 数据插⼊之后, 还需要有后续的关联操作, 需要获取到新插⼊数据的id
⽐如订单系统
当我们下完订单之后, 需要通知物流系统, 库存系统, 结算系统等, 这时候就需要拿到订单ID

如果想要拿到⾃增id, 需要在Mapper接⼝的⽅法上添加⼀个Options的注解
@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("insert into userinfo (username, age, gender, phone) values (#
{userinfo.username},#{userinfo.age},#{userinfo.gender},#{userinfo.phone})")
Integer insert(@Param("userinfo") UserInfo userInfo);

useGeneratedKeys:这会令 MyBatis 使⽤ JDBC 的 getGeneratedKeys ⽅法来取出由数据库内

部⽣成的主键(⽐如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的⾃动递增字
段),默认值:false.
keyProperty:指定能够唯⼀识别对象的属性,MyBatis 会使⽤ getGeneratedKeys 的返回值或
insert 语句的 selectKey ⼦元素设置它的值,默认值:未设置(unset)
测试语句
结果分析
之前是影响行数1
现在是受影响的是第几行
    @Test
    void insert12() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("zhaoliu");
        userInfo.setPassword("zhaoliu");
        userInfo.setGender(2);
        userInfo.setAge(21);
        userInfo.setPhone("18612340005");
        Integer count = userInfoMapper.insert(userInfo);
        Integer con=userInfo.getId();
        System.out.println("添加数据条数:" +count +", 数据ID:" + con);
    }

注意: 设置 useGeneratedKeys=true 之后, ⽅法返回值依然是受影响的⾏数, ⾃增id 会设置在上
述 keyProperty 指定的属性中

3.4 删(Delete)

SQL 语句:
delete from userinfo where id=6

把SQL中的常量替换为动态的参数
Mapper接⼝

@Delete("delete from userinfo where id = #{id}")
void delete(Integer id);

3.5 改(Update)

SQL 语句:
update userinfo set username="zhaoliu" where id=5
把SQL中的常量替换为动态的参数
Mapper接⼝
@Update("update userinfo set username=#{username} where id=#{id}")
    void update(UserInfo userInfo);

3.6 查(Select)

我们在上⾯查询时发现, 有⼏个字段是没有赋值的, 只有Java对象属性和数据库字段⼀模⼀样时, 才会进⾏赋值 接下来我们多查询⼀些数据
@Select("select id, username, `password`, age, gender, phone, delete_flag, 
create_time, update_time from userinfo")
List<UserInfo> queryAllUser();

从运⾏结果上可以看到, 我们SQL语句中, 查询了delete_flag, create_time, update_time, 但是这⼏个属性却没有赋值.
注意:
MyBatis 会根据⽅法的返回结果进⾏赋值.
⽅法⽤对象 UserInfo接收返回结果, MySQL 查询出来数据为⼀条, 就会⾃动赋值给对象.
⽅法⽤List<UserInfo>接收返回结果, MySQL 查询出来数据为⼀条或多条时, 也会⾃动赋值给List
但如果MySQL 查询返回多条, 但是⽅法使⽤UserInfo接收, MyBatis执⾏就会报错.
原因分析:
当⾃动映射查询结果时,MyBatis 会获取结果中返回的列名并在 Java 类中查找相同名字的属性(忽略⼤⼩写)。 这意味着如果发现了 ID 列和 id 属性,MyBatis 会将列 ID 的值赋给 id 属性

 名称一样自动赋值,名称不同需要找解决办法!!!

解决办法:
1. 起别名
2. 结果映射
3. 开启驼峰命名

3.6.1 sql和java名称不同解决办法

3.6.1.1 起别名
在SQL语句中,给列名起别名,保持别名和实体类属性名⼀样
@Select("select id, username, `password`, age, gender, phone, delete_flag as deleteFlag, " +
            "create_time as createTime, update_time as updateTime from userinfo")
    public List<UserInfo> queryAllUser2();
3.6.1.2 结果映射
    @Select("select id, username, `password`, age, gender, phone, delete_flag, create_time, update_time from userinfo")
            @Results({
                    @Result(column = "delete_flag",property = "deleteFlag"), 
                    @Result(column = "create_time",property = "createTime"), 
                    @Result(column = "update_time",property = "updateTime")
            }) 
    List<UserInfo> queryAllUser5();

如果其他SQL, 也希望可以复⽤这个映射关系, 可以给这个Results定义⼀个名称

@Select("select id, username, `password`, age, gender, phone, delete_flag, " +
            "create_time, update_time from userinfo")
            @Results(id = "resultMap",value = {
                    @Result(column = "delete_flag",property = "deleteFlag"), 
                    @Result(column = "create_time",property = "createTime"), 
                    @Result(column = "update_time",property = "updateTime")
    })
    List<UserInfo> queryAllUser6();
    @Select("select id, username, `password`, age, gender, phone, delete_flag, " +
            "create_time, update_time " +
            "from userinfo where id= #{userid} ")
    @ResultMap(value = "resultMap")
    UserInfo queryById6(@Param("userid") Integer id);

 利用id后面的resultmap进行复用

使⽤ id 属性给该 Results 定义别名, 使⽤ @ResultMap 注解来复⽤其他定义的 ResultMap
 3.6.1.3 开启驼峰命名(推荐)
通常数据库列使⽤蛇形命名法进⾏命名(下划线分割各个单词), ⽽ Java 属性⼀般遵循驼峰命名法约定.
为了在这两种命名⽅式之间启⽤⾃动映射,需要将 mapUnderscoreToCamelCase 设置为 true。
mybatis.configuration.map-underscore-to-camel-case=true #配置驼峰⾃动转换
驼峰命名规则: abc_xyz => abcXyz
表中字段名:abc_xyz
类中属性名:abcXyz

4. MyBatis XML配置⽂件  

Mybatis的开发有两种⽅式:
1. 注解
2. XML
上⾯学习了注解的⽅式, 接下来我们学习XML的⽅式
使⽤Mybatis的注解⽅式,主要是来完成⼀些简单的增删改查功能. 如果需要实现复杂的SQL功能,建 议使⽤XML来配置映射语句,也就是将SQL语句写在XML配置⽂件中.
MyBatis XML的⽅式需要以下两步:
1. 配置数据库连接字符串和MyBatis
2. 写持久层代码

4.1 配置连接字符串和MyBatis

此步骤需要进⾏两项设置,数据库连接字符串设置和 MyBatis 的 XML ⽂件配置。
如果是application.yml⽂件, 配置内容如下:

# 数据库连接配置
spring:
 datasource:
 url: jdbc:mysql://127.0.0.1:3306/mybatis_test?
characterEncoding=utf8&useSSL=false
 username: root
 password: root
 driver-class-name: com.mysql.cj.jdbc.Driver
# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件
mybatis:
 mapper-locations: classpath:mapper/**Mapper.xml

4.2 写持久层代码

持久层代码分两部分
1. ⽅法定义 Interface
2. ⽅法实现: XXX.xml

4.2.1 添加 mapper 接⼝

数据持久层的接⼝定义:

import com.example.demo.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserInfoXMlMapper {
 List<UserInfo> queryAllUser();
}

4.2.2 添加 UserInfoXMLMapper.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.UserInfoXMlMapper">

</mapper>
创建UserInfoXMLMapper.xml, 路径参考yml中的配置
(1)要一一对应

查询所有⽤⼾的具体实现 :

<?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.UserInfoXMlMapper">
    <select id="queryAllUser112" resultType="com.example.demo.model.UserInfo">
        select username,password, age, gender, phone from userinfo
    </select>
</mapper>

一一对应

package com.example.demo.mapper;

import com.example.demo.model.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 吉祥瑞
 * Date: 2024-03-23
 * Time: 22:23
 */
@SpringBootTest
public class UserInfoXMlMapperTest {
    @Autowired
    private UserInfoXMlMapper userInfoXMlMapper;
    @Test
    void queryAllUser() {
        List<UserInfo> userInfoList = userInfoXMlMapper.queryAllUser112();
        System.out.println(userInfoList);
    }
}

4.3 增删改查操作

接下来,我们来实现⼀下⽤⼾的增加、删除和修改的操作.

4.3.1 增(Insert)

UserInfoMapper接⼝
<insert id="insertUser">
        insert into userinfo (username, `password`, age, gender, phone) values (#
        {username}, #{password}, #{age},#{gender},#{phone})
    </insert>

4.3.2 删(Delete)

<delete id="deleteUser">
 delete from userinfo where id = #{id}
</delete>

4.3.3 改(Update)

<update id="updateUser">
 update userinfo set username=#{username} where id=#{id}
</update>

4.3.4 查(Select)

同样的, 使⽤XML 的⽅式进⾏查询, 也存在数据封装的问题
我们把SQL语句进⾏简单修改, 查询更多的字段内容
<select id="queryAllUser" resultType="com.example.demo.model.UserInfo">
 select id, username,`password`, age, gender, phone, delete_flag, 
create_time, update_time from userinfo
</select>

同样有很多null

结果显⽰: deleteFlag, createTime, updateTime 也没有进⾏赋值.
解决办法和注解类似:
1. 起别名
2. 结果映射
3. 开启驼峰命名
其中1,3的解决办法和注解⼀样,不再多说, 接下来看下xml如果来写结果映射
Mapper.xml
<resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
 <id column="id" property="id"></id>
 <result column="delete_flag" property="deleteFlag"></result>
 <result column="create_time" property="createTime"></result>
 <result column="update_time" property="updateTime"></result>
</resultMap>
<select id="queryAllUser" resultMap="BaseMap">
 select id, username,`password`, age, gender, phone, delete_flag, 
create_time, update_time from userinfo
</select>

5.#{} 和 ${} 

#{} 使⽤的是预编译SQL, 通过 ? 占位的⽅式, 提前对SQL进⾏编译, 然后把参数填充到SQL语句 中. #{} 会根据参数类型, ⾃动拼接引号 '' .
${} 会直接进⾏字符替换, ⼀起对SQL进⾏编译. 如果参数为字符串, 需要加上引号 '' .
参数为数字类型时, 也可以加上, 查询结果不变, 但是可能会导致索引失效, 性能下降

5.1 #{} 和 ${}区别

#{} 和 ${} 的区别就是预编译SQL和即时SQL 的区别.
简单回顾:
当客⼾发送⼀条SQL语句给服务器后, ⼤致流程如下:
1. 解析语法和语义, 校验SQL语句是否正确
2. 优化SQL语句, 制定执⾏计划
3. 执⾏并返回结果
⼀条 SQL如果⾛上述流程处理, 我们称之为 Immediate Statements(即时 SQL)
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、付费专栏及课程。

余额充值