Springboot入门教程(2)-结合MyBatis进行增删改查

紧接着上一篇教程Springboot入门教程(1)
,这一篇我要来说明一下如何在Springboot项目中使用MyBatis来操作数据库,进行增删改查。
预备环境:除了java8以上和IntelliJ IDEA 2019以上之外,需要安装Mysql5.7以上,另外推荐Navicat作为连接数据库的客户端。
先做一下数据库准备,用Navicat连接到本地的数据库服务器,创建一个叫schoolmanager的数据库

新建数据库

在schoolmanager数据库中插入一张subject的表
创建subject表

接着开始修改代码,我们在上一篇创建的Springboot项目schoolmanager的基础上,先把上一篇中在build.gradle中的mybatis和mysql依赖包的注释去掉。


去掉数据库依赖包注释

接着需要在项目中配置数据库和mybatis,在resources中的application.properties添加如下配置

spring.datasource.url=jdbc:mysql://localhost:3306/schoolmanager?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
mybatis.mapper-locations=classpath*:mapper/*.xml
mybatis.type-aliases-package=com.example.schoolmanager.entity

这里要注意的是数据库的名称,连接数据库的用户名和密码。mybatis.mapper-locations表示指向的mybatis的mapper xml文件的存放位置,是在resources/mapper里面。而mybatis.type-aliases-package是存放实体类的包名。

之后我们需要在SchoolmanagerApplication中添加mybatis的mapper接口的包名注释

@SpringBootApplication
@MapperScan("com.example.schoolmanager.mapper")
public class SchoolmanagerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SchoolmanagerApplication.class, args);
    }

}

这里直接添加这个注释后可以指示系统直接去这个包下面找到mapper接口,省去在每个mapper接口中添加注释的麻烦。

然后根据前面配置的,我们需要创建一个entity的package,在entity下面创建一个Subject的实体类,代码如下

private Long id;
    private String name;

    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;
    }

再创建一个mapper的package,就是对应在SchoolmanagerApplication 里面配置的@MapperScan,在里面新建一个SubjectMapper的接口,代码如下

public interface SubjectMapper {
    void insertSubject(@Param("name")String name);
}

这里先写的是一个增加subject数据的接口方法。

根据之前配置的在recources路径下面创建一个mapper的文件夹,在里面创建一个SubjectMapper的xml文件,其中代码如下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mappper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.schoolmanager.mapper.SubjectMapper">
    <resultMap id="subject" type="com.example.schoolmanager.entity.Subject">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
    </resultMap>
    <insert id="insertSubject">
        insert into subject (name) values(#{name})
    </insert>
</mapper>

这个xml文件很关键,所有数据库操作都是写在这里面的。这里要注意的是这个xml文件的命名和mapper包下面的mapper接口名称必须保持一致,否则有可能运行时找不到对应的xml文件。
这里虽然在namespace中配置了对应的mapper接口,但是还是建议将两者命名一致(笔者之前就遇到了两者没有命名一致导致怎么都报找不到对应xml文件的错误)。
resultMap中,type就是对应的实体类,id是具有唯一标识的字段,一般就是对应数据库中的id,result是其他字段。property对应的是映射到实体类中的参数名称,column是sql语句输出时的列名。
insert标签就是用于插入数据的,id对应的是mapper接口中的方法名,中间就是插入一条数据的sql语句,前面一个name是数据库表中的列名,后面{}里面的name就是mapper接口中@Param的名称。

最后再写controller,在controller包下面新建一个SubjectController类,代码如下

@RestController
@RequestMapping(value = "/subject")
public class SubjectController {
    @Autowired
    SubjectMapper subjectMapper;

    @PostMapping(value = "/addSubject")
    public String addSubject(final String name){
        subjectMapper.insertSubject(name);
        return "Insert success";
    }
}

这里给这个类加了一个@RequestMapping,使该类下面接收的请求路径都有"/subject"的前缀。然后这边用到了上一篇教程提到的@PostMapping,接收的是post请求。

到这增的代码就编写完成了,可以启动项目,如果没有报错,就可以测试了。
测试推荐使用postman


用postman测试

这里返回Insert success说明请求成功,用Navicat查看subject表,会发现插入了一条新的数据。

接下来可以把删改查的代码放到一起编写。在这之前,为了让返回的数据格式更规范一些,我们先编写一个类来存放返回的数据。在entity包下新建一个类ResponseData

public class ResponseData {
    private final String message;
    private final int code;
    private final Map<String, Object> data = new HashMap<String, Object>();

    public String getMessage() {
        return message;
    }

    public int getCode() {
        return code;
    }

    public Map<String, Object> getData() {
        return data;
    }

    public ResponseData putDataValue(String key, Object value) {
        data.put(key, value);
        return this;
    }

    private ResponseData(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public static ResponseData ok() {
        return new ResponseData(200, "Ok");
    }

    public static ResponseData notFound() {
        return new ResponseData(404, "Not Found");
    }

    public static ResponseData badRequest() {
        return new ResponseData(400, "Bad Request");
    }

    public static ResponseData forbidden() {
        return new ResponseData(403, "Forbidden");
    }

    public static ResponseData unauthorized() {
        return new ResponseData(401, "unauthorized");
    }

    public static ResponseData serverInternalError() {
        return new ResponseData(500, "Server Internal Error");
    }

    public static ResponseData customerError() {
        return new ResponseData(1001, "customer Error");
    }
}

在这个类中,我们写了一些常见的返回状态,可以直接调用。
然后才修改SubjectMapper的接口,添加几个方法

public interface SubjectMapper {
    void insertSubject(@Param("name")String name);
    List<Subject> findSubjects(@Param("name")String name);
    void updateSubject(@Param("id")Long id, @Param("name")String name);
    void deleteSubject(@Param("id")Long id);
}

再修改SubjectMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mappper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.schoolmanager.mapper.SubjectMapper">
    <resultMap id="subject" type="com.example.schoolmanager.entity.Subject">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
    </resultMap>
    <insert id="insertSubject">
        insert into subject (name) values(#{name})
    </insert>
    <select id="findSubjects" resultType="com.example.schoolmanager.entity.Subject" >
        select id,name from subject where name like CONCAT('%',#{name},'%')
    </select>
    <update id="updateSubject">
        update subject
        <set>
            <if test="name != ''">name = #{name}</if>
        </set>
        where id = #{id}
    </update>
    <delete id="deleteSubject">
        delete from subject where id = #{id}
    </delete>
</mapper>

这里查的时候包含了按name进行模糊查询的功能,update的时候加了判断name是否为空。
最后修改SubjectController

@RestController
@RequestMapping(value = "/subject")
public class SubjectController {
    @Autowired
    SubjectMapper subjectMapper;

    @PostMapping(value = "/addSubject")
    public ResponseData addSubject(final String name){
        subjectMapper.insertSubject(name);
        ResponseData responseData = ResponseData.ok();
        return responseData;
    }

    @RequestMapping(value = "/subjects")
    public ResponseData findSubjects(final String name){
        List<Subject> subjectList = subjectMapper.findSubjects(name);
        ResponseData responseData = ResponseData.ok();
        responseData.putDataValue("subjects", subjectList);
        return responseData;
    }

    @PostMapping(value = "/editSubject")
    @ResponseBody
    public ResponseData editSubject(Long id, final String name)
    {
        subjectMapper.updateSubject(id, name);
        ResponseData responseData = ResponseData.ok();
        return responseData;
    }

    @PostMapping(value = "/deleteSubject")
    @ResponseBody
    public ResponseData deleteSubject(Long id)
    {
        subjectMapper.deleteSubject(id);
        ResponseData responseData = ResponseData.ok();
        return responseData;
    }
}

全部编写完成后启动项目,用postman测试。

本篇教程中的代码可以参考我在github上面的代码https://github.com/ahuadoreen/studentmanager,因为github上的代码是之前已经写好的完整版本,所以Springboot的版本号和项目名称和文中使用的不同,其余思路是一致的,可供参考使用。

补充说明:如果之前有用ssh或者ssm框架开发java web经验的可能会想,我这里的代码为什么没有service层呢。其实这是因为考虑到这是一个demo性质的项目,只是单纯的增删改查,没有复杂的业务逻辑,所以省略了service层。如果是复杂的大型项目,那么还是需要增加service层的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容