MyBatis增、删、改、查操作
- 1. 增加用户操作(insert标签),返回受影响的行数.
- 1.1 返回自增id
- 2. 修改用户操作(update)
- 3. 删除用户操作(delete)
- 4. 查询用户操作(select)
- 4.1 表单查询
- 4.1.1 模糊(like)查询
- 4.2 多表查询
- 4.2.1 返回类型:resultType
- 4.2.2 返回字典映射:resultMap
- 4.2.3 多表查询
- 4.2.3.1 一对一表映射
- 演示通过文章id获得文章的所有信息:
- 4.2.3.2 一对多查询,就是所谓的一个用户对应多篇文章.
- 演示一个通过用户id查询用户所有的文章的操作:
1. 增加用户操作(insert标签),返回受影响的行数.
首先在数据库中创建一个user表:
create table user(userId int primary key auto_increment,
username varchar(128) not null,
password varchar(128) not null);
有了表,还需要创建一个实体类:
package com.example.demo.model;
import lombok.Data;
@Data //加上这个注解,可直接使用set/get等方法
public class User {
private Integer userId;
private String username;
private String password;
}
这里的数据库表中的字段名和实体类中的成员变量名字最好相同.
controller层代码:
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.model.UserInfo;
import com.example.demo.servce.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@Autowired
public UserService userMapper;
@RequestMapping("/add")
public int add(User user){
if(user==null)return 0;
return userMapper.add(user);
}
}
service 层代码:
package com.example.demo.servce;
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.User;
import com.example.demo.model.UserInfo;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class UserService {
@Resource
public UserMapper userMapper;
public int add(User user){
return userMapper.add(user);
}
}
mapper层代码:
package com.example.demo.mapper;
import com.example.demo.model.User;
import com.example.demo.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface UserMapper {
public int add(User user);
}
xml文件中添加insert标签和插入语句如下:
<insert id="add">
insert into user (username,password)values(#{username},#{password})
</insert>
通过网页输入url直接访问:
结果:
1.1 返回自增id
controller层代码:
@RequestMapping("/add2")
public int add2(User user){
userMapper.add_increment(user);
return user.getUserId();
}
service层代码:
public int add_increment(User user){
return userMapper.add_increment(user);
}
mapper层代码:
public int add_increment(User user);
.xml文件中代码:
<!-->在mybatis的XML映射器中设置useGeneratedKeys=true,是为了在执行insert 、update操作后能获取操作成功后的插入对象的自增主键id<!-->
<!-->keyProperty指定在Java 实体类中对应的主键<!-->
<!-->keyColumn指的是数据库表中自增主键的字段名<!-->
<insert id="add_increment" useGeneratedKeys="true" keyColumn="userId" keyProperty="userId">
insert into user (username,password)values(#{username},#{password})
</insert>
访问结果:
数据库中结果:
2. 修改用户操作(update)
controller层代码:
@RequestMapping("/up")
public int update(Integer userId,String username){
return userMapper.update(userId,username);
}
service层代码:
public int update(Integer uid,String name){
return userMapper.update(uid,name);
}
mapper层代码:
public int update(@Param("userId") Integer userId,@Param("username") String username);
.xml文件代码:
<update id="update">
update user set username=#{username}where userId=#{userId}
</update>
访问结果:
数据库中结果:
3. 删除用户操作(delete)
controller层代码:
@RequestMapping("del")
public int del(Integer userId){
return userMapper.del(userId);
}
service层代码:
public int del(Integer userId){
return userMapper.del(userId);
}
mapper层代码:
public int del(@Param("userId") Integer userId);
.xml文件代码:
<delete id="del">
delete from user where userId=#{userId}
</delete>
访问结果:
数据库查询结果(前后对比图):
4. 查询用户操作(select)
- 表单查询
- 多表查询
4.1 表单查询
controller层代码:
@RequestMapping("/getu")
public User getUserById2(Integer userId) {
return userMapper.getUserById2(userId);
}
service层代码:
public User getUserById2(Integer id ){
return userMapper.getUserById2(id);
}
mapper层代码:
public User getUserById2(@Param("userId")Integer userId);
.xml文件代码:
<select id="getUserById2" resultType="com.example.demo.model.User"> <!-->resultType表示返回的类型<!-->
select * from user where userId =#{userId}
</select>
访问结果:
数据库中:
4.1.1 模糊(like)查询
controller层代码:
@RequestMapping("like")
public User find(String username){
return userMapper.likefind(username);
}
service层代码:
public User likefind(String username){
return userMapper.likefind(username);
}
mapper层代码:
//模糊查询
public User likefind(@Param("username") String username);
.xml文件代码:
<select id="likefind" resultType="com.example.demo.model.User">
<!-- select * from user where username=#{username}-->
select * from user where username like '%${username}%'
</select>
注意使用迷糊查询时:使用’%#{username}%’ 时,会报错,因为#{}会对字符串自动进行加引号处理,可以使用concat(‘%’,#{username},‘%’)来代替.
访问结果:
数据库中数据:
4.2 多表查询
如果是增、删、改返回搜影响的⾏数,那么在 mapper.xml 中是可以不设置返回的类型的.
然⽽即使是最简单查询⽤户的名称也要设置返回的类型,否则会出现错误。
4.2.1 返回类型:resultType
直接返回实体类
列如:
<select id="likefind" resultType="com.example.demo.model.User">
<!-- select * from user where username=#{username}-->
select * from user where username like '%${username}%'
</select>
4.2.2 返回字典映射:resultMap
resultMap 使⽤场景:
1.字段名称和程序中的属性名不同的情况,可使⽤ resultMap 配置映射;
2.⼀对⼀和⼀对多关系可以使⽤ resultMap 映射并查询数据
字段名和属性名不同的情况:
package com.example.demo.model;
import lombok.Data;
@Data
public class User {
private Integer id; // userId被改成了id
private String username;
private String password;
}
上述数据库个实体类的id被改成了不同的名字,这时候查询时查不到数据的,就需要使用resultMap来一一映射.
在上述情况下,通过如下语句查询:
<select id="resultMapfind" resultType="com.example.demo.model.User">
<!--此处你通过User类来返回类型,可是User类中没有userId这个成员,只有id成员,
userId是有值的,id是没有值的,返回类中的Integer类型的id就为null,
此处记住实体类中最好不要用int等类型,因为不支持null,一旦用了int等类型,一旦报错无从查找-->
select * from user where userid=#{userId}
</select>
结果(id的结果查询为null):
使用resultMap查询,使用下面语句:
<resultMap id="BaseMap" type="com.example.demo.model.User">
<id column="userId" property="id"></id>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
</resultMap>
<select id="resultMapfind" resultMap="BaseMap">
select * from user where userId=#{userId}
</select>
查询结果(id有值了):
4.2.3 多表查询
首先创建两张表(用户表/文章表):
-- 创建⽂章表
drop table if exists articleinfo;
create table articleinfo(
id int primary key auto_increment,
title varchar(100) not null,
content text not null,
createtime datetime default now(),
updatetime datetime default now(),
uid int not null,
rcount int not null default 1,
`state` int default 1
);
-- 创建表[⽤户表]
drop table if exists userinfo;
create table userinfo(
id int primary key auto_increment,
username varchar(100) not null,
password varchar(32) not null,
photo varchar(500) default '',
createtime datetime default now(),
updatetime datetime default now(),
`state` int default 1
);
对应的两个实体类为:
package com.example.demo.model;
import lombok.Data;
@Data
public class ArticleInfo {
private int id;
private String title;
private String content;
private String createtime;
private String updatetime;
private int uid;
private int rcount;
private int state;
private UserInfo userInfo; //这里是文章对应的用户 一对一
}
package com.example.demo.model;
import lombok.Data;
import org.springframework.beans.factory.annotation.Configurable;
import java.util.List;
@Data
public class UserInfo {
private Integer id;
private String name;
private String password;
private String photo;
private String createtime;
private String updatetime;
private int state;
private List<ArticleInfo> artlist; //这里是用户对应的文章 多对一
}
4.2.3.1 一对一表映射
⼀对⼀映射要使⽤ 标签,具体实现如下(⼀篇⽂章只对应⼀个作者):
<?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.ArticleMapper">
<resultMap id="BaseMap" type="com.example.demo.model.ArticleInfo">
<id column="id" property="id"></id>
<result column="title" property="title"></result>
<result column="content" property="content"></result>
<result column="createtime" property="createtime"></result>
<result column="updatetime" property="updatetime"></result>
<result column="uid" property="uid"></result>
<result column="rcount" property="rcount"></result>
<result column="state" property="state"></result>
<association property="userInfo" <!--</这个userinfo 就是对应实体类>-->
resultMap="com.example.demo.mapper.UserMapper.BseMap" <!--</这个路径为UserMapper.xml文件中id叫BseMap的resultMap >-->
columnPrefix="u_"> <!--</给column属性加上前缀作用下面写了>-->
</association>
</resultMap>
<select id="getArticle" resultMap="BaseMap">
select a.*,u.id u_id,u.username u_username,u.password u_password ,u.createtime u_createtime from articleinfo a left join userinfo u on
a.uid=u.id
where a.id=#{id}
</select>
</mapper>
以上使⽤ 标签,表示⼀对⼀的结果映射:
property 属性:指定 Article 中对应的属性,即⽤户。
resultMap 属性:指定关联的结果集映射,将基于该映射配置来组织⽤户数据。
columnPrefix 属性:绑定⼀对⼀对象时,是通过columnPrefix+association.resultMap.column 来映射结果集字段。(columnPrefix 如果省略,并且恰好两个表中如果有相同的字段,那么就会导致查询出错)
association.resultMap.column是指 标签中 resultMap属性,对应的结果集映射中,column字段
演示通过文章id获得文章的所有信息:
controller层代码:
@RequestMapping("/a")
public ArticleInfo getAll(Integer id) {
return userMapper.getAll(id);
}
service层代码:
public ArticleInfo getAll(Integer id) {
return articleMapper.getArticle(id);
}
mapepr层代码:
@Mapper
public interface ArticleMapper {
//一对一
//根据文章id获取文章
public ArticleInfo getArticle(@Param("id")Integer id);
}
.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.ArticleMapper">
<resultMap id="BaseMap" type="com.example.demo.model.ArticleInfo">
<id column="id" property="id"></id>
<result column="title" property="title"></result>
<result column="content" property="content"></result>
<result column="createtime" property="createtime"></result>
<result column="updatetime" property="updatetime"></result>
<result column="uid" property="uid"></result>
<result column="rcount" property="rcount"></result>
<result column="state" property="state"></result>
<association property="userInfo"
resultMap="com.example.demo.mapper.UserMapper.BseMap"
columnPrefix="u_">
</association>
</resultMap>
<select id="getArticle" resultMap="BaseMap">
select a.*,u.id u_id,u.username u_username,u.password u_password ,u.createtime u_createtime from articleinfo a left join userinfo u on
a.uid=u.id
where a.id=#{id}
</select>
</mapper>
访问的结果:
数据库中数据:
4.2.3.2 一对多查询,就是所谓的一个用户对应多篇文章.
⼀对多需要使⽤ <collection> 标签,⽤法和 <association> 相同.
<resultMap id="BseMap" type="com.example.demo.model.UserInfo">
<!-- 主键映射 -->
<id column="id" property="id"></id>
<!-- 普通属性映射 -->
<result column="username" property="name"></result>
<result column="password" property="password"></result>
<result column="photo" property="photo"></result>
<result column="createtime" property="createtime"></result>
<result column="updatetime" property="updatetime"></result>
<result column="state" property="state"></result>
<collection property="artlist"
resultMap="com.example.demo.mapper.ArticleMapper.BaseMap"
columnPrefix="a_"></collection>
</resultMap>
<!--多表查询一对多的查询-->
<select id="getUserAndArticleByUid" resultMap="BseMap">
select u.*,a.id a_id,a.title a_title,a.content a_content,
a.createtime a_createtime,
a.updatetime a_updatetime from userinfo u left join articleinfo a
on u.id=a.uid where u.id=#{uid}
</select>
演示一个通过用户id查询用户所有的文章的操作:
controller层代码:
@RequestMapping("/b")
public UserInfo getUserByid(Integer id){
return userMapper.getUserAndArticleByUid(id);
}
service层代码:
public UserInfo getUserAndArticleByUid(Integer id){
return userMapper.getUserAndArticleByUid(id);
}
mapper层代码:
//多对一
//查询用户及用户的所有文章,根据id
public UserInfo getUserAndArticleByUid(@Param("uid") Integer uid);
.xml文件代码:
<resultMap id="BseMap" type="com.example.demo.model.UserInfo">
<!-- 主键映射 -->
<id column="id" property="id"></id>
<!-- 普通属性映射 -->
<result column="username" property="name"></result>
<result column="password" property="password"></result>
<result column="photo" property="photo"></result>
<result column="createtime" property="createtime"></result>
<result column="updatetime" property="updatetime"></result>
<result column="state" property="state"></result>
<collection property="artlist"
resultMap="com.example.demo.mapper.ArticleMapper.BaseMap"
columnPrefix="a_"></collection>
</resultMap>
<!--多表查询一对多的查询-->
<select id="getUserAndArticleByUid" resultMap="BseMap">
select u.*,a.id a_id,a.title a_title,a.content a_content,
a.createtime a_createtime,
a.updatetime a_updatetime from userinfo u left join articleinfo a
on u.id=a.uid where u.id=#{uid}
</select>
访问查询结果(用户1有三篇文章):
数据库数据(用户1有三篇文章):