1. 概述
Mybatis
是一个优秀的持久层框架,底层基于JDBC
实现与数据库的交互;
使用此框架程序员只需要通过注解或者修改xml配置文件的方式配置好需要执行的SQL
语句,MyBatis
框架会根据SQL
语句生成对应的JDBC
代码并对数据库中数据进行增删改查操作。
Mybatis
框架的简单应用架构,如图所示:
MyBatis
优势如下:
-
MyBatis
是基于 Java 的持久层框架,用于和数据库映射; -
MyBatis
避免了几乎所有的JDBC代码和手动设置参数以及获取结果集的工作; -
MyBatis
通过注解方式或者xml配置文件的方式来配置SQL和映射关系,灵活性非常高。
2.在类中使用
基于MyBatis
规范设计用户数据访问接口,在工程目录下创建包mapper
,并创建ProductMapper
接口,然后添加注解:
-
@Mapper
注解
用于描述数据层接口,告诉系统底层为此接口创建其实现类,在实现类中定义数据访问逻辑,执行与数据库的会话(交互) -
@Insert
注解
根据接口方法的参数类型自动生成插入数据的代码。 - 占位符
#{}
#{}
是 MyBatis 框架中用来表示占位符的语法。
在 @Insert
注解中,#{}
所代表的是一个占位符,它可以接受 Java
对象作为输入参数,并将其转换为预编译的 SQL
语句中的参数。使用 #{}
可以帮助我们避免 SQL 注入等问题,同时也让 SQL 写起来更加简单。
package com.tedu.egmybatis1.mapper;
import com.tedu.egmybatis1.pojo.Product;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface ProductMapper {
@Insert("INSERT INTO product(title,price,stock) " +
"VALUES(#{title},#{price},#{stock})")
int insertProduct(Product product);
/*
deleteProductById
updateProductById
*/
@Update("UPDATE product " +
"SET title=#{title},price=#{price},stock=#{stock} " +
"WHERE id=#{id}")
int updateProductById(Product product);
@Delete("DELETE FROM product WHERE id=#{id}")
int deleteProductById(Integer id);
@Select("SELECT id,title,price,stock " +
"FROM product " +
"WHERE id=#{id}")
Product selectProductById(Integer id);
@Select("SELECT id,title,price,stock " +
"FROM product ")
List<Product> selectAllProduct();
}
3.通过xml管理
上面的注解方式,可以通过xml
的方式实现。
3.1 xml与注解比较
XML
是一种可扩展性语言,用户可以自己定义标签,用来描述特定类型的数据;
XML
的语法严格,每个标签都必须有一个结束标签,标签的嵌套关系也必须合法;
3.2 和SQL注解比较
-
xml
配置SQL
,可以将SQL
语句和JAVA
代码分离开 -
xml
配置SQL
,支持动态SQL
语句 -
xml
配置SQL
,支持SQL
语句的复用
3.3 使用
- SpringBoot版本:2.6.13
- 依赖项
- MyBatis Framework
- MySQL Driver
- 在
resources
目录下创建mappers
目录,用来存放xml
配置文件 -
application.properties
中添加配置:mybatis
框架映射配置文件的位置# 设置MyBatis框架的映射(Mapper)配置文件的位置 mybatis.mapper-locations=classpath:mappers/*.xml
- 配置映射文件模板
在mappers
目录下创建WeiboMapper.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">
<!-- 1.填写namespace,填写WeiboMapper的绝对路径 -->
<mapper namespace="cn.xxx.projectname.mapper.WeiboMapper">
<!-- id的属性值要和UserMapper中定义的方法名一致 -->
<insert id="insert">
INSERT INTO user VALUES (NULL,#{username},#{password},#{nickname},#{created})
</insert>
</mapper>
id
代表调用的方法
parameterType
入参类型
resultType
返回值类型
(具体配置往下看)
3.4 xml配置SQL标签
在 Mybatis
的 XML
文件中,SQL
语句都是使用 SQL
标签来定义的。
-
select
用于查询操作,包括多表查询、条件查询等。可以使用resultType
来指定返回结果的类型。 -
insert
用于插入操作,并将其自动注入实体类中。 -
update
用于更新操作,包括更新一条记录或者批量更新。 -
delete
用于删除操作,包括删除一条记录或者批量删除。 -
if、foreach、set
用于条件控制,可以根据不同的条件进行查询、插入、更新和删除操作。if
标签用于指定可以为空的查询条件,foreach
标签用于循环查询,set
标签用于指定更新操作的字段值。
<update id="dynamicUpdate">
UPDATE weibo
<set>
<if test="content!=null">content=#{content},</if>
<if test="created!=null">created=#{created},</if>
<if test="userId!=null">user_id=#{userId}</if>
</set>
WHERE id=#{id}
</update>
<!--DELETE FROM weibo WHERE id IN (2,3,4) -->
<delete id="deleteByListId">
DELETE FROM weibo
WHERE id IN (
<foreach collection="array" item="e" separator=",">
#{e}
</foreach>
)
</update>
-
sql
:用于定义可重用的SQL
片段,通常是一些较为复杂的SQL
片段。可以在其它SQL
语句中使用include
标签来引用SQL
片段。 -
include
:用于引入外部的SQL
片段。可以在include
标签的refid
属性中指定外部SQL
片段的名字,然后在当前SQL
中使用它。
<!--WeiboMapper -->
int dynamicDelete(Integer[] ids);
int dynamicDelete2(List<Integer> ids);
<!--xml-->
<delete id="dynamicDelete2">
<include refid="deleteSQL"/>(
<foreach collection="list" item="i" separator=",">
#{i}
</foreach>
)
</delete>
<delete id="dynamicDelete">
<include refid="deleteSQL"/>(
<foreach collection="array" item="i" separator=",">
#{i}
</foreach>
)
</delete>
<sql id="deleteSQL">
DELETE FROM weibo
WHERE id IN
</sql>
-
resultMap
:结果集映射表,用于为一个查询语句的结果集与java中对象表示该结果集中记录的对应关系 -
id
用来为映射表取个名字,方便<select>
将查询结果集使用该映射表 -
type
用来指明结果集中的一条记录用哪个对象表示
<resultMap id="myMap1" type="com.xxx.projectname.pojo.WeiboVO3">
<!-- column:指定查询结果集中字段名 property:指明存入对象的哪个属性中 -->
<id column="id" property="id" /><!-- 如果查询主键字段,用id标签 -->
<result column="content" property="content" /><!--其余字段用result标签-->
<result column="user_id" property="userId" />
</resultMap>
<select id="selectWeiboVO3ById" resultMap="myMap1">
SELECT id,content,user_id
FROM weibo
WHERE id=#{id}
</select>
<!-- 针对一对多的关系,可以使用collection ,比如查询员工及其发布的微博数据 -->
<resultMap id="userWeiboMap" type="com.xxx.projectname.pojo.UserVO2 ">
<id column="uid" property="id" />
<result column="username" property="username" />
<result column="password" property="password" />
<result column="nickname" property="nickname" />
<result column="ucreated" property="created" />
<collection property="weiboList" ofType="com.xxx.projectname.pojo.Weibo">
<!-- 注意这块的column是wid,代表上面微博的主键id(别名),否则如果是id的话只会取一条,且id为用户id 。wcreated同理 -->
<id column="wid" property="id" />
<result column="content" property="content" />
<result column="wcreated" property="created" />
<result column="user_id" property="userId" />
</collection>
</resultMap>
<select id="selectUserAndWeiboById" resultMap="userWeiboMap">
SELECT u.id uid,u.username,u.password,u.nickname,u.created ucreated,
w.id wid,w.content,w.created wcreated,w.user_id
FROM user u
LEFT JOIN weibo w ON u.id=w.user_id
WHERE u.id=#{id}
</select>
public class UserVO2 {
private Integer id;
private String username;
private String password;
private String nickname;
private Date created;
private List<Weibo> weiboList;
...
}
这些
SQL
标签可以随意组合,可以使SQL
语句变得很灵活和强大。通常需要根据实际业务场景选择合适的标签来实现相应的SQL
操作。
3.5 Dao
接口设计
WeiboMapper.java
package cn.xxx.projectname.mapper;
import cn.xxx.projectname.Weibo;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface WeiboMapper {
/**在微博表中插入数据*/
int insert(Weibo weibo);
/**根据微博id查询数据*/
Weibo selectByWeiboId(int id);
/**查询所有微博信息*/
List<Weibo> selectWeibo();
/**更新微博表数据*/
int updateById(Weibo weibo);
/**删除微博表数据*/
int deleteById(int id);
}
3.6 定义映射文件WeiboMapper.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">
<!-- 1.填写namespace,填写WeiboMapper的绝对路径 -->
<mapper namespace="cn.xxx.projectname.mapper.WeiboMapper">
<!--在微博表中插入数据-->
<insert id="insert">
INSERT INTO weibo
VALUES (NULL, #{content}, #{created}, #{userId})
</insert>
<!--根据微博id查询数据-->
<select id="selectByWeiboId" resultType="cn.xxx.projectname.pojo.Weibo">
SELECT *
FROM weibo
WHERE id = #{id}
</select>
<!--查询所有微博信息-->
<select id="selectWeibo" resultType="cn.xxx.projectname.pojo.Weibo">
SELECT *
FROM weibo
</select>
<!--更新微博表数据-->
<update id="updateById">
UPDATE weibo
SET content=#{content},
created=#{created},
user_id=#{userId}
WHERE id = #{id}
</update>
<!--删除微博表数据-->
<delete id="deleteById">
DELETE
FROM weibo
WHERE id = 2
</delete>
</mapper>
4. MySQL和Java
4.1 数据类型映射对应关系
MySQL数据类型 | Java-Pojo类属性 |
---|---|
TINYINT、SMALLINT、INT |
Integer |
BIGINT |
Long |
FLOAT |
Float |
DOUBLE 、DECIMAL
|
Double |
CHAR 、VARCHAR 、TEXT ... |
String |
DATE 、TIME 、DATETIME 、TIMESTAMP
|
java.util.Date |
4.2 不同数据类型进行条件判断分类
MyBatis映射类型 | 判断 |
---|---|
String |
非null 和非空字符串 |
Long 、Integer 、Date 、Float 、Double
|
非null
|