项目实训9
1. 背景
本项目持久层实现采用的是mybatis框架
MyBatis 是一个半自动化的 ORM 框架,所谓半自动化是指 MyBatis 只支持将数据库查出的数据映射到 POJO 实体类上,而实体到数据库的映射则需要我们自己编写 SQL 语句实现,相较于Hibernate 这种完全自动化的框架,Mybatis 更加灵活,我们可以根据自身的需求编写 sql 语句来实现复杂的数据库操作。
2. 使用
- 首先引入依赖
<!--引入 mybatis-spring-boot-starter 的依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
当然,使用数据库之前得先在application-dev.properties文件中配置好数据库配置
- 创建好实体类【建议与数据库中表字段一一对应】
package com.example.guke.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User
{
private int id;
// 用户的唯一标识
@NotEmpty
private String openid;
private String nickname;
private int sex;
// 头像地址
private String headimgurl;
// 用户所在省份
private String province;
// 用户的累计积分
private int score;
public User(String openid)
{
this.openid = openid;
}
}
- 创建 Mapper 映射文件
springboot中创建映射文件有两种方式,包括xml方式和注解方式,我个人比较喜欢用注解的方式进行动态SQL的编写,下面是两种方式的展示:
基于注解:
- @Select
- @Insert
- @Update
- @Delete
package com.example.guke.mapper;
import com.example.guke.entity.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface UserMapper
{
@Insert("INSERT INTO user(openid,nickName,sex,headimgurl,province,score) " +
"VALUES(#{openid},#{nickname},#{sex},#{headimgurl},#{province},0)")
public int insertUser(User user);
@Select("SELECT * FROM user WHERE openid = #{openid}")
public User findUserByOpenid(@Param("openid") String openid);
/**
* @param openid
* @name: getHeadimgurlByOpenid
* @description: TODO 根据openid获取头像地址
* @return: java.lang.String
* @date: 2022/4/13 16:45
* @author: NiuYiq
*/
@Select("SELECT headimgurl FROM user WHERE openid = #{openid}")
public String getHeadimgurlByOpenid(@Param("openid") String openid);
/**
* @param openid
* @name: getNicknameByOpenid
* @description: TODO 根据openid获取nickname
* @return: java.lang.String
* @date: 2022/4/13 16:45
* @author: NiuYiq
*/
@Select("SELECT nickname FROM user WHERE openid = #{openid}")
public String getNicknameByOpenid(@Param("openid") String openid);
/**
* @param score
* @param openid
* @name: updateUserScore
* @description: TODO 更新user表的评分
* @return: int
* @date: 2022/5/10 21:16
* @author: NiuYiq
*/
@Update("UPDATE user SET score = score + #{score} WHERE openid = #{openid}")
int updateUserScore(@Param("score") int score, @Param("openid") String openid);
/**
* @name: getRank
* @description: TODO 获取排行榜
* @return: java.util.List<com.example.guke.entity.User>
* @date: 2022/5/18 08:42
* @author: NiuYiq
*
*/
@Select("SELECT * FROM user ORDER BY score DESC")
List<User> getRank();
/**
* @name: getScoreByOpenid
* @description: TODO 通过openid获取用户积分
* @param openid
* @return: int
* @date: 2022/5/18 08:43
* @author: NiuYiq
*
*/
@Select("SELECT score FROM user WHERE openid = #{openid}")
int getScoreByOpenid(String openid);
}
根据不同的注解可以进行不同类型的SQL语句的编写,而且十分方便。
基于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="net.biancheng.www.mapper.UserMapper">
<resultMap id="BaseResultMap" type="User">
<id column="id" jdbcType="INTEGER" property="id"/>
<result column="user_id" jdbcType="VARCHAR" property="userId"/>
<result column="user_name" jdbcType="VARCHAR" property="userName"/>
<result column="password" jdbcType="VARCHAR" property="password"/>
<result column="email" jdbcType="VARCHAR" property="email"/>
</resultMap>
<sql id="Base_Column_List">
id, user_id, user_name, password, email
</sql>
<!--根据用户名密码查询用户信息-->
<!--application.yml 中通过 type-aliases-package 指定了实体类的为了,因此-->
<select id="getByUserNameAndPassword" resultType="User">
select *
from user
where user_name = #{userName,jdbcType=VARCHAR}
and password = #{password,jdbcType=VARCHAR}
</select>
</mapper>
两种方式都行,看个人喜好,但是,我们知道 mapper 映射文件其实就是一个 XML 配置文件,它存在 XML 配置文件的通病,即编写繁琐,容易出错。即使是一个十分简单项目,涉及的 SQL 语句也都十分简单,我们仍然需要花费一定的时间在mapper 映射文件的配置上。
mapper 接口中的任何一个方法,都只能使用一种配置方式,即注解和 mapper 映射文件二选一,但不同方法之间,这两种方式则可以混合使用,例如方法 1 使用注解方式,方法 2 使用 mapper 映射文件方式。
我们可以根据 SQL 的复杂程度,选择不同的方式来提高开发效率。
- 如果没有复杂的连接查询,我们可以使用注解的方式来简化配置;
- 如果涉及的 sql 较为复杂时,则使用 XML (mapper 映射文件)的方式更好一些。
之后在业务层就可以比较方便地使用了。