MyBatis 操作数据库


提示:以下是本篇文章正文内容,Java系列学习将会持续更新

一、为何学习 MyBatis

1-1 JDBC 操作流程

这是因为 JDBC 的操作太繁琐了,我们回顾一下 JDBC 的操作流程:

  1. 创建数据库连接池 DataSource
  2. 通过 DataSource 获取数据库连接 Connection
  3. 编写要执行带 ? 占位符的 SQL 语句
  4. 通过 Connection 及 SQL 创建操作命令对象 Statement
  5. 替换占位符:指定要替换的数据库字段类型,占位符索引及要替换的值
  6. 使用 Statement 执行 SQL 语句
  7. 查询操作:返回结果集 ResultSet,更新操作:返回更新的数量
  8. 处理结果集
  9. 释放资源

所以需要引入一些框架进行 JDBC 优化,它可以帮助我们更方便、更快速的操作数据库。

1-2 JDBC 优化方式

Java中对JDBC优化的主要思路:

  1. ORM (Object Relational Mapping) —— 核心思路, 尝试把一张表中的一条条记录完全映射成一个个的对象——去掉 SQL。当表结构 + SQL查询真的做简单映射时,非常方便。
    但如果有复杂查询(一次涉及多表或者表的优化比较特殊时),就不好了

  2. 仅仅简化SQL的编写

常见框架模式
Hibernate框架偏向简化SQL的模式
MyBatis框架偏向ORM的模式
国内使用MyBatis相对较多(MyBatisPlus 做SQL生成)
Spring内部提供的JdbcTemplate偏向简化SQL的模式
JPA完全倒向了ORM的形式,建表的过程都被抽象,我们看到的只有类
(我写了类,框架根据类建表)

1-3 认识 MyBatis

MyBatis 官网

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

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

怎么学 MyBatis:

  1. 配置 MyBatis 开发环境;
  2. 使用 MyBatis 模式和语法操作数据库。

回到目录…

二、使用 MyBatis

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

  1. 将输入数据(即传入对象)+SQL 映射成原生 SQL
  2. 将结果集映射为返回对象,即输出对象

ORM 把数据库映射为对象:

  • 数据库表(table)–> 类(class)
  • 记录(record,行数据)–> 对象(object)
  • 字段(field)–> 对象的属性(attribute)

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

Mybatis的使用有两种方式:

  1. 通过注解使用(相对比较容易, 好上手。做一些复杂操作的时候不太灵活)
  2. 通过XML配置文件的形式(比较规则,缺点就是XML 一大堆,又没有语法检查,出错不容易排查)

回到目录…

2-1 添加依赖

需要导入3个依赖:

  • Spring Data JDBC: 这个依赖把 DataSource 对象注册到Spring中(默认HakiraDataSource),Aliyun开源Durid (国内用Durid的比较多)。
  • MySQL Driver: (无论是Durid or Hakira 最终依赖MySQL官方提供的DataSource)
  • MyBatis Framework: (引入了 Mybatis + MybatisSpring)
<!-- Spring Data JDBC -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- MySQL Driver -->
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>
<!-- MyBatis Framework -->
<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>2.1.4</version>
</dependency>

回到目录…

2-2 yml 配置连接字符串

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/lianxi?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456

回到目录…

2-3 使用 @Mapper 注解

2-3-1 添加实体类

// 表示数据库中直接读取出来的对象
@Data
public class UserDO {
    private Integer uid;
    private String username;
    private String password;
}

回到目录…

2-3-2 添加 mapper 接口

@Repository // 注册到 Spring
@Mapper // 让 mybatis 将这个接口看出一个 Mapper,并且使用代理对象代理它
public interface UserMapper { // 按照 Mybatis 的习惯,称为 UserMapper,或者习惯叫 UserDao / UserRepo

	// #{username} 会对应 @Param("username") username
    // #{password} 会对应 @Param("password") password
    @Select("select uid, username, password from users where username = #{username} and password = #{password}")
    User selectOneByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
    
    // 由于用不到这个返回值,所以写成 void 更常见
    // #{username} 会对应 userDO.getUsername() 或者 userDO.username
    // #{password} 会对应 userDO.getPassword() 或者 userDO.password
    @Insert("insert into users (username, password) values (#{username}, #{password})")
    void insert(UserDO userDO);

    // 通过 @Options 注解,添加一些配置,得到自增主键,设置成 uid
    // keyProperty: 对象的属性名是 uid, keyColumn: 表的字段名的 uid
    @Insert("insert into users (username, password) values (#{username}, #{password})")
    @Options(useGeneratedKeys = true, keyProperty = "uid", keyColumn = "uid")
    void insert2(UserDO userDO);

    @Update("update users set username = #{username}, password = #{password} where uid = #{uid}")
    int update(UserDO userDO);

    @Delete("delete from users where uid = #{uid}")
    int delete(@Param("uid") int i);
}

回到目录…

2-3-3 进行 Service 业务

@Service
public class UserService {
	// 依赖注入
    private final UserMapper userMapper;
    @Autowired
    public UserService(UserMapper userMapper) {
        this.userMapper = userMapper;
    }
	// 注册
    public User register(String username, String password) {
        User user = new User(username, password);
        userMapper.insert(user);
        return user;
    }
	// 登录
    public User login(String username, String password) {
        return userMapper.selectOneByUsernameAndPassword(username, password);
    }
}

回到目录…

2-4 使用 XML 配置文件

MyBatis XML 相关文档

2-4-1 实体类

正常情况下,我们的实体类的属性名和数据库中字段名应该一样。如果出现以下情况,就只能使用 XML文件了。

@Data
public class User {
    public Integer a;
    public String b;
    public String c;

    public User(String username, String password) {
        this.b = username;
        this.c = password;
    }
}

2-4-2 UserMapper 接口

// xml 中需要指定 Mapper 接口的位置
@Mapper
@Repository
public interface UserMapper {
    User selectOneByUid(@Param("uid") int uid);

    List<User> selectListByUidList(@Param("uidList") List<Integer> uidList);

    int insertBatch(@Param("userList") List<User> userList);

    User selectByUser(@Param("user") User user);
}

回到目录…

2-4-3 创建 mapper.xml

在 resources/mapper 下创建 mapper.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 接口 -->
<mapper namespace="com.example.mybatis_xml.UserMapper">
	
	<!-- 映射到 User 实体类 -->
    <resultMap id="xxx" type="com.example.mybatis_xml.User">
    	<!-- id property="属性名" javaType="属性类型" column="字段名" jdbcType="字段类型" / -->
        <id property="a" javaType="Integer" column="uid" jdbcType="INTEGER" />
        <result property="b" javaType="String" column="username" jdbcType="VARCHAR" />
        <result property="c" column="password" />
    </resultMap>

	<!-- id="mapper中的方法名" parameterType="参数类型" -->
    <select id="selectOneByUid" resultMap="xxx" parameterType="int">
        select uid, username, password from users where uid = #{uid}
    </select>

    <select id="selectListByUidList" resultMap="xxx" parameterType="List">
        select uid, username, password from users where uid in (
        <!-- for (id : uidList) { -->
        <foreach collection="uidList" item="id" separator=", ">
            #{id}
        </foreach>
        ) order by uid
    </select>

    <insert id="insertBatch" useGeneratedKeys="true" keyProperty="a" keyColumn="uid">
        insert into users (username, password) values
        <foreach collection="userList" item="user" separator=", ">
            (#{user.b}, #{user.c})
        </foreach>
    </insert>

    <select id="selectByUser" resultMap="xxx" parameterType="com.peixinchen.mybatis_xml.User">
        select uid, username, password from users where
        <if test="user.a != null">
            uid = #{user.a}
        </if>
        <if test="user.b != null">
            and username = #{user.b}
        </if>
        <if test="user.c != null">
            and password = #{user.c}
        </if>
    </select>
</mapper>

2-4-4 在 yml 中声明 mapper.xml 的路径

mybatis:
  mapper-locations: classpath:mapper/**.xml

回到目录…

三、参数占位符 #{} 和 ${}

#{}:预编译处理。会帮我们加 引号 处理,防止SQL注入。
${}:字符直接替换。在某些特定的场景使用。

#{} 传递字符串类型的字段:

@Select("select username from users where username = #{username}")
User select(@Param("username") String username);
// select username from users where username = "wangshaoyu"; // √

@Select("select username from users where username = ${username}")
User select(@Param("username") String username);
// select username from users where username = wangshaoyu; // ×

${} 传递整型的字段:

@Select("select * from users where username = #{username} offset ${offset} limit ${limit}")
void sort(@Param("username") String username, 
		  @Param("offset") int a, 
		  @Param("limit") int b);
// select * from users where username = "wangshaoyu" offset 5 limit 3;

like 查询:

错误用法:使用 #{} 报错

select * from userinfo where username like '%#{username}%';
// 相当于 select * from userinfo where username like '%'username'%'; // ×

正确用法:使用 #{} + mysql 的内置函数 concat()

select * from userinfo where username like concat('%',#{username},'%');
// 相当于 select * from userinfo where username like '%username%'; // √

回到目录…


总结:
提示:这里对文章进行总结:
以上就是今天的学习内容,本文是MyBatis的学习,认识到MyBatis带给我们的便利,更简单的去操作数据库,MyBatis的两种使用方式:注解 / XML配置文件。之后的学习内容将持续更新!!!

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一只咸鱼。。

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

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

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

打赏作者

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

抵扣说明:

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

余额充值