Mybatis Java API - Mapper 注解

MyBatis自诞生以来一直是一个以XML驱动的框架。配置是基于XML的,映射语句也是在XML中定义的。随着MyBatis 3的推出,有了新的选择。MyBatis 3建立在一个全面而强大的基于Java的配置API之上。该配置API是基于XML的MyBatis配置以及新的基于注解的配置的基础。注解提供了一种简单的方式来实现简单的映射语句,而不引入过多的开销。

注意:不幸的是,Java注解在表达能力和灵活性方面存在一定的限制。尽管我们花费了大量时间进行调查、设计和试验,但最强大的MyBatis映射无法只使用注解构建,除非变得荒谬可笑。C#的属性(例如)没有这些限制,因此MyBatis.NET将享受到一个更丰富的替代XML的选择。尽管如此,基于Java注解的配置也有其优点。

以下是一些注解:

Annotation(注解)Target(目标)XML equivalent(等价于)Description(描述)
@CacheNamespaceClass<cache>为给定的命名空间(即类)配置缓存。属性包括:implementation(实现类),eviction(淘汰策略),flushInterval(刷新间隔时间),size(缓存大小),readWrite(读写模式),blocking(是否阻塞),properties(其他属性)。
@PropertyN/A<property>指定属性的值或占位符(可以由在mybatis-config.xml中定义的配置属性替换)。属性包括:name(属性名),value(属性值)。(仅适用于MyBatis 3.4.2及以上版本)
@CacheNamespaceRefClass<cacheRef>引用另一个命名空间的缓存以供使用。注意,即使XML映射文件中声明的缓存使用相同的全限定类名,它们仍被视为不同的命名空间。属性包括:value(命名空间对应的Java类型)和name(命名空间名称)。如果您使用这个注解,应该指定value或name属性之一。对于value属性,指定一个Java类型来表示命名空间(命名空间名称将成为指定的Java类型的全限定类名),而对于name属性(从3.4.2版本开始可用),指定一个表示命名空间的名称。
@ConstructorArgsMethod<constructor>收集一组结果并传递给结果对象的构造函数。属性包括:value,是一个Args数组。
@ArgN/A
  • <arg>
  • <idArg>
一个构造函数参数,作为ConstructorArgs集合的一部分。属性包括:id(标识符),column(列名),javaType(Java类型),jdbcType(JDBC类型),typeHandler(类型处理器),select(查询语句),resultMap(结果映射)。id属性是一个布尔值,用于标识用于比较的属性,类似于​<idArg> XML元素。从3.5.4版本开始,它可以作为可重复注解使用。
@TypeDiscriminatorMethod<discriminator>一组值情况,可用于确定要执行的结果映射。属性包括:column(列名),javaType(Java类型),jdbcType(JDBC类型),typeHandler(类型处理器),cases(值情况)。cases属性是一个Cases数组。
@CaseN/A<case>一个值及其对应映射的单个情况。属性包括:value(值),type(类型),results(结果)。results属性是一个Results数组,因此这个Case注解类似于下面的Results注解,指定了一个实际的ResultMap。
@ResultsMethod<resultMap>一个Result映射列表,包含了特定结果列如何映射到属性或字段的详细信息。属性包括:value(值),id(标识符)。value属性是一个Result注解的数组。id属性是结果映射的名称。
@ResultN/A
  • <result>
  • <id>
一列与属性或字段之间的单个结果映射。属性包括:id(标识符),column(列名),property(属性名),javaType(Java类型),jdbcType(JDBC类型),typeHandler(类型处理器),one(单个关联),many(集合)。id属性是一个布尔值,表示该属性应该用于比较(类似于XML映射中的​<id>)。one属性用于单个关联,类似于​<association>,而many属性用于集合,类似于​<collection>。它们被命名为此,以避免类命名冲突。从3.5.4版本开始,它可以作为可重复注解使用。
@OneN/A<association>一个复杂类型的单个属性值映射。属性包括:select(完全限定名称的映射语句,即映射器方法),fetchType(覆盖该映射的全局配置参数lazyLoadingEnabled),resultMap(自3.5.5版本可用,用于映射到从select结果中的单个容器对象的完全限定名称的结果映射),columnPrefix(自3.5.5版本可用,用于对嵌套结果映射中的select列进行分组的列前缀)。注意,您将注意到,通过注解API不支持连接映射。这是由于Java注解的限制,它不允许存在循环引用。
@ManyN/A<collection>一个复杂类型的集合属性映射。属性包括:select(完全限定名称的映射语句,即映射器方法),fetchType(覆盖该映射的全局配置参数lazyLoadingEnabled),resultMap(自3.5.5版本可用,用于映射到从select结果中的集合对象的完全限定名称的结果映射),columnPrefix(自3.5.5版本可用,用于对嵌套结果映射中的select列进行分组的列前缀)。注意,您将注意到,通过注解API不支持连接映射。这是由于Java注解的限制,不允许存在循环引用。
@MapKeyMethod该注解用于返回类型为Map的方法上。它用于根据结果对象的某个属性,将结果对象的列表转换为Map。属性包括:value,该属性作为Map的键值。
@OptionsMethodAttributes of mapped statements.
 

该注解提供了访问映射语句上通常存在的各种开关和配置选项的途径。通过使用Options注解,可以以一致清晰的方式访问这些选项,而不会使每个语句注解变得复杂。属性包括:useCache=true、flushCache=FlushCachePolicy.DEFAULT、resultSetType=DEFAULT、statementType=PREPARED、fetchSize=-1、timeout=-1、useGeneratedKeys=false、keyProperty=""、keyColumn=""、resultSets="" 和 databaseId=""。

重要的是要了解,在Java注解中,无法指定null作为值。因此,一旦启用Options注解,您的语句将受到所有默认值的影响。请注意默认值,以避免意外行为发生。数据库标识(自3.5.5版本可用):如果存在已配置的DatabaseIdProvider,MyBatis将使用不带databaseId属性的Options注解,或者databaseId与当前databaseId匹配的Options注解。在找到带有和不带databaseId的情况下,后者将被丢弃。


 
  • @Insert
  • @Update
  • @Delete
  • @Select
Method
  • <insert>
  • <update>
  • <delete>
  • <select>
 

每个注解表示要执行的实际SQL语句。它们都接受一个字符串数组(或者只有一个字符串也可以)。如果传递了一个字符串数组,则会使用单个空格将它们连接起来,以分隔它们。这有助于在Java代码中构建SQL时避免“缺少空格”的问题。但是,如果您愿意,您也可以将单个字符串连接在一起。

属性包括:value,该属性是用于形成单个SQL语句的字符串数组。数据库标识(自3.5.5版本可用):如果存在已配置的DatabaseIdProvider,MyBatis将使用没有databaseId属性的语句,或者databaseId与当前databaseId匹配的语句。在找到带有和不带databaseId的情况下,后者将被丢弃。

  • @InsertProvider
  • @UpdateProvider
  • @DeleteProvider
  • @SelectProvider
Method
  • <insert>
  • <update>
  • <delete>
  • <select>
 

允许创建动态SQL。这些替代的SQL注解允许您指定一个类和一个方法名,在执行时返回要运行的SQL(自3.4.6版本开始,您可以将CharSequence指定为方法的返回类型而不是String)。在执行映射语句时,MyBatis将实例化该类,并按照提供程序指定的方式执行该方法。您可以通过ProviderContext(自MyBatis 3.4.5或更高版本可用)作为方法参数传递传递给映射器方法的对象,“Mapper接口类型”,“Mapper方法”和“Database ID”(在MyBatis 3.4或更高版本中,它允许多个参数)。

属性包括:value、type、method和databaseId。value和type属性都是类(type属性是value的别名,必须指定其中一个。但是,在指定defaultSqlProviderType为全局配置时,这两个属性都可以省略)。method是该类上的方法名称(自3.5.1版本以后,您可以省略method属性,MyBatis将通过ProviderMethodResolver接口解析目标方法。如果无法通过该接口解析,MyBatis将使用名为"provideSql"的保留回退方法)。数据库标识(自3.5.5版本可用):如果存在已配置的DatabaseIdProvider,MyBatis将使用没有databaseId属性的提供程序方法,或者databaseId与当前databaseId匹配的提供程序方法。在找到带有和不带databaseId的情况下,后者将被丢弃。

注意:在此部分之后,我们将讨论有关类的内容,它可以以更干净、更易读的方式构建动态SQL。

@ParamParameterN/A如果您的映射器方法接受多个参数,可以将此注解应用于映射器方法的参数,以为每个参数指定一个名称。否则,默认情况下,多个参数将按其位置以“param”为前缀进行命名(不包括任何RowBounds参数)。例如,#{param1}、#{param2}等是默认值。使用@Param("person")注解,则参数将被命名为#{person}。
@SelectKeyMethod<selectKey>
 

该注解可以在使用@Insert、@InsertProvider、@Update或@UpdateProvider注解的方法中复制​<selectKey>功能。对于其他方法,将忽略该注解的使用。如果您指定了@SelectKey注解,那么MyBatis将忽略通过@Options注解或配置属性设置的任何生成的键属性。

属性包括:statement(字符串数组),表示要执行的SQL语句;keyProperty,表示将使用新值更新的参数对象的属性;before,必须为true或false,表示SQL语句在插入之前或之后执行;resultType,表示keyProperty的Java类型;statementType,表示statement的类型,可以是STATEMENT、PREPARED或CALLABLE,分别对应Statement、PreparedStatement和CallableStatement,默认为PREPARED。

数据库标识(自3.5.5版本可用):如果存在已配置的DatabaseIdProvider,MyBatis将使用没有databaseId属性的语句,或者databaseId与当前databaseId匹配的语句。在找到带有和不带databaseId的情况下,后者将被丢弃。

@ResultMapMethodN/A此注解用于将XML映射器中的<resultMap>元素的ID提供给@Select或@SelectProvider注解。这允许使用注释的查询重用在XML中定义的resultmap。如果在注解的查询上同时指定了@Results或@ConstructorArgs注解,此注解将覆盖它们。
@ResultTypeMethodN/A该注解用于使用结果处理器时。在这种情况下,返回类型是void,所以MyBatis必须有一种方法来确定每一行的对象类型。如果存在XML的resultmap,则使用@ResultMap注解。如果在<select>元素中指定了结果类型,则不需要其他注解。在其他情况下,请使用此注解。例如,如果@Select注解的方法将使用结果处理器,则返回类型必须是void,并且需要使用此注解(或@ResultMap)。除非方法的返回类型是void,否则将忽略此注解的使用。
@FlushMethodN/A如果使用了此注解,可以通过在映射器接口中定义的方法调用SqlSession#flushStatements()。(适用于MyBatis 3.3或更高版本)
Mapper Annotation Examples-注解例子

以下示例展示了使用@SelectKey注解在插入之前从序列中获取一个值:

@Insert("insert into table3 (id, name) values(#{nameId}, #{name})")
@SelectKey(statement="call next value for TestSequence", keyProperty="nameId", before=true, resultType=int.class)
int insertTable3(Name name);

以下示例展示了如何使用@SelectKey注解在插入后获取自动生成的主键值:

@Insert("insert into table2 (name) values(#{name})")
@SelectKey(statement="call identity()", keyProperty="nameId", before=false, resultType=int.class)
int insertTable2(Name name);

以下示例展示了如何使用@Flush注解调用SqlSession#flushStatements()方法:

@Flush
List<BatchResult> flush();

以下示例展示了如何通过指定@Results注解的id属性来命名一个ResultMap:

@Results(id = "userResult", value = {
  @Result(property = "id", column = "uid", id = true),
  @Result(property = "firstName", column = "first_name"),
  @Result(property = "lastName", column = "last_name")
})
@Select("select * from users where id = #{id}")
User getUserById(Integer id);

@Results(id = "companyResults")
@ConstructorArgs({
  @Arg(column = "cid", javaType = Integer.class, id = true),
  @Arg(column = "name", javaType = String.class)
})
@Select("select * from company where id = #{id}")
Company getCompanyById(Integer id);

以下示例展示了使用@SelectProvider注解的单个参数:

@SelectProvider(type = UserSqlBuilder.class, method = "buildGetUsersByName")
List<User> getUsersByName(String name);

class UserSqlBuilder {
  public static String buildGetUsersByName(final String name) {
    return new SQL(){{
      SELECT("*");
      FROM("users");
      if (name != null) {
        WHERE("name like #{value} || '%'");
      }
      ORDER_BY("id");
    }}.toString();
  }
}

以下示例展示了使用@Provider注解的多个参数:

@SelectProvider(type = UserSqlBuilder.class, method = "buildGetUsersByName")
List<User> getUsersByName(
    @Param("name") String name, @Param("orderByColumn") String orderByColumn);

class UserSqlBuilder {

  // If not use @Param, you should be define same arguments with mapper method
  public static String buildGetUsersByName(
      final String name, final String orderByColumn) {
    return new SQL(){{
      SELECT("*");
      FROM("users");
      WHERE("name like #{name} || '%'");
      ORDER_BY(orderByColumn);
    }}.toString();
  }

  // If use @Param, you can define only arguments to be used
  public static String buildGetUsersByName(@Param("orderByColumn") final String orderByColumn) {
    return new SQL(){{
      SELECT("*");
      FROM("users");
      WHERE("name like #{name} || '%'");
      ORDER_BY(orderByColumn);
    }}.toString();
  }
}

该示例展示了使用全局配置将一个SQL提供器类共享给所有映射器方法的用法(自3.5.6版起可用):

Configuration configuration = new Configuration();
configuration.setDefaultSqlProviderType(TemplateFilePathProvider.class); // Specify an sql provider class for sharing on all mapper methods
// ...
// Can omit the type/value attribute on sql provider annotation
// If omit it, the MyBatis apply the class that specified on defaultSqlProviderType.
public interface UserMapper {

  @SelectProvider // Same with @SelectProvider(TemplateFilePathProvider.class)
  User findUser(int id);

  @InsertProvider // Same with @InsertProvider(TemplateFilePathProvider.class)
  void createUser(User user);

  @UpdateProvider // Same with @UpdateProvider(TemplateFilePathProvider.class)
  void updateUser(User user);

  @DeleteProvider // Same with @DeleteProvider(TemplateFilePathProvider.class)
  void deleteUser(int id);
}// Can omit the type/value attribute on sql provider annotation
// If omit it, the MyBatis apply the class that specified on defaultSqlProviderType.
public interface UserMapper {

  @SelectProvider // Same with @SelectProvider(TemplateFilePathProvider.class)
  User findUser(int id);

  @InsertProvider // Same with @InsertProvider(TemplateFilePathProvider.class)
  void createUser(User user);

  @UpdateProvider // Same with @UpdateProvider(TemplateFilePathProvider.class)
  void updateUser(User user);

  @DeleteProvider // Same with @DeleteProvider(TemplateFilePathProvider.class)
  void deleteUser(int id);
}

该示例展示了使用ProviderMethodResolver的默认实现的用法(自MyBatis 3.5.1版或更高版本起可用):

@SelectProvider(UserSqlProvider.class)
List<User> getUsersByName(String name);

// Implements the ProviderMethodResolver on your provider class
class UserSqlProvider implements ProviderMethodResolver {
  // In default implementation, it will resolve a method that method name is matched with mapper method
  public static String getUsersByName(final String name) {
    return new SQL(){{
      SELECT("*");
      FROM("users");
      if (name != null) {
        WHERE("name like #{value} || '%'");
      }
      ORDER_BY("id");
    }}.toString();
  }
}

该示例展示了在`@Statement`注解上使用`databaseId`属性的用法(自3.5.5版起可用):

@Select(value = "SELECT SYS_GUID() FROM dual", databaseId = "oracle") // Use this statement if DatabaseIdProvider provide "oracle"
@Select(value = "SELECT uuid_generate_v4()", databaseId = "postgres") // Use this statement if DatabaseIdProvider provide "postgres"
@Select("SELECT RANDOM_UUID()") // Use this statement if the DatabaseIdProvider not configured or not matches databaseId
String generateId();

  • 17
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mybatis-plus是MyBatis增强工具包,用于简化CRUD操作。该工具包为MyBatis提供了一些高效,有用,即用的功能,使用它可以有效地节省您的开发时间。Mybatis-plus特征与MyBatis完全兼容 启动时自动配置 开箱即用的用于操作数据库的界面 强大而灵活的条件包装器 生成主键的多种策略 Lambda样式的API 全能和高度可定制的代码生成器 自动分页操作 SQL注入防御 支持活动记录 支持可插拔的自定义界面 内置许多有用的扩展Mybatis-plus功能1、单表CURD(简单 + 批量)操作,自动完成(支持 like 比较等查询)。 2、分页插件,Count查询自动或自定义SQL查询。 3、Spring根据不同环境加载不同配置支持(支持typeAliasesPackage通配符扫描)。 【自动生成Entity Mapper Service文件】Mybatis-plus(Mybatis增强工具包) v3.3.2更新日志分页参数提取,单元测试用例修复 达梦数据库代码生成器表过滤支持 微软数据库代码生成器表过滤支持 修复代码生成器属性字段规则错误 SelectById 支持自定义方法名 修复分页插件获取数据库类型问题 Json转换器空值处理 bugfix(mybatis-plus-generator):SQL类型返回错误问题 调整未知方言异常,自动识别url转换小写匹配. fix: 初始化TableInfo中遇到多个字段有@TableId注解时未能抛出异常的问题 SuperController有Class参数的set方法 增加方法StrategyConfig.setSuperServiceImplClass(java.lang.Class<?>). 代码生成器命名策略调整. 扩展分页缓存key值计算. 去除方法推测,直接访问属性字段. 修正枚举处理器类型不匹配比较. 修改表前缀匹配方式 修改在Mybatis全局配置文件中设置分页插件参数不生效问题 修改在Mybatis全局配置文件中设置分页插件参数不生效问 修复PR未指定解析器的时候引发空指针 增加分页插件limit参数配置 修复指定superEntityClass重复生成父类字段问题 无主键的情况无需导入IdType与TableId包 调整生成BaseResultMap格式 支持lombok模式下选择是否进行链式set生成 修复解析器for update错误 过滤PG约束列(只留下主键约束) 增加生成器禁用模板生成 fix(kotlin): 修复动态表名BUG,最大努力替换表名 修复PG约束生成重复属性字段问题 fix(kotlin): 将LambdaUtils中缓存的key改为String 代码生成器增加数据库关键字处理接口 fix github/issues/2454 支持注解可继承 新增 AES 加密数据库用户名密码 优化方法入参泛型,支持更多类型 修复代码生成器开启移除is前缀生成实体缺少包导入 fixed github issues/2470Mybatis-plus截图
### 技术选型: ###### 后端支持: 主体支持: **JDK1.8**、**Springboot1.4.2** 页面支持:**html** ORM支持: **mybatis3.2.8** ORM插件支持: **mapper3.3**、**PageHelp4.1** 分页 权限支持:**shiro1.2.5** 访问接口支持: **swagger2** JSON支持:**fastjson** 连接池支持:**druid** 缓存支持:**ehcache** 、**guava** 参数验证支持:**jsr303** web容器支持:**内嵌tomcat** maven支持:**maven3.3.9** maven仓库支持:**阿里云** 代码精简与日志支持: **lombok** ###### 前端支持: 主体支持:**jQuery** 风格支持:**layui** 图标支持:**font-awesome** 弹窗支持:**layer** websocket支持:**sockjs** 树结构支持:**ztree** ### 支持情况 1. 修改 **config/application-dev.properties** JDBC 链接属性。 2. tomcat 端口在 **config/application-dev.properties** 更改,默认**8082**。 3. 自动创建数据库,关闭请在配置文件找到 JDBC 链接删除 **&createDatabaseIfNotExist=true**。 4. 自动运行SQL脚本,关闭请注释掉 **spring.datasource.schema**。 5. 默认登录 **admin/admin** 6. 打印后台 SQL 语句。 (打开/关闭 注释该方法 com.zyf.framework.config.MybatisAutoConfiguration.pageHelper) 7. 切换配置文件 **application.properties** 设置参数 8. 访问`http://localhost:8082/api`可以查看项目的接口情况。(打开/关闭 com.zyf.other.api.config.SwaggerConfig)。 9. 使用 html,基本使用 ajax 异步请求,页面不刷新。 10. 基于 shiro 改造的 sso 单机实现,登录生成 token 存储在用户 cookies 中,请求解析 cookies,以解析成功作为标识。 11. 交互上使用 layui,使用第三方功能。 12. 热刷新实体 mapper.xml文件 MapperRefresh.java(打开/关闭 config/application-dev.properties -> mapper.mapper-refresh-enable: true/false) 13. 自动注册枚举到 mybatis,查询出来自动转换枚举。 14. 消息转换未配置,如果需要返回 map 自动转换成 UTF-8 json 及需要保证 JDK8 LocalDateTime 类日期的正确性,请打开 com.zyf.admin.support.config.WebConfiguration.configureMessageConverters 注释部分。 15. 采用 mapper3 pageHelper 插件,因此大部分通用 dao 层及 xml 都不比书写。 16. 后台基本使用 resultFull 风格,前端做的事情比较多。 17. 对象池测试 com.zyf.other.pool.test.RunTest#main ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
本项目详细介绍请看:http://www.sojson.com/shiro (强烈推荐) Demo已经部署到线上,地址是http://shiro.itboy.net, 管理员帐号:admin,密码:sojson.com 如果密码错误,请用sojson。 PS:你可以注册自己的帐号,然后用管理员赋权限给你自己的帐号,但是,每20分钟会把数据初始化一次。建议自己下载源码,让Demo跑起来,然后跑的更快,有问题加群解决。 声明: 本人提供这个Shiro + SpringMvc + Mybatis + Redis 的Demo 本着学习的态度,如果有欠缺和不足的地方,给予指正,并且多多包涵。 “去其糟粕取其精华”。如果觉得写的好的地方就给个赞,写的不好的地方,也请多多包涵。 使用过程: 1.创建数据库。 创建语句 :tables.sql 2.插入初始化数据 插入初始化数据:init.data.sql 3.运行。 管理员帐号:admin 密码:sojson ps:定时任务的sql会把密码改变为sojson.com 新版本说明:http://www.sojson.com/blog/164.html 和 http://www.sojson.com/blog/165.html 主要解决是之前说的问题:Shiro 教程,关于最近反应的相关异常问题,解决方法合集。 项目在本页面的附件中提取。 一、Cache配置修改。 配置文件(spring-cache.xml )中已经修改为如下配置: <!-- redis 配置,也可以把配置挪到properties配置文件中,再读取 --> <!-- 这种 arguments 构造的方式,之前配置有缺点。 这里之前的配置有问题,因为参数类型不一致,有时候jar和环境的问题,导致参数根据index对应,会处理问题, 理论上加另一个 name,就可以解决,现在把name 和type都加上,更保险。 --> 二、登录获取上一个URL地址报错。 当没有获取到退出前的request ,为null 的时候会报错。在(UserLoginController.java )135行处有所修改。 /** * shiro 获取登录之前的地址 * 之前0.1版本这个没判断空。 */ SavedRequest savedRequest = WebUtils.getSavedRequest(request); String url = null ; if(null != savedRequest){ url = savedRequest.getRequestUrl(); } /** * 我们平常用的获取上一个请求的方式,在Session不一致的情况下是获取不到的 * String url = (String) request.getAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE); */ 三、删除了配置文件中的cookie写入域的问题。 在配置文件里(spring-shiro.xml )中的配置有所修改。 <!-- 会话Cookie模板 --> <!--cookie的name,我故意取名叫xxxxbaidu --> <!--cookie的有效时间 --> <!-- 配置存储Session Cookie的domain为 一级域名 --> 上面配置是去掉了 Session 的存储Key 的作用域,之前设置的.itboy.net ,是写到当前域名的 一级域名 下,这样就可以做到N 个 二级域名 下,三级、四级....下 Session 都是共享的。 <!-- 用户信息记住我功能的相关配置 --> <!-- 配置存储rememberMe Cookie的domain为 一级域名 --> <!-- 30天时间,记住我30天 --> 记住我登录的信息配置。和上面配置是一样的道理,可以在相同 一级域名 下的所有域名都可以获取到登录的信息。 四、简单实现了单个帐号只能在一处登录。 我们在其他的系统中可以看到,单个帐号只允许一人使用,在A处登录了,B处再登录,那A处就被踢出了。如下图所示。 但是此功能不是很完美,当A处被踢出后,再重新登录,这时候B处反应有点慢,具体我还没看,因为是之前加的功能,现在凌晨了,下次我有空再瞧瞧,同学你也可以看看,解决了和我说一声,我把功能修复。 五、修复功能(BUG) 1.修复权限添加功能BUG。 之前功能有问题,每当添加一个权限的时候,默认都给角色为“管理员”的角色默认添加当前新添加的权限。这样达到管理员的权限永远是最大的。由于代码有BUG ,导致所有权限删除了。现已修复。 2.修复项目只能部署到Root目录下的问题。 问题描述:之前项目只能部署到Root 下才能正常运行,目前已经修复,可以带项目路径进行访问了,之前只能这样访问,http://localhost:8080 而不能http://localhost:8080/shiro.demo/ 访问,目前是可以了。 解决方案:在 FreeMarkerViewExtend.java 33行处 增加了BasePath ,通过BasePath 来控制请求目录,在 Freemarker 中可以自由使用,而 JSP 中是直接在 JSP 中获取BasePath 使用。 解决后遗症:因为我们的权限是通过URL 来控制的,那么增加了项目的目录,导致权限不能正确的判断,再加上我们的项目名称(目录)可以自定义,导致更不好判断。 后遗症解决方案:PermissionFilter.java 50行处 解决了这个问题,详情请看代码和注释,其实就是replace 了一下。 HttpServletRequest httpRequest = ((HttpServletRequest)request); /** * 此处是改版后,为了兼容项目不需要部署到root下,也可以正常运行,但是权限没设置目前必须到root 的URI, * 原因:如果你把这个项目叫 ShiroDemo,那么路径就是 /ShiroDemo/xxxx.shtml ,那另外一个人使用,又叫Shiro_Demo,那么就要这么控制/Shiro_Demo/xxxx.shtml * 理解了吗? * 所以这里替换了一下,使用根目录开始的URI */ String uri = httpRequest.getRequestURI();//获取URI String basePath = httpRequest.getContextPath();//获取basePath if(null != uri && uri.startsWith(basePath)){ uri = uri.replace(basePath, ""); } 3.项目启动的时候报错,关于JNDI的错误提示。 其实也不是错,但是看着不舒服,所以还得解决这个问题。解决这个问题需要在web.xml 中的开始部位加入以下代码。 spring.profiles.active dev spring.profiles.default dev spring.liveBeansView.mbeanDomain dev 4.项目Maven打包问题。 打包的时候,不同版本的 Eclipse 还有IDEA 会有打包打不进去Mapper.xml 文件,这个时候要加如下代码(群里同学提供的)。 src/main/java **/*.properties **/*.xml false 在 标签内加入即可,如果还是不能解决,那么请你加群(改名后)说明你的问题,有人会回答你。 5.Tomcat7以上在访问JSP页面的时候,提示JSTL错误。 这个错误是因为Tomcat7 中没有 JSTL 的jar包,现在已经在项目pom.xml 中增加了如下 jar 的引入管理。 javax.servlet jstl 1.2 javax.servlet jsp-api 2.0 provided 如果还是不能解决问题,请在官方群(群号:259217951)内搜索“jstl” 如图下载依赖包。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值