4、SpringBoot+Mybatis多表操作以及增删改查

来源:互联网 发布:c语言最简单的加法程序 编辑:程序博客网 时间:2024/06/15 14:37

Mybatis整合成功之后,接下来了解一下增删改查的配置以及多表操作,先从增删改查开始

为了方便后面的多表操作,现在针对数据表的配置我这里全部在xml中配置(暂时不用注解的方式了),先看一下目前的工程结构(注意包名)
这里写图片描述
首先为了了解增删改查的操作,我这里将针对数据库中的一个文章表进行操作,文章表结构如下:
这里写图片描述
sql语句

CREATE TABLE `diary` (  `_id` int(11) NOT NULL AUTO_INCREMENT,  `title` varchar(255) DEFAULT NULL,  `content` varchar(255) DEFAULT NULL,  `pub_time` datetime DEFAULT NULL,  `user_id` int(11) NOT NULL DEFAULT '1',  PRIMARY KEY (`_id`)) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;

编写文章操作Mapper类

package com.example.demo.mapper;import java.util.List;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;import com.example.demo.bean.Diary;@Mapperpublic interface DiaryMapper {    /**     * 获取文章内容     *      * @param id     *            文章id     * @return     */    public Diary getDiaryById(@Param("id") Integer id);    /**     * 获取文章内容     *      * @param id     *            文章id     * @return     */    public Diary getDiaryById2(@Param("id") Integer id);    /**     * 获取所有文章     *      * @return     */    public List<Diary> getAllDiary();    /**     * 添加文章     */    public Integer addDiary(Diary d);    /**     * 更新文章     *      * @param d     */    public Integer updateDiary(Diary d);    /**     * 删除文章     * @param id     * @return     */    public Integer deleteDiary(@Param("id") Integer id);}

查询部分比较复杂,可以后面再看,先搞定简单的

编写结果映射文件(xml)

在src/main/resource/com/example/demo/mapper/下创建映射文件,这里我直接用操作接口类名首字母小写来作为文件名,diaryMapper .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.example.demo.mapper.DiaryMapper">    <update id="updateDiary" parameterType="com.example.demo.bean.Diary">        update diary set        title=#{title},content=#{content},pub_time=#{pubTime}        where _id=#{id}    </update>    <delete id="deleteDiary" parameterType="int">        delete from diary where        _id=#{id}    </delete>    <insert id="addDiary" useGeneratedKeys="true" keyProperty="id"        parameterType="com.example.demo.bean.Diary">        insert into diary(title,content,pub_time,user_id)        values(#{title},#{content},#{pubTime},#{userId})    </insert>    ...先省略查询部分...</mapper>

首先mapper其实描述的是一个操作接口,如这里就是描述着com.example.demo.mapper.DiaryMapper这个接口,namespace属性直接用包名.类名表示即可

namespace="com.example.demo.mapper.DiaryMapper"

下面其他Mapper接口也一样,分别对应一个mapper xml文件即可

这里标签都比较简单,从标签名就可以看出来具体的操作了(这不是废话嘛…),接着主要看一下标签内的属性:

id:可以理解为对应Java文件中的方法名parameterType:可以理解为该方法的参数类型,无参数可以不写

标签括起来的就是sql语句,其中需要引用方法参数时可以使用#{参数名}
来引用,如Java中的方法为:

public Integer deleteDiary(@Param("id") Integer mId);

这里用@Param(“id”)标注了参数mId,因此如果要在sql中引用mId的值则可以直接用#{id}

delete from diary where _id=#{id}

这里插入数据的方法是Diary文章对象:

public Integer addDiary(Diary d);

默认情况下,参数是对象时在写sql语句时可以直接用对象的属性作为参数

insert into diary(title,content,pub_time,user_id) values(#{title},#{content},#{pubTime},#{userId})

注意:增删改的结果可以返回一个int类型,一般操作成功会大于0,否则会返回0

运用

package com.example.demo.controller;import java.sql.Date;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import com.alibaba.fastjson.JSON;import com.example.demo.bean.Diary;import com.example.demo.bean.User;import com.example.demo.mapper.DiaryMapper;@RestControllerpublic class DiaryMappingController {    @Autowired    DiaryMapper diaryMapper;    ...省略其他...    @RequestMapping("/add_diary")    public String addDiary(String title, String content, int userId) {        Diary d = new Diary(title,content,new Date(System.currentTimeMillis()),userId);        int row = diaryMapper.addDiary(d);        if (row > 0) {            return "success";        } else {            return "fail";        }    }}

关于查询以及多表查询

为了体现多表查询的环境,这里在数据库中新增了用户表、标签表、文章标签对应表

--用户表(一个文章由一个用户发布)CREATE TABLE `users` (  `_id` int(11) NOT NULL AUTO_INCREMENT,  `name` varchar(255) NOT NULL,  `psw` varchar(255) NOT NULL,  `sex` varchar(2) DEFAULT NULL,  `sign` varchar(255) DEFAULT NULL,  `photo` varchar(255) DEFAULT NULL,  `age` int(11) DEFAULT '0',  PRIMARY KEY (`_id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;--标签表CREATE TABLE `tags` (  `_id` int(11) NOT NULL AUTO_INCREMENT,  `name` varchar(255) DEFAULT NULL,  `creator` int(11) NOT NULL DEFAULT '0',  PRIMARY KEY (`_id`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;--文章标签对应表(一个文章可以有多个标签)CREATE TABLE `diary_tags` (  `diary_id` int(11) NOT NULL,  `tag_id` int(11) NOT NULL,  `extras` varchar(255) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;

同时针对这些数据在Java中也定义了相应的类型来接收

User.java描述用户类型,表示文章发布者信息

package com.example.demo.bean;public class User {    private int id;    private String name;    private String sex;    private String sign;    private String photo;    private int age;    ...省略getter/setter...}

Tag.java标签类型,表示文章所在的标签

package com.example.demo.bean;/** * 标签 * @author Administrator * */public class Tag {    private int id;    private String name;    ...省略getter/setter...}

Diary.java文章类型,描述了文章信息以及作者、所处的标签等

package com.example.demo.bean;import java.sql.Date;import java.util.List;public class Diary {    private int id;    private String title;    private String content;    private Date pubTime;    private int userId;    private User user; //作者信息    private List<Tag> tags; //所处的标签,一个文章可以属于不同的标签    ...省略getter/setter...    public Diary(String title, String content, Date pubTime, int userId) {        this.title = title;        this.content = content;        this.pubTime = pubTime;        this.userId = userId;    }    public Diary() {    }}

针对上面这个复杂的结构(文章中有一个作者信息,同时有多个标签信息),如果要找出一个文章的完整信息,那么需要通过文章表中的user_id字段到users表中查询用户信息,同时还需要通过文章表的id到diary_tags表中找到所关联的标签(找到标签id)然后再从tags表中获取标签列表。因此查询的mapper配置如下

...省略前面的增删改的配置...<resultMap type="com.example.demo.bean.Diary" id="DiaryMap">        <id property="id" column="_id" />        <result property="title" column="title" />        <result property="content" column="content" />        <result property="pubTime" column="pub_time" javaType="java.sql.Date" />        <association property="user" column="user_id"            javaType="com.example.demo.bean.User">            <id property="id" column="uId" />            <result property="name" column="name" />            <result property="sex" column="sex" />            <result property="sign" column="sign" />            <result property="photo" column="photo" />            <result property="age" column="age" />        </association>        <collection property="tags" ofType="com.example.demo.bean.Tags"            column="_id" select="com.example.demo.mapper.TagMapper.getTagsByDiaryId">        </collection>    </resultMap>    <select id="getDiaryById" parameterType="int" resultMap="DiaryMap">        select        d._id,d.title,d.content,d.pub_time,d.user_id,u._id as        uId,u.name,u.sex,u.sign,u.photo,u.age        from diary d left join users u on        d.user_id=u._id where d._id=#{id}    </select>    <select id="getAllDiary" resultMap="DiaryMap">        select        d._id,d.title,d.content,d.pub_time,d.user_id,u._id as        uId,u.name,u.sex,u.sign,u.photo,u.age        from diary d left join users u on        d.user_id=u._id    </select>    <resultMap type="com.example.demo.bean.Diary" id="DiaryMap2">        <id property="id" column="_id" />        <result property="title" column="title" />        <result property="content" column="content" />        <result property="pubTime" column="pub_time" javaType="java.sql.Date" />        <result property="userId" column="user_id" />        <association property="user" column="user_id"            javaType="com.example.demo.bean.User" select="com.example.demo.mapper.UserMapper.getUserById">        </association>        <collection property="tags" ofType="com.example.demo.bean.Tags"            column="_id" select="com.example.demo.mapper.TagMapper.getTagsByDiaryId">        </collection>    </resultMap>    <select id="getDiaryById2" parameterType="int" resultMap="DiaryMap2">        select        * from diary where _id=#{id}    </select>

resultMap标签配置的是查询结果,type表示结果返回类型,id则表示该结果处理的一个独一无二名称而已
resultMap中的属性

id标签:主键映射result标签:普通属性的映射association标签:关联其他查询一个对象的映射,如当前环境的作者信息collection标签:关联其他查询的集合,如当前环境的标签列表标签上的属性property表示Java对象中的属性名column表示对应的查询结果中数据库字段名select表示该结果的其他查询方法(子查询)

映射结果的关联是有select标签中的resultMap属性来关联的,该属性值对应一个resultMap标签的id
对应关系如下:
这里写图片描述

其他类以及映射文件的情况
UserMapper.java处理用户表的用户信息操作类,这里练习的时候也可以全部写到同一个类中,现在分开主要是为了后面新增方法的需要

package com.example.demo.mapper;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;import com.example.demo.bean.User;@Mapperpublic interface UserMapper {    /**     * 根据id获取用户信息     * @param id     * @return     */    public User getUserById(@Param("id") int id);}

userMapper.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.example.demo.mapper.UserMapper">    <resultMap type="com.example.demo.bean.User" id="UserMap">        <id property="id" column="_id" />        <result property="name" column="name" />        <result property="sex" column="sex" />        <result property="sign" column="sign" />        <result property="photo" column="photo" />        <result property="age" column="age" />    </resultMap>    <select id="getUserById" parameterType="int" resultMap="UserMap">        select * from users where _id=#{id}    </select></mapper>

TagMapper.java

package com.example.demo.mapper;import java.util.List;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;import com.example.demo.bean.Tag;@Mapperpublic interface TagMapper {    /**     * 根据文章id获取标签列表      * @param diaryId     * @return     */    public List<Tag> getTagsByDiaryId(@Param("d_id") int diaryId);}

tagMapper.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.example.demo.mapper.TagMapper">    <resultMap type="com.example.demo.bean.Tag" id="TagMap">        <id property="id" column="_id" />        <result property="name" column="name" />    </resultMap>    <select id="getTagsByDiaryId" parameterType="int" resultMap="TagMap">        select * from tags where _id in (select tag_id from diary_tags where diary_id=#{d_id})    </select></mapper>

测试

这里写图片描述

源码:https://github.com/huajianzh/spring/tree/master/springdemo

[附]

MyBatis传入多个参数的问题

针对多个参数的情况,parameterType可以不用指定

1、可以直接使用#{参数下标}的方式访问

public List<XXXBean> getXXXBeanList(String xxId, String xxCode);  <select id="getXXXBeanList" resultType="XXBean">  select t.* from tableName where id = #{0} and name = #{1}  </select>  

2、之际在方法参数中使用@Parm声明各个参数的别名

public AddrInfo getAddrInfo(@Param("corpId")int corpId, @Param("addrId")int addrId);<select id="getAddrInfo"  resultMap="com.xxx.xxx.AddrInfo">       SELECT * FROM addr_info     where addr_id=#{addrId} and corp_id=#{corpId}</select>

3、封装List

public List<XXXBean> getXXXBeanList(List<String> list);  <select id="getXXXBeanList" resultType="XXBean">  select 字段... from XXX where id in  <foreach item="item" index="index" collection="list" open="(" separator="," close=")">      #{item}    </foreach>  </select>  foreach 最后的效果是select 字段... from XXX where id in ('1','2','3','4') 

4、使用Map携带多个参数

public List<XXXBean> getXXXBeanList(HashMap map);  <select id="getXXXBeanList" parameterType="hashmap" resultType="XXBean">  select 字段... from XXX where id=#{xxId} code = #{xxCode}  </select>  

其中hashmap是mybatis自己配置好的直接使用就行。map中key的名字是那个就在#{}使用那个

原创粉丝点击