IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> SpringBoot集成通用Mapper和分页插件PageHelper(三) -> 正文阅读

[大数据]SpringBoot集成通用Mapper和分页插件PageHelper(三)

??通用 Mapper 默认使用了几个简单的注解,其他 JPA 的注解默认并不支持,但是如果你开发自己的通用方法,你可以使用 JPA 注解或者引入自己的注解。

@NameStyle 注解(Mapper) 名字转换样式,注解的优先级高于全局配置,主要有以下几个值:

normal,                     //原值
camelhump,                  //驼峰转下划线
uppercase,                  //转换为大写
lowercase,                  //转换为小写
camelhumpAndUppercase,      //驼峰转下划线大写形式
camelhumpAndLowercase,      //驼峰转下划线小写形式

示例:

@NameStyle(value = Style.camelhump)
public class Role {
}

@Table 注解(JPA) 此注解指定注解实体的主表,将实体类和数据库表进行关联映射。@Table 注解可以配置 name,catalog 和 schema 三个属性,配置 name 属性后,直接使用提供的表名,不再根据实体类名进行转换。其他两个属性中,同时配置时,catalog 优先级高于 schema,也就是只有 catalog 会生效。
示例:

@Table(name = "`role`")
public class Role {
}

@Column 注解(JPA) 将实体类属性和数据库表字段进行关联映射。@Column 注解支持 name, insertable 和 updateable 三个属性。name 配置映射的列名;insertable 对提供的 insert 方法有效,如果设置 false 就不会出现在 SQL 中;updateable 对提供的 update 方法有效,设置为 false 后不会出现在 SQL 中。
示例:

public class Role {
    /**
     * 角色名
     */
    @Column(name = "`role_name`",insertable = true,updatable = false)
    private String roleName;
}

@ColumnType 注解(Mapper) 针对列的复杂属性配置,这个注解提供的 column属性和 @Column 中的 name 作用相同。但是 @Column 的优先级更高。除了 name 属性外,这个注解主要提供了 jdbcType 属性和 typeHandler 属性。jdbcType 用于设置特殊数据库类型时指定数据库中的 jdbcType。typeHandler 用于设置特殊类型处理器,常见的是枚举。
示例:

public class Role {
    /**
     * 角色名
     */
    @ColumnType(column = "`role_name`",jdbcType = JdbcType.VARCHAR,typeHandler = StringTypeHandler.class)
    private String roleName;
}

@Transient 注解(JPA) 一般情况下,实体中的字段和数据库表中的字段是一一对应的,但是也有很多情况我们会在实体中增加一些额外的属性,这种情况下,就需要使用 @Transient 注解来告诉通用 Mapper 这不是表中的字段。
示例:

public class Role {
    @Transient
    private String uid;
}

@Id 注解(JPA) @Id 注解和映射无关,它是一个特殊的标记,用于标识数据库中的主键字段。正常情况下,一个实体类中至少需要一个标记 @Id 注解的字段,存在联合主键时可以标记多个。如果表中没有主键,类中就可以不标记。

public class Role {
    /**
     * 主键ID
     */
    @Id
    @Column(name = "`id`")
    private String id;
}

@KeySql @GeneratedValue 注解 这两个注解都是主键策略注解,用于配置如何生成主键。

??除了主键策略注解,其他注解在实际开发中会多或少都会使用,接下来就详细说说主键策略注解的使用。

??首先主键策略和数据库关系很大,有些数据库支持主键自增,而有些数据库只能通过序列来获得。通用mapper新增的@KeySql 注解用于替换 @GeneratedValue 注解,因此 @KeySql 能以更简单方式实现原来的功能。

??首先看看 @KeySql 注解 ,通过源码可以看出,@KeySql 不仅支持通过JDBC的方式获取自增主键,例如用于MySQL;同时也可以通过自定义SQL的方式获取主键值,例如用于Oracle;并且也可以自定义生成主键值的方法,例如用于全局主键,在使用时请注意优先级。

/**
 * 主键策略,用于替换 JPA 中的复杂用法
 */
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface KeySql {
    /**
     * 是否使用 JDBC 方式获取主键,优先级最高,设置为 true 后,不对其他配置校验
     */
    boolean useGeneratedKeys() default false;
    /**
     * 优先级第二,根据配置的数据库类型取回主键,忽略其他配置
     */
    IdentityDialect dialect() default IdentityDialect.NULL;

    /**
     * 取主键的 SQL
     */
    String sql() default "";

    /**
     * 生成 SQL,初始化时执行,优先级低于 sql
     */
    Class<? extends GenSql> genSql() default GenSql.NULL.class;

    /**
     * 和 sql 可以配合使用,默认使用全局配置中的 ORDER
     */
    ORDER order() default ORDER.DEFAULT;

    /**
     * Java 方式生成主键,可以和发号器一类的服务配合使用
     */
    Class<? extends GenId> genId() default GenId.NULL.class;
}

??而 @GeneratedValue 就只有两个属性,在使用时需要同时使用xml映射方法实现

@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface GeneratedValue {

    /**
     * (可选)持久性提供程序生成带注释实体主键时必须使用的主键生成策略。
     */
    GenerationType strategy() default AUTO;

    /**
	 * (可选)在{@link SequenceGenerator}或{@link TableGenerator}注释中指定的要使用的主键生成器的名称
	 *  默认为持久性提供程序提供的id生成器。
     */
    String generator() default "";
}

1. 自增主键的数据库主键策略
??常见的支持自增主键的数据库如下,自增主键的值主要通过数据库自己管理,所以存值时是不需要我们过多的去干涉;而自增主键取回主键值主要是通过数据库提供的 JDBC 支持 getGeneratedKeys 方法

DB2: VALUES IDENTITY_VAL_LOCAL()
MYSQL: SELECT LAST_INSERT_ID()
SQLSERVER: SELECT SCOPE_IDENTITY()
CLOUDSCAPE: VALUES IDENTITY_VAL_LOCAL()
DERBY: VALUES IDENTITY_VAL_LOCAL()
HSQLDB: CALL IDENTITY()
SYBASE: SELECT @@IDENTITY
DB2_MF: SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1
INFORMIX: select dbinfo('sqlca.sqlerrd1') from systables where tabid=1

@KeySql 示例:

@Id
@KeySql(useGeneratedKeys = true)
private Long id;

@Id
//DEFAULT 需要配合 IDENTITY 参数(ORDER默认AFTER)
@KeySql(dialect = IdentityDialect.DEFAULT)
private Integer id;

//建议直接指定数据库
@Id
@KeySql(dialect = IdentityDialect.MYSQL)
private Integer id;

注意:SqlServer 中使用时,需要设置 id 的 insertable=false
??同时也可以通过 dialect 参数,根据配置的数据库类型取回主键,它的优先级比 useGeneratedKeys 低,参数值有以下集中

    DB2("VALUES IDENTITY_VAL_LOCAL()"),
    MYSQL("SELECT LAST_INSERT_ID()"),
    SQLSERVER("SELECT SCOPE_IDENTITY()"),
    CLOUDSCAPE("VALUES IDENTITY_VAL_LOCAL()"),
    DERBY("VALUES IDENTITY_VAL_LOCAL()"),
    HSQLDB("CALL IDENTITY()"),
    SYBASE("SELECT @@IDENTITY"),
    DB2_MF("SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1"),
    INFORMIX("select dbinfo('sqlca.sqlerrd1') from systables where tabid=1"),
    DEFAULT(""),
    NULL("");

@GeneratedValue示例:

// 实体类
@Id
@Column(name = "`id`")
@GeneratedValue(strategy = GenerationType.IDENTITY,generator = "JDBC")
private String id;

// xml映射方法实现
<insert id="insert">
	// 获取主键值得方法,因为是自增主键,所以order的值为 "AFTER" 代表插入完成后返回
    <selectKey keyProperty="id" resultType="int" order="AFTER">
      SELECT LAST_INSERT_ID()
    </selectKey>
    insert into country (id, countryname, countrycode)
    values (#{id},#{countryname},#{countrycode})
</insert>

2. 序列和任意 SQL 的数据库主键策略
??像 Oracle 中通过序列获取主键就属于这种情况,实际上 2.3.2 中的 SQL 也可以在这里配置。除了类似序列获取值外,还可以是获取 UUID 的 SQL 语句,例如 select uuid()。
@KeySql示例:

@Id
@KeySql(sql = "select SEQ_ID.nextval from dual", order = ORDER.BEFORE)
private Integer id;

@GeneratedValue示例:

// 实体类
@Id
@Column(name = "`id`")
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "select uuid()")
private String id;

// xml映射方法实现
<insert id="insert">
	// 获取主键值得方法,order的值为 "BEFORE" 代表插入前先获取主键的值
    <selectKey keyProperty="id" resultType="String" order="BEFORE">
        select uuid()
    </selectKey>
    insert into dept (id, dept_name)
    values (#{id},#{deptName})
</insert>

3. 全局主键
??通用 Mapper 4.0.2+ 版本增加了新的控制主键生成的策略 genId() 属性,可以自己定义主键生成策略。使用该功能需要自己去实现生成的方法,可以用于全局主键。
示例:

// 实现GenId类,本文提供几个方案参考
/**
 * 时间戳
 */
public class TimeStampSql implements GenId {
    private Long time;
    private Integer seq;

    @Override
    public synchronized Object genId(String table, String column) {
        long current = System.currentTimeMillis();
        if (time == null || time != current) {
            time = current;
            seq = 1;
        } else if (current == time) {
            seq++;
        }
        return ((time << 20) | seq) + "";
    }
}

/**
 * 使用uuid
 */
public class UUIDSql implements GenId {
    @Override
    public Object genId(String table, String column) {
        return UUID.randomUUID().toString().replace("-", "");
    }
}

// 实体类主键注解
@Id
@Column(name = "`id`")
@KeySql(genId = UUIDSql.class)
private String id;

源码地址:https://gitee.com/peachtec/hxz-study

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-03-17 22:14:33  更:2022-03-17 22:15:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:04:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码