阿里JAVA规范:【强制】不得使用外键与级联,一切外键概念必须在应用层解决。
原因:
当加入外键后,数据库每插入一条或删除一条数据,它都需要去看与之关联的表中是否有这个数据项,例如teacher、student表,teacher管理的student_id是student表的主键,当插入一条teacher数据时,要检查当前插入数据中的student_id是否存在于student表中,保证一致性,删除一条teacher数据时,也会触发一次级联操作,会同步更新和删除student表中的student_id。
这样就会导致大中型项目的数据库的业务变动,修改数据库的成本变高。外键影响数据库的查询、插入速度,故选择不插入外键,表与表之间的依赖关系要通过应用程序来解决。
如何做到不使用外键,目前采取的方法:
例如数据库中有用户表和角色表,以及用户对应的角色关联表。
用户表UserBean如下:
DROP TABLE "UserBean";
CREATE TABLE "UserBean" (
"user_id" NUMBER(11) NOT NULL ,
"username" VARCHAR2(40 BYTE) ,
"password" VARCHAR2(40 BYTE)
)
角色表RoleBean如下:
DROP TABLE "RoleBean";
CREATE TABLE "RoleBean" (
"role_id" NUMBER(11) NOT NULL ,
"role_name" VARCHAR2(100 BYTE) ,
"description" VARCHAR2(200 BYTE) ,
)
用户角色关联表UserRole如下:
DROP TABLE "UserRole";
CREATE TABLE "UserRole" (
"user_id" NUMBER(11) NOT NULL ,
"role_id" NUMBER(11) NOT NULL
)
这个时候在数据库表中不添加外键,而是在应用层,写sql语句时关联上。
后端使用Mybatis连接数据库,当你需要查询某个用户的角色时,在roleMapper中:
public interface RoleMapper {
//通过username查找用户角色信息
String findRoleByUsername(@Param("username") String username);
}
在roleService中:
@Service
public interface RoleService {
//通过username查找用户角色信息
String findRoleByUsername(@Param("username") String username);
}
在roleServiceImpl中:
@Service
public class RoleServiceImpl implements RoleService{
@Autowired
RoleMapper roleMapper;
@Override
public String findRoleByUsername(String username) {
return roleMapper.findRoleByUsername(username);
}
}
而在roleMapper.xml中findRoleByUsername方法的sql语句就可以写为:
<?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.tjm.mapper.RoleMapper">
<select id="findRoleByUsername" resultType="String" parameterType="String">
select
"RoleBean"."role"
from
"UserBean"
RIGHT JOIN "UserRole" on "UserBean"."user_id"="UserRole"."user_id"
LEFT JOIN "RoleBean" on "RoleBean"."role_id"="UserRole"."role_id"
where "username"=#{username}
</select>
</mapper>
通过right join和left join来关联两张表,查询出我们需要的信息,插入与删除同样这么操作,也就在不使用外键的情况下,保证了数据库中数据的一致性。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理