一:数据封装(返回结果)
在之前的Mybaties中的接口中,返回值的类型不是很人性化,为了更加人性化,可以写一个返回类Result来更方便与前端的统一。
放在uilts目录下
Result类
package com.mybatis.mybatis.utils;
import java.util.HashMap;
import java.util.Map;
/**
* 返回数据封装类
*/
public class Result extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
public Result() {
put("code", 0);
put("msg", "success");
}
public static Result error() {
return error(500, "未知异常,请联系管理员");
}
public static Result error(String msg) {
return error(500, msg);
}
public static Result error(int code, String msg) {
Result r = new Result();
r.put("code", code);
r.put("msg", msg);
return r;
}
public static Result ok(String msg) {
Result r = new Result();
r.put("msg", msg);
return r;
}
public static Result ok(Object obj) {
Result r = new Result();
r.put("data", obj);
return r;
}
public static Result ok(Map<String, Object> map) {
Result r = new Result();
r.putAll(map);
return r;
}
public static Result ok() {
return new Result();
}
public Result put(String key, Object value) {
super.put(key, value);
return this;
}
}
之后将接口的返回值修改成如下即可
查询接口
public Result findAllUser(){
return Result.ok(userService.findAllUser());
}
删除接口
public Result deleteUserById(@PathVariable int userid){
if(userService.deleteUserById(userid) > 0){
return Result.ok("删除成功");
}
return Result.error(-1,"数据库删除失败");
}
新增接口
public Result addUser(@RequestBody User user){
if (userService.addUser(user) > 0){
return Result.ok(user);
}
return Result.error(-1,"数据库增加失败");
}
更新接口
public Result updateUser(@RequestBody User user){
if(userService.updateUser(user) > 0){
return Result.ok("更新成功");
}
return Result.error(-1,"数据库更新 失败");
}
useGeneratedKeys="true" keyProperty="id"
二:主键回填
有时候前端在新增操作的时候需要看到新增的值是什么(比如新增的id是自增长的,新增的时候并没有指定,前端看到的就是0,所以需要返回查看),这个时候就可以用上主键回填的功能。
修改前
在UserMapper.xml中修改insert部分,新增两个属性useGeneratedKeys和keyProperty
useGeneratedKeys=”true”的作用是回填keyProperty指定的值
keyProperty代表的是回填的值,此处就会回填id
<insert id="addUser" parameterType="com.mybatis.mybatis.entity.User" useGeneratedKeys="true" keyProperty="id">
insert into user (name,age) values (#{name},#{age})
</insert>
修改后(会显示数据库分配的id)
三:ResultMap
一般情况下,实体类的属性名需要和数据库的字段名对应统一,但有时候实体类的属性名和数据库名没法保持一致时,可以采用
Result Map进行对应匹配。
此处的User类的属性名和数据库中的字段名不一致
修改UserMapper.xml文件的select部分的代码如下
<select id="findAllUser" resultMap="userMap">
select * from user
</select>
<resultMap id="userMap" type="com.mybatis.mybatis.entity.User">
<!-- id映射主键 property:实体类的字段名字 column:数据库表字段名字-->
<id property="id" column="id" ></id>
<result property="name1" column="name"></result>
<result property="age" column="age"></result>
</resultMap>
-
将select部分的返回类型设置为userMap
-
在resultMap中设置userMap的样式
在resultMap中设置样式时,
< id >元素对应数据库中的字段是主键,< result>对应的是普通字段
在元素的属性设置时,property对应的是实体类中的名字,column对应的是数据库中的名字
*修改User的实体类中属性name为name1之后,其他的方法也会受到影响(一般还是与数据库对应的为好)
四:多表的查询
建表的注意事项:在数据库建表的时候,
不要使用外键
,应该在代码层维持表与表之间的关系。
1对1 需要在某一方保存对方的主键
案例
1:建表
创建idcard表和person表,样式如下
2:创建对应的实体类
Idcard.class
package com.mybatis.mybatis.entity;
import lombok.Data;
@Data
public class Idcard {
private int id;
private String code;
}
Person.class
package com.mybatis.mybatis.entity;
import lombok.Data;
@Data
public class Person {
private int id;
private int age;
private String name;
private Idcard cardid;
}
*注意:Person类中的cardid的类型是Idcard类型
3:dao层新建两个接口
IdcardMapper
package com.mybatis.mybatis.dao;
import com.mybatis.mybatis.entity.Idcard;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface IdcardMapper {
public Idcard findCardByid(int id);
}
PersonMapper
package com.mybatis.mybatis.dao;
import com.mybatis.mybatis.entity.Person;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface PersonMapper {
public List<Person> findAllPerson();
public List<Person> findAllPerson2();
}
在resources下新建IdcardMapper.xml与PersonMapper.xml
IdcardMapper.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.mybatis.mybatis.dao.IdcardMapper">
<!-- 方法1:通过sql语句查询结果得到中间表 中间表通过resultMap做映射-->
<select id="findCardByid" resultType="com.mybatis.mybatis.entity.Idcard">
select * from idcard where id = #{id}
</select>
</mapper>
PersonMapper.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.mybatis.mybatis.dao.PersonMapper">
<!-- 方法1: 一对一查询 通过sql语句查询结果得到中间表 中间表通过resultMap做映射-->
<select id="findAllPerson" resultMap="personMap">
SELECT person.*,idcard.code
from person,idcard
where person.cardid = idcard.id
</select>
<resultMap id="personMap" type="com.mybatis.mybatis.entity.Person">
<!-- id映射主键 property:实体类的字段名字 column:数据库表字段名字-->
<id property="id" column="id" ></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<association property="cardid" javaType="com.mybatis.mybatis.entity.Idcard">
<id property="id" column="cardid"></id>
<result property="code" column="code"></result>
</association>
</resultMap>
<!-- 方法2: 级联查询-->
<select id="findAllPerson2" resultMap="personMap2">
SELECT *
from person
</select>
<resultMap id="personMap2" type="com.mybatis.mybatis.entity.Person">
<!-- id映射主键 property:实体类的字段名字 column:数据库表字段名字-->
<id property="id" column="id" ></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<association property="cardid"
javaType="com.mybatis.mybatis.entity.Idcard"
column="cardid"
select="com.mybatis.mybatis.dao.IdcardMapper.findCardByid">
</association>
</resultMap>
</mapper>
其他层的代码就不附加了,重复度太高。
4:查询方式————PersonMapper.xml中反映出来了
-
一对一查询:通过sql语句查询结果得到中间表 中间表通过resultMap做映射
需要关注的是它用的sql语句,是直接把所有的结果都一次性查询出来了。
-
级联查询:通过拼接,把最后的查询结果拼接到一起吗,调用到了其他部位的查询方法。