文章目录
MyBatis环境初始化
概述
Mybatis是一个优秀的持久层(数据层)框架,底层基于JDBC实现与数据库的交互。并在JDBC操作的基础上做了封装和优化,它借助灵活的动态SQL,参数及结果集的映射方式,更好的适应了当前互联网技术的发展。Mybatis框架的简单应用架构,如图所示:
在当今的互联网应用中项目,mybatis框架通常会由spring框架进行资源整合,作为数据层技术实现数据交互操作。
创建项目模块
在spr-boot工程下创建项目moudle,名字为spr-mybatis,其初始pom.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
</parent>
<groupId>com.cy</groupId>
<artifactId>spr-mybatis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>03-mybatis</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
</project>
添加项目依赖
mysql数据库驱动依赖,例如:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
添加mybatis依赖(参考官方),例如:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
我们添加了mybatis依赖以后,spring框架启动时会对mybatis进行自动配置。例如SqlSessionFactory工厂对象的创建。
Mybatis简易配置实现。
假如需要对mybatis框架进行简易配置,可以创建并打开application.properties文件,在此文件中进行基本配置(可选,暂时可以不配置),例如:
#设置连接数据库的url、username、password,这三部分不能省略
spring.datasource.url=jdbc:mysql://localhost:3306/jy-blog?serverTimezone=Asia/Shanghai&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
#设置池中最小连接数
spring.datasource.hikari.minimum-idle=5
#设置池中最大连接数
spring.datasource.hikari.maximum-pool-size=15
#设置事务自动提交
spring.datasource.hikari.auto-commit=true
#设置空间链接多长时间后被释放
spring.datasource.hikari.idle-timeout=30000
#设置连接池的名字
spring.datasource.hikari.pool-name=JyHikariCP
#设置连接超时时间(客户端一直请求不到连接时,在这个时间以后会抛出连接超时)
spring.datasource.hikari.connection-timeout=30000
#连接测试
spring.datasource.hikari.connection-test-query=SELECT 1
mybatis.configuration.default-statement-timeout=30
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.mapper-locations=classpath:/mapper/*.xml
配置mybatis中的sql日志的输出:(com.cy为我们写的项目的根包)
logging.level.com.spring=DEBUG
创建项目启动类
创建项目启动类,代码如下:
package com.spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyBatisApplication {//Application.class
public static void main(String[] args) {//Main Thread
SpringApplication.run(MyBatisApplication .class, args);
}
}
环境测试代码实现
在src/test/java目录中添加测试类,对mybatis框架整合进行基本测试,代码如下:
package com.spring;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
@SpringBootTest
public class ConnectionTests {
@Autowired
private DataSource dataSource;
@Test
void testGetConnection() throws SQLException {
Connection conn = dataSource.getConnection();
System.out.println(conn);
}
}
package com.spring;
@SpringBootTest
public class SqlSessionTests {
@Autowired
private SqlSession sqlSession;
@Test
public void testGetConnection() {
Connection conn=sqlSession.getConnection();
System.out.println("connection="+conn);
}
}
在SpringBoot脚手架工程中,Spring框架会基于MyBatis框架底层配置,创建SqlSessionFactory对象,然后再通过此工厂对象创建SqlSession,最后基于Springku框架为测试类注入SqlSession对象,接下来,我们可以通过SqlSession对象实现与数据库的会话了。如图所示:
课堂练习
基于mybatis实现一个简易的查询映射,从数据库查询一条记录存储到map对象。
第一步:定义sql映射文件(这个文件中按照mybatis语法结构定义我们的sql映射元素,参考官方mybatis.org/mybatis-3)
在项目的resources目录下创建mapper目录,并在此目录中创建NoticeEgMapper.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.spring.dao.NoticeMapper">
<!--这里的每个sql元素都会在服务启动时进行解析,并将解析的结果存储到MappedStatement对象-->
<select id="selectById" resultType="map">
select *
from tb_sys_notices
where id = #{id}
</select>
</mapper>
第二步:确定springboot配置文件(application.properties)中指定了sql映射文件的路径
mybatis.mapper-locations=classpath:/mapper/*.xml
第三步:编写测试类,基于sqlSession对象查询数据库数据。
在项目的test目录下创建单元测试类,进行功能测试,代码如下:
package com.spring;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.sql.Connection;
@SpringBootTest
public class SqlSessionTests {
/**
* SqlSession是MyBatis官方提供的一个与数据库进行会话的接口。
* 在springboot工程中假如添加了mybatis-spring-boot-starter依赖,
* 项目中就有了这个接口,并且在服务启动时可以为我们创建一个SqlSession
* 对象(?)
*/
@Autowired
private SqlSession sqlSession;//SqlSessionTemplate
@Test
void testGetConnection(){
Connection connection = sqlSession.getConnection();//底层还是通过DataSource对象获取连接
System.out.println(connection);
}
@Test
void testSelectNotice(){
//1.定义statement对象(命名空间+元素id),系统底层会基于这个key找到sql
String statement="com.spring.dao.NoticeMapper.selectById";
//2.基于sqlSession实现与数据库的会话,这里表示查询一条记录
Object result = sqlSession.selectOne(statement,1);
System.out.println(result);
System.out.println(result.getClass());
}
}
系统公告综合实践
业务描述
基于SpringBoot脚手架工程对MyBatis框架进行整合,然后实现对通知模块数据的基本操作,通过这个实践帮助我们在业务的基础上掌握mybatis的基本应用(例如API的应用,工作机制,动态SQL-基于条件动态构建sql语句)
Pojo类设计
创建Notice类,借助此类对象封装公告(通知)数据。
package com.spring.pojo;
public class Notice {
private Long id;
private String title;
private String type;
private String content;
private String status;
private Long userId;
private Date createdTime;
private Date modifiedTime;
private String remark;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Date getCreatedTime() {
return createdTime;
}
public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
}
public Date getModifiedTime() {
return modifiedTime;
}
public void setModifiedTime(Date modifiedTime) {
this.modifiedTime = modifiedTime;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public String toString() {//alt+insert
return "Notice{" +
"id=" + id +
", title='" + title + '\'' +
", type='" + type + '\'' +
", content='" + content + '\'' +
", status='" + status + '\'' +
", userId=" + userId +
", createdTime=" + createdTime +
", modifiedTime=" + modifiedTime +
", remark='" + remark + '\'' +
'}';
}
Dao接口及方法
第一步:定义通告业务数据层接口及业务方法。借助此类型的对象基于MyBatis技术实现与数据库的交互。
package com.spring.dao;
@Mapper
public interface NoticeDao {
/**
* 基于id查询notice对象
* @param id 公告唯一标识id
* @return 基于id查询到结果
* 建议:简单sql映射语句可以直接写到接口方法上,复杂sql还是推荐写到xml映射文件
*/
@Select("select * from tb_sys_notices where id=#{id}")
Notice selectById(Long id);
/**
* 基于条件查询公告信息
* @param notice 用于封装查询参数
* @return 基于查询条件查询到结果
*/
List<Notice> selectNotices(Notice notice);
/**
* 基于id删除公告信息
* @param id
* @return 删除了几行
* 说明:在jdk8之前,对于接口方法,假如参数有多个或者参数是数组,是不可以
* 直接在sql映射文件中使用参数名的,需要通过@Param这个注解定义参数名,然后
* 在sql映射语句中使用@Param注解中的名字获取参数数据。对于数组而言在sql映射
* 中可以直接使用array进行接收也可以。
*/
int deleteById(@Param("ids") Long... id);//array
/**
* 持久化notice对象数据
* @param notice (封装了要更新的数据)
* @return 返回更新的行数。
*/
int updateNotice(Notice notice);
/**
* 持久化notice对象数据
* @param notice (封装了要写入的数据)
* @return 返回写入的行数。
*/
int insertNotice(Notice notice);
}
其中:@Mapper是由MyBatis框架中定义的一个描述数据层接口的的注解(所有的注解只起到一个描述性的作用),当系统启动时,会对启动类所在包以及子包中的类进行扫描,假如发现接口上有@Mapper注解(mybatis提供),系统底层会基于接口创建其实现类(借助反射包中Proxy类进行创建)的对象,并将对象交给spring管理。在实现类的内部,底层会又基于sqlsession对象(SqlSessionTemplate)实现数据访问和操作。
第二步:创建NoticeDao接口对应的SQL映射文件,名字为NoticeDaoMapper.xml,存储在resources/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 namespace="com.spring.dao.NoticeDao">
</mapper>
第三步:在映射文件中添加对应的sql映射,关键代码如下:
<!--假如Dao接口方法上写了sql映射,映射文件中就不需要再写sql映射了-->
<!--
<select id="selectById" resultType="com.spring.pojo.Notice">
select id,title,type,content,status,user_id userId,
created_time createdTime,modified_time modifiedTime,remark
from tb_sys_notices
where id=#{id}
</select>
-->
<!--动态sql应用(sql语句可以根据查询条件进行动态构建)-->
<select id="selectNotices"
parameterType="com.spring.pojo.Notice"
resultType="com.spring.pojo.Notice">
select id,title,type,content,status,user_id ,
created_time,modified_time,remark
from tb_sys_notices
<where>
<if test="title!=null and title!=''">
title like concat("%",#{title},"%")
</if>
<if test="status==1 or status==0">
and status=#{status}
</if>
</where>
</select>
<!--基于元素id执行删除操作-->
<delete id="deleteById">
delete from tb_sys_notices
<where>
<choose>
<when test="ids!=null and ids.length>0">
id in <!--(1,2,3,4)-->
<foreach collection="ids" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</when>
<otherwise>
1=2
</otherwise>
</choose>
</where>
</delete>
<!--更新Notice对象-->
<update id="updateNotice" parameterType="com.spring.pojo.Notice">
update tb_sys_notices
<set>
<if test="status==1 or status==0">status=#{status},</if>
<if test="content!=null and content!=''">content=#{content},</if>
<if test="modifiedTime==null">modified_time=now(),</if>
</set>
where id=#{id}
</update>
<!-- 添加新的notice-->
<insert id="insertNotice" parameterType="com.spring.pojo.Notice">
insert into tb_sys_notices
(title,type,content,status,user_id,created_time,modified_time,remark)
values
(#{title},#{type},#{content},#{status},#{userId},now(),now(),#{remark})
</insert>
单元测试实现及分析
在src/java/test目录下定义单元测试类,对NoticeDao对象进行应用测试。
package com.spring;
import com.spring.dao.NoticeDao;
import com.spring.pojo.Notice;
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
public class NoticeDaoTests {
@Autowired
private NoticeDao noticeDao;
@Test
void testSelectById(){
Notice notice = noticeDao.selectById(1L);
System.out.println(notice);
}
/**
* 基于多个条件查询notice信息
*/
@Test
void testSelectNotices(){
Notice notice=new Notice();
//notice.setTitle("title-");
//notice.setStatus("0");
List<Notice> notices = noticeDao.selectNotices(notice);
for(Notice n:notices){
System.out.println(n);
}
}
@Test
void testDeleteById(){
int rows = noticeDao.deleteById(100L,200L);
System.out.println(rows);
}
@Test
void testUpdateNotice(){
Notice notice = noticeDao.selectById(5L);
notice.setContent("Content-E");
notice.setStatus("0");
notice.setModifiedTime(new Date());
noticeDao.updateNotice(notice);
}
@Test
void testInsertNotice(){
Notice notice=new Notice();
notice.setTitle("Title-X");
notice.setContent("Content-Y");
notice.setStatus("1");
notice.setType("1");
notice.setUserId(102L);
notice.setCreatedTime(new Date());
notice.setModifiedTime(new Date());
noticeDao.insertNotice(notice);
}
}
文章标签综合实践
业务描述
我们发布文章或者发布一个问题,一般都会指定一个标签(Tag),在这个实践中我们就基于标签做一个CRUD业务的实践。
通过这个业务实践,强化单表的增删改查的操作,同时掌握基于注解方式的SQL映射实现(@Select,@Insert,@Update,@Delete)。
Tag表设计
create table tb_sys_tags
(
id bigint(20) unsigned auto_increment,
name varchar(50) default 'java',
remark varchar(100) default '',
created_time datetime,
modified_time datetime,
primary key (id)
);
Pojo对象
创建Tag对象用于封装标签信息
package com.spring.pojo;
import java.util.Date;
/**
* 创建一个文章标签对象
*/
public class Tag {
private Long id;
private String name;
private String remark;
private Date createdTime;
private Date modifiedTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Date getCreatedTime() {
return createdTime;
}
public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
}
public Date getModifiedTime() {
return modifiedTime;
}
public void setModifiedTime(Date modifiedTime) {
this.modifiedTime = modifiedTime;
}
@Override
public String toString() {
return "Tag{" +
"id=" + id +
", name='" + name + '\'' +
", remark='" + remark + '\'' +
", createdTime=" + createdTime +
", modifiedTime=" + modifiedTime +
'}';
}
}
Dao接口对象
创建Dao接口封装Tag的数据访问操作。
package com.spring.dao;
import com.spring.pojo.Tag;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface TagDao {
@Select("select * from tb_sys_tags")
List<Tag> list();
@Insert("insert into tb_sys_tags (name,remark,created_time,modified_time) " +
"values (#{name},#{remark},#{createdTime},#{modifiedTime})")
int insert(Tag tag);
@Update("update tb_sys_tags set name=#{name},remark=#{remark},modified_time=#{modifiedTime} " +
"where id=#{id}")
int update(Tag tag);
@Delete("delete from tb_sys_tags where id=#{id}")
int deleteById(Long id);
}
单元测试分析与实践
编写TagDao接口的单元类,针对TagDao接口中的具体数据操作方法进行单元测试。
package com.spring;
import com.spring.dao.TagDao;
import com.spring.pojo.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Date;
import java.util.List;
@SpringBootTest
public class TagDaoTests {
@Autowired
private TagDao tagDao;
@Test
void testInsert(){
Tag tag=new Tag();
tag.setName("mysql");
tag.setRemark("mysql...");
tag.setCreatedTime(new Date());
tag.setModifiedTime(new Date());
tagDao.insert(tag);
}
@Test
void testList(){
List<Tag> list = tagDao.list();
System.out.println(list.size());
}
@Test
void testUpdate(){
Tag tag=new Tag();
tag.setId(2L);
tag.setName("TiDB");
tag.setRemark("TiDB...");
tag.setModifiedTime(new Date());
tagDao.update(tag);
}
@Test
void testDeleteById(){
tagDao.deleteById(2L);
}
}
博客文章综合实践
业务描述
基于需求实现文章的发布和查询,要求在发布文章时,要给文章指定标签,还有在查询文章时,将文章所有的标签也要查询出来。通过这个案例掌握mybatis中的一些更加高级应用技巧。
Article表设计
基于业务创建文章表,例如:
create table tb_sys_articles
(
id bigint(20) unsigned auto_increment comment 'ID',
title varchar(50) not null comment '标题',
type char(1) not null comment '类型(1 原创 2 转载 3翻译)',
content varchar(500) default null comment '文章内容',
status char(1) default '0' comment '状态(1审核 2通过 3关闭)',
user_id bigint(20) unsigned not null comment '用户id',
created_time datetime comment '创建时间',
modified_time datetime comment '更新时间',
remark varchar(255) comment '备注',
primary key (id)
) engine=innodb auto_increment=1 comment = '通知公告表';
基于业务创建文章、标签关系表(文章和标签是一种多对多的关系,这种关系需要一张关系表。)
create table tb_article_tags
(
id bigint(20) unsigned auto_increment comment 'ID',
article_id bigint(20) unsigned comment '文章 ID',
tag_id bigint(20) unsigned comment '标签 ID',
created_time datetime comment '创建时间',
modified_time datetime comment '更新时间',
primary key (id)
)
Pojo类的设计
package com.spring.pojo;
import java.util.Date;
import java.util.List;
public class Article {
private Long id;
private String title;
private String type;
private String status;
private String content;
private Long userId;
private Date createdTime;
private Date modifiedTime;
private String remark;
private List<Tag> tags;
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Date getCreatedTime() {
return createdTime;
}
public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
}
public Date getModifiedTime() {
return modifiedTime;
}
public void setModifiedTime(Date modifiedTime) {
this.modifiedTime = modifiedTime;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public String toString() {
return "Article{" +
"id=" + id +
", title='" + title + '\'' +
", type='" + type + '\'' +
", status='" + status + '\'' +
", content='" + content + '\'' +
", userId=" + userId +
", createdTime=" + createdTime +
", modifiedTime=" + modifiedTime +
", remark='" + remark + '\'' +
", tags=" + tags +
'}';
}
}
Dao接口的设计
第一步:定义ArticleDao接口及sql映射设计(对应文章表的数据操作)。
package com.spring.dao;
import com.spring.pojo.Article;
import org.apache.ibatis.annotations.Mapper;
/**
* 定义文章dao
*/
@Mapper
public interface ArticleDao {
int insertArticle(Article article);
Article selectById(Long id);
}
ArticleDao接口对应的Sql映射文件ArticleDaoMapper.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.spring.dao.ArticleDao">
<insert id="insertArticle"
parameterType="com.spring.pojo.Article"
useGeneratedKeys="true"
keyProperty="id">
insert into tb_sys_articles
(title,type,content,status,user_id,created_time,modified_time,remark)
values
(#{title},#{type},#{content},#{status},#{userId},now(),now(),#{remark})
</insert>
<!--ResultMap是高级的ResultType,ResultMap可以自己定制映射规则-->
<resultMap id="articleMap" type="com.spring.pojo.Article">
<id property="id" column="id"></id>
<result property="title" column="title"></result>
<result property="type" column="type"></result>
<result property="content" column="content"></result>
<result property="status" column="status"></result>
<result property="userId" column="user_id"></result>
<result property="createdTime" column="created_time"></result>
<result property="modifiedTime" column="modified_time"></result>
<result property="remark" column="remark"></result>
<collection property="tags" ofType="com.spring.pojo.Tag">
<id property="id" column="tagId"></result>
<result property="name" column="tagName"></result>
</collection>
</resultMap>
<select id="selectById" resultMap="articleMap">
select a.id,a.title,a.type,a.content,a.status,a.user_id,
a.created_time,a.modified_time,a.remark,t.id tagId,t.name tagName
from tb_sys_articles a left join tb_article_tags at
on a.id=at.article_id left join tb_sys_tags t
on at.tag_id=t.id
where a.id=#{id}
</select>
</mapper>
第二步:定义ArticleTagDao 接口及sql映射设计(对应文章标签关系表的数据操作)
package com.spring.dao;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface ArticleTagDao {
int insertArticleTag(@Param("articleId") Long articleId,
@Param("tagIds") Long[]tagIds);
}
ArticleTagDao 对应的sql映射文件ArticalTagDaoMapper.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.spring.dao.ArticleTagDao">
<!--博客文章与标签的关系表中写入数据-->
<insert id="insertArticleTag">
insert into tb_article_tags
(article_id,tag_id)
values <!--(1,2),(1,3),(1,4)-->
<foreach collection="tagIds" separator="," item="tagId">
(#{articleId},#{tagId})
</foreach>
</insert>
</mapper>
单元测试分析和实践
构建单元测试类,对文章模块进行单元测试。
package com.spring;
import com.spring.dao.ArticleDao;
import com.spring.dao.ArticleTagDao;
import com.spring.pojo.Article;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Date;
@SpringBootTest
public class ArticleDaoTests {
@Autowired
private ArticleDao articleDao;
@Autowired
private ArticleTagDao articleTagDao;
@Test
void testAddArticle(){
//1.文章要写入到数据库
Article art=new Article();
art.setTitle("Blog-Title-A");
art.setContent("Blog-Content-A");
art.setType("2");
art.setStatus("1");
art.setRemark("..");
art.setUserId(101L);
art.setCreatedTime(new Date());
art.setModifiedTime(new Date());
articleDao.insertArticle(art);
System.out.println(art);
//2.文件和标签的关系也要写入数据库
articleTagDao.insertArticleTag(art.getId(), new Long[]{1L,3L});
}
@Test
void testSelectById(){
Article article = articleDao.selectById(4L);
System.out.println(article);
}
}
总结(Summary)
重难点分析
- MyBatis框架核心优势(简单、灵活、功能强大)
- MyBatis框架应用架构及核心API(SqlSessionFactory,SqlSession,…)
- MyBatis框架在SpringBoot工程中的整合(参考官网)
- MyBatis框架与数据库会话的入口及会话过程
- MyBatis框架中的动态SQL应用
FAQ分析
- MyBatis是什么?(持久层框架,半成品-只解决了数据的持久化问题)
- 为什么选择MyBatis?(开源,简单,功能强大,灵活,稳定,…)
- MyBatis应用场景?(互联网软件应用都倾向于使用mybatis做数据持久化)
- MyBatis框架实现与数据库交互的入口对象?SqlSession
- SqlSession对象是如何创建的?SqlSessionFactory
- 你了解哪些具体的SqlSession对象呢?(DefaultSqlSession,SqlSessionTemplate)
- @Mapper注解的作用是什么?
- MyBatis为我们的Dao接口创建的实现类及其方法内部做了什么?
BUG分析
- BindingException
- BadSqlGrammarException
- SqlSyntaxErrorException
- UnstatisfiedDependencyException
- BeanInstantiationException