首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

具有自定义包装类型的Diesel

在使用 Diesel(一个用于 Rust 的 ORM 和查询构建器)时,有时您可能需要处理自定义类型。Diesel 提供了扩展机制,允许您定义和使用自定义类型。以下是一个示例,展示如何在 Diesel 中创建和使用自定义包装类型。

示例:自定义包装类型

假设我们有一个自定义类型 Email,它是一个包装类型,用于验证和存储电子邮件地址。

1. 定义自定义类型

首先,定义一个新的类型 Email,并实现必要的特性(traits)以便与 Diesel 一起使用。

代码语言:javascript
复制
use diesel::backend::Backend;
use diesel::deserialize::{self, FromSql};
use diesel::serialize::{self, IsNull, Output, ToSql};
use diesel::sql_types::Text;
use std::io::Write;
use std::str::FromStr;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Email(String);

impl FromStr for Email {
    type Err = &'static str;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.contains('@') {
            Ok(Email(s.to_string()))
        } else {
            Err("Invalid email format")
        }
    }
}

impl ToString for Email {
    fn to_string(&self) -> String {
        self.0.clone()
    }
}

// Implementing ToSql for Email
impl<DB: Backend> ToSql<Text, DB> for Email {
    fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> serialize::Result {
        out.write_all(self.0.as_bytes())?;
        Ok(IsNull::No)
    }
}

// Implementing FromSql for Email
impl<DB: Backend> FromSql<Text, DB> for Email {
    fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result<Self> {
        let bytes = not_none!(bytes);
        let s = std::str::from_utf8(bytes)?;
        Email::from_str(s).map_err(|_| "Invalid email format".into())
    }
}

2. 使用自定义类型与 Diesel 模型

接下来,定义一个 Diesel 模型,并使用自定义类型 Email

代码语言:javascript
复制
use diesel::prelude::*;
use diesel::sql_types::Text;

table! {
    users (id) {
        id -> Integer,
        email -> Text,
    }
}

#[derive(Queryable, Insertable)]
#[table_name = "users"]
pub struct User {
    pub id: i32,
    pub email: Email,
}

3. 运行示例

以下是一个完整的示例,展示如何使用自定义类型 Email 与 Diesel 进行数据库操作。

代码语言:javascript
复制
#[macro_use]
extern crate diesel;
extern crate dotenv;

use diesel::prelude::*;
use diesel::sqlite::SqliteConnection;
use dotenv::dotenv;
use std::env;

mod schema {
    table! {
        users (id) {
            id -> Integer,
            email -> Text,
        }
    }
}

use self::schema::users;
use self::schema::users::dsl::*;

#[derive(Debug, Queryable, Insertable)]
#[table_name = "users"]
pub struct User {
    pub id: i32,
    pub email: Email,
}

fn establish_connection() -> SqliteConnection {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    SqliteConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url))
}

fn main() {
    let connection = establish_connection();

    // Create a new user
    let new_user = User {
        id: 1,
        email: "user@example.com".parse().expect("Invalid email format"),
    };

    // Insert the new user into the database
    diesel::insert_into(users)
        .values(&new_user)
        .execute(&connection)
        .expect("Error inserting new user");

    // Query the user from the database
    let results = users
        .filter(id.eq(1))
        .load::<User>(&connection)
        .expect("Error loading user");

    for user in results {
        println!("Found user: {:?}", user);
    }
}

总结

通过上述步骤,您可以在 Diesel 中定义和使用自定义包装类型。关键步骤包括:

  1. 定义自定义类型并实现 FromStrToString
  2. 实现 ToSqlFromSql 特性,以便 Diesel 能够序列化和反序列化自定义类型。
  3. 在 Diesel 模型中使用自定义类型,并进行数据库操作。
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

为自定义属性包装类型添加类 @Published 的能力

,但适用于 NSUbiquitousKeyValueStore ),来展示如何为其他的自定义属性包装类型添加可访问包裹其的类实例的属性或方法的能力。...本文中为其他属性包装类型添加的类似 @Published 的能力是指 —— 无需显式设置,属性包装类型便可访问包裹其的类实例的属性或方法。...propertyWrapper 来自定义属性包装类型。...与 掌握 Result builders[6] 一文中介绍的 @resultBuilder 类似,编译器在最终编译前,首先会对用户自定义的属性包装类型代码进行转译。...@PublishedObject —— @Published 的引用类型版本 @Published 只能胜任包装值为值类型的场景,当 wrappedValue 为引用类型时,仅改变包装值的属性内容并不会对外发布通知

3.4K20
  • 02 java包装类型的缓存机制

    02 java包装类型的缓存机制 Java 基本数据类型的包装类型的大部分都用到了缓存机制来提升性能。...Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character 创建了数值在 [0,127] 范围的缓存数据,Boolean...Integer源码 可以看到 当我们需要转换的值在 -128>=x的引用 不信看看下面的测试 测试 可以看到 俩个对象在jvm中的内存地址是一样的 从来说明 使用的是缓存数据...如果超出对应范围仍然会去创建新的对象,缓存的范围区间的大小只是在性能和资源之间的权衡。 两种浮点数类型的包装类 Float,Double 并没有实现缓存机制。 下面我们来看一下问题。...记住:所有整型包装类对象之间值的比较,全部使用 equals 方法比较什么是装箱拆箱

    25210

    01 java基本类型和包装类型的区别?

    基本类型和包装类型的区别?...1 包装类型可以为 null,而基本类型不可以 数据库的查询结果可能是 null,如果使用基本类型的话,因为要自动拆箱(将包装类型转为基本类型,比如说把 Integer 对象转换成 int 值),就会抛出...3 虚拟机中存放位置的不同 基本数据类型的局部变量存放在 Java 虚拟机栈中的局部变量表中 基本数据类型的成员变量(未被 static 修饰 )存放在 Java 虚拟机的堆中 包装类型属于对象类型,我们知道几乎所有对象实例都存在于堆中...⚠️注意 : 基本数据类型存放在栈中是一个常见的误区! 基本数据类型的成员变量如果没有被 static 修饰的话(不建议这么使用,应该要使用基本数据类型对应的包装类型),就存放在堆中。...会产生异常 class BasicTypeVar{ private int x; } 4 基本类型比包装类型更高效 包装类属于对象类型占用空间大, 基本数据类型占用的空间非常小。

    19710

    包装类型与基本数据类型的异同

    包装类型与基本数据类型的异同 一、基本数据类型: Java 语言提供了八种基本类型:六种数字类型(四个整数型,两个浮点型), 一种字符类型,还有一种布尔型。...三、基本类型与包装类型的异同 1、在 Java 中,一切皆对象,但八大基本类型却不是对象。 2、声明方式的不同,基本类型无需通过 new 关键字来创建,而包装类型需 new 关键字。...3、存储方式及位置的不同,基本类型是直接存储变量的值保存在栈中能高 效的存取,包装类型需要通过引用指向实例,具体的实例保存在堆中。...4、初始值的不同,包装类型的初始值为 null,基本类型的的初始值视具体的类型而定,比如 int 类型的初始值为 0,boolean 类型为 false。...5、使用方式的不同,比如与集合类合作使用时只能使用包装类型。

    57430

    基本数据类型的包装类

    基本数据类型的包装类 包装类基本知识 JAVA 并不是纯面向对象的语言。Java 语言是一个面向对象的语言,但是 Java 中的基本数据类型却是不面向对象的。...包装类均位于 java.lang 包,包装类和基本数据类型的对应关系如下表所示: 基本数据类型 包装类 byte Byte boolean Boolean short Short char Character...包装类的用途 对于包装类说,这些类的用途主要包含两种: 1、作为和基本数据类型对应的类类型存在,方便涉及到对象的操作。...2、包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法(这些操作方法的作用是在基本类型数据、包装类对象、字符串之间提供转化!)。...自动装箱的过程:每当需要一种类型的对象时,这种基本类型就自动地封装到与它相同类型的包装中。

    77420

    Java基本数据类型的包装类

    数据类型包装类 Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表...,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class),有些地方也翻译为外覆类或数据类型类。...包装类均位于java.lang包,包装类和基本数据类型的对应关系如下表所示: ?...包装类的用途 对于包装类说,这些类的用途主要包含两种: a、作为和基本数据类型对应的类类型存在,方便涉及到对象的操作。...则字符串s的值是”1000”。 自动拆箱和装箱 自动装箱的过程:每当需要一种类型的对象时,这种基本类型就自动地封装到与它相同类型的包装中。

    80430

    面试官:兄弟,说说基本类型和包装类型的区别吧

    他当时扔了一个面试题把我砸懵了:说说基本类型和包装类型的区别吧。...Java 的每个基本类型都对应了一个包装类型,比如说 int 的包装类型为 Integer,double 的包装类型为 Double。基本类型和包装类型的区别主要有以下 4 点。...03、基本类型比包装类型更高效 基本类型在栈中直接存储的具体数值,而包装类型则存储的是堆中的引用。 ? 很显然,相比较于基本类型而言,包装类型需要占用更多的内存空间。...03、两个包装类型的值可以相同,但却不相等 两个包装类型的值可以相同,但却不相等——这句话怎么理解呢?来看一段代码就明明白白了。...把基本类型转换成包装类型的过程叫做装箱(boxing)。反之,把包装类型转换成基本类型的过程叫做拆箱(unboxing)。

    56651

    定制自己的数据类型(二次加工标准类型(包装))

    ---恢复内容开始--- 包装:python为大家提供了标准数据类型,以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增/改写方法,这就用到了我们刚学的继承/派生知识...(其他的标准类型均可以通过下面的方式进行二次加工) 定制了子类List的append,多了类型检查功能 class List(list):#继承list所有的属性,也可以派生出自己新的,比如append...index=len(self)//2 return self[index] l=List([1,2,3,4]) print(l) l.append(5) print(l) 授权:授权是包装的一个特性..., 包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原有产品的功能。...实现授权的关键点就是覆盖__getattr__方法 # 授权:授权是包装的一个特性,包装一个类型通常是对已经存在的类型的一些定制,这种做法可以新建, # 修改或删除原有产品的功能。其他的则保持原样。

    43810

    JVM - 基本类型的包装类和对象池

    接下来我们也顺便看下基本类型的包装类和起对应的对象池 JDK1.8 ---- 八大基本类型 Java基本类型共有八种,基本类型可以分为三类, 字符类型char 布尔类型boolean 数值类型byte、...java中基本类型的包装类的大部分都实现了常量池技术(严格来说应该叫对象池,在堆上),这些类是Byte,Short,Integer,Long,Character,Boolean,另外两种浮点数类型的包装类...另外Byte,Short,Integer,Long,Character这5种整型的包装类也只是在对应值小于等于127时才可使用对象池,也即对象不负责创建和管理大于127的这些类的对象。...版本 1.8 public class BasicTypePoolTest { public static void main(String[] args) { //5种整形的包装类...true; Boolean bool2 = true; System.out.println(bool1 == bool2);//输出true //浮点类型的包装类没有实现对象池技术

    49410

    面试官:兄弟,说说基本类型和包装类型的区别吧

    Java 的每个基本类型都对应了一个包装类型,比如说 int 的包装类型为 Integer,double 的包装类型为 Double。基本类型和包装类型的区别主要有以下 4 点。...基本类型比包装类型更高效 基本类型在栈中直接存储的具体数值,而包装类型则存储的是堆中的引用。 很显然,相比较于基本类型而言,包装类型需要占用更多的内存空间。...两个包装类型的值可以相同,但却不相等 两个包装类型的值可以相同,但却不相等——这句话怎么理解呢?来看一段代码就明明白白了。...换句话说就是:将“==”操作符应用于包装类型比较的时候,其结果很可能会和预期的不符。 自动装箱和自动拆箱 既然有了基本类型和包装类型,肯定有些时候要在它们之间进行转换。...把基本类型转换成包装类型的过程叫做装箱(boxing)。反之,把包装类型转换成基本类型的过程叫做拆箱(unboxing)。

    3.3K40

    【Rust 基础篇】Rust Newtype模式:类型安全的包装器

    在Rust中,Newtype模式是一种常见的编程模式,用于创建类型安全的包装器。Newtype模式通过定义新的结构体包装器来包装现有的类型,从而在不引入运行时开销的情况下提供额外的类型安全性。...Newtype模式是一种常见的编程模式,用于创建类型安全的包装器。在Rust中,Newtype模式通过定义新的结构体包装器来包装现有的类型,从而在不引入运行时开销的情况下提供额外的类型安全性。...通过将现有类型包装在Newtype结构体中,我们可以防止将不同含义的数据类型进行混用,从而减少出错的可能性。...但要注意,Newtype包装器的方法调用可能会稍微增加一点性能开销。 4.2 Newtype包装器和类型转换 Newtype包装器在编译时提供了更强的类型安全性,但也意味着需要进行一些类型转换操作。...在使用Newtype包装器时,需要注意类型转换的情况。 结论 Rust的Newtype模式允许通过定义新的结构体包装器来包装现有类型,增强类型安全性并增加语义表达力。

    40140

    对基本类型包装类常量池的补充

    在前文JAVA-常量及常量池中,对java中的各种常量池进行分析。在具体的细节中,并不完善。现在对数据类型包装类常量池进行相应的补充。有很多细节也是面试中容易遗漏的地方。...意思是说,IntegerCache对-128-127之间的数据自动装箱支持。在IntegerCache第一次使用的时候通过static的构造方法进行初始化。...for(int i = 0; i < cache.length; i++) cache[i] = new Long(i - 128); } } 作为Long包装类的内部类...总结 对于java中的8种基本的数据类型,存在Cache的情况如下: 原始类型 缓存类型 范围 是否可调整 int IntegerCache -128-127 通过-XX:AutoBoxCacheMax...在系统中的数字在一个较小的范围内变化的时候,可以通过缓存的方式,提前创建好。

    49410

    面试官:兄弟,说说基本类型和包装类型的区别吧

    Java 的每个基本类型都对应了一个包装类型,比如说 int 的包装类型为 Integer,double 的包装类型为 Double。基本类型和包装类型的区别主要有以下 4 点。...基本类型比包装类型更高效 基本类型在栈中直接存储的具体数值,而包装类型则存储的是堆中的引用。 很显然,相比较于基本类型而言,包装类型需要占用更多的内存空间。...两个包装类型的值可以相同,但却不相等 两个包装类型的值可以相同,但却不相等——这句话怎么理解呢?来看一段代码就明明白白了。...换句话说就是:将“==”操作符应用于包装类型比较的时候,其结果很可能会和预期的不符。 自动装箱和自动拆箱 既然有了基本类型和包装类型,肯定有些时候要在它们之间进行转换。...把基本类型转换成包装类型的过程叫做装箱(boxing)。反之,把包装类型转换成基本类型的过程叫做拆箱(unboxing)。

    54410

    第47节:Java当中的基本类型包装类

    标题图 Java当中的基本类型包装类 01 基本数据类型对象的包装类 什么是基本数据类型对象包装类呢?就是把基本数据类型封装成对象,这样就可以提供更多的操作基本数值的功能了。...基本数据类型对象的包装类8个: 基本数据类型 包装类 byte Byte short Short int Integet long Long float Float double Double boolean...int的值包装成为对象的包装类。...基本数据类型对象的包装类,就是为了提供更多的操作方法,这里的Integer类中Java提供了多个方法,而且Integer类能够在int类型和String类型之间互相进行转换,还可以处理一些int类型有关一些常量和方法等...(String nm) 返回的是 static Integer,确定具有指定名称的系统属性的整数值 getInteger(String nm, int val) 返回的是static Integer,确定具有指定名称的系统属性的整数值

    46820

    【JAVASE】Java 包装类的秘密:解开数据类型的谜团

    包装类 在 Java 中,有一些基本数据类型,如 int、float、boolean 等。这些基本数据类型是简单的数据类型,可以直接操作和使用。...包装类是将基本数据类型包装成对象的类 1、基本数据类型和对应的包装类 基本数据类型 包装类 byte Byte short Short int Integer long Long float Float...2、包装类的用途 (1)安全性:通过使用包装类,可以避免直接使用原始数据类型,从而提高代码的安全性和可维护性。...3、包装类的用法 (1)创建包装对象: Integer integerObj = new Integer(10); (2)使用自动装箱: 装箱是指将基本数据类型转换为对应的包装类对象的过程。...对象 (3)使用自动拆箱: 拆箱是指将包装类对象转换回基本数据类型的过程。

    11510

    记住这道必考题:不是所有包装类型都有缓存的!

    上一篇文章中,我们分辨了基本类型和包装类型的区别。今天我们来聊聊包装类型的缓存机制。 笔试题 关于包装类型的缓存机制,几乎是一道必考题。...如果文末的题目你也能做对,且明白其中原因,那以下内容就可以直接跳过了;反之,请详细阅读本文。 同样都是包装类型的赋值,比较结果却不一样,这是怎么回事呢?这和自动装箱有关。...把基本类型转换成包装类型的过程叫做装箱(boxing)。 自动装箱的发生,就涉及到包装类型的缓存机制。...(我们会在下一篇文章中来说明这个知识点) 包装类型的缓存源码 Java 基本数据类型的包装类型的大部分都用到了缓存机制来提升性能。...先记住下面这四句话: Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据。

    27110
    领券