application.properties文件:
#thymeleaf 配置 spring.thymeleaf.mode=HTML5 spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.servlet.content-type=text/html #缓存设置为false, 这样修改之后马上生效,便于调试 spring.thymeleaf.cache=false #数据库 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.jpa.properties.hibernate.hbm2ddl.auto=update #显示SQL语句 spring.jpa.show-sql=true #不加下面这句则不会默认创建MyISAM引擎的数据库 spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect #自己重写的配置类,默认使用utf8编码 spring.jpa.properties.hibernate.dialect=com.wmyskxz.demo.shiro.config.MySQLConfig 第二步:新建实体类新建一个【entity】包,在下面创建以下实体:
用户信息:
@Entity public class UserInfo { @Id @GeneratedValue private Long id; // 主键. @Column(unique = true) private String username; // 登录账户,唯一. private String name; // 名称(匿名或真实姓名),用于UI显示 private String password; // 密码. private String salt; // 加密密码的盐 @JsonIgnoreProperties(value = {"userInfos"}) @ManyToMany(fetch = FetchType.EAGER) // 立即从数据库中进行加载数据 @JoinTable(name = "SysUserRole", joinColumns = @JoinColumn(name = "uid"), inverseJoinColumns = @JoinColumn(name = "roleId")) private List<SysRole> roles; // 一个用户具有多个角色 /** getter and setter */ }角色信息:
@Entity public class SysRole { @Id @GeneratedValue private Long id; // 主键. private String name; // 角色名称,如 admin/user private String description; // 角色描述,用于UI显示 // 角色 -- 权限关系:多对多 @JsonIgnoreProperties(value = {"roles"}) @ManyToMany(fetch = FetchType.EAGER) @JoinTable(name = "SysRolePermission", joinColumns = {@JoinColumn(name = "roleId")}, inverseJoinColumns = {@JoinColumn(name = "permissionId")}) private List<SysPermission> permissions; // 用户 -- 角色关系:多对多 @JsonIgnoreProperties(value = {"roles"}) @ManyToMany @JoinTable(name = "SysUserRole", joinColumns = {@JoinColumn(name = "roleId")}, inverseJoinColumns = {@JoinColumn(name = "uid")}) private List<UserInfo> userInfos;// 一个角色对应多个用户 /** getter and setter */ }权限信息:
@Entity public class SysPermission { @Id @GeneratedValue private Long id; // 主键. private String name; // 权限名称,如 user:select private String description; // 权限描述,用于UI显示 private String url; // 权限地址. @JsonIgnoreProperties(value = {"permissions"}) @ManyToMany @JoinTable(name = "SysRolePermission", joinColumns = {@JoinColumn(name = "permissionId")}, inverseJoinColumns = {@JoinColumn(name = "roleId")}) private List<SysRole> roles; // 一个权限可以被多个角色使用 /** getter and setter */ }注意:这里有一个坑,还缠了我蛮久感觉,就是当我们想要使用RESTful风格返回给前台JSON数据的时候,这里有一个关于多对多无限循环的坑,比如当我们想要返回给前台一个用户信息时,由于一个用户拥有多个角色,一个角色又拥有多个权限,而权限跟角色也是多对多的关系,也就是造成了 查用户→查角色→查权限→查角色→查用户... 这样的无限循环,导致传输错误,所以我们根据这样的逻辑在每一个实体类返回JSON时使用了一个@JsonIgnoreProperties注解,来排除自己对自己无线引用的过程,也就是打断这样的无限循环。
根据以上的代码会自动生成user_info(用户信息表)、sys_role(角色表)、sys_permission(权限表)、sys_user_role(用户角色表)、sys_role_permission(角色权限表)这五张表,为了方便测试我们给这五张表插入一些初始化数据:
INSERT INTO `user_info` (`id`,`name`,`password`,`salt`,`username`) VALUES (1, \'管理员\',\'951cd60dec2104024949d2e0b2af45ae\', \'xbNIxrQfn6COSYn1/GdloA==\', \'wmyskxz\'); INSERT INTO `sys_permission` (`id`,`description`,`name`,`url`) VALUES (1,\'查询用户\',\'userInfo:view\',\'/userList\'); INSERT INTO `sys_permission` (`id`,`description`,`name`,`url`) VALUES (2,\'增加用户\',\'userInfo:add\',\'/userAdd\'); INSERT INTO `sys_permission` (`id`,`description`,`name`,`url`) VALUES (3,\'删除用户\',\'userInfo:delete\',\'/userDelete\'); INSERT INTO `sys_role` (`id`,`description`,`name`) VALUES (1,\'管理员\',\'admin\'); INSERT INTO `sys_role_permission` (`permission_id`,`role_id`) VALUES (1,1); INSERT INTO `sys_role_permission` (`permission_id`,`role_id`) VALUES (2,1); INSERT INTO `sys_user_role` (`role_id`,`uid`) VALUES (1,1); 第三步:配置 Shiro新建一个【config】包,在下面创建以下文件:
MySQLConfig:
public class MySQLConfig extends MySQL5InnoDBDialect { @Override public String getTableTypeString() { return "ENGINE=InnoDB DEFAULT CHARSET=utf8"; } }这个文件关联的是配置文件中最后一个配置,是让 Hibernate 默认创建 InnoDB 引擎并默认使用 utf-8 编码