Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
J

jet

> 数据库
Open source

Type safe SQL builder with code generation and automatic query result data mapping

3.8K stars0 likes0 views
WebsiteGitHub

About

Type safe SQL builder with code generation and automatic query result data mapping

Jet

Jet is a complete solution for efficient and high performance database access, combining a type-safe SQL builder with code generation and automatic query result mapping.

Jet currently supports the following database engines:

  • PostgreSQL
  • MySQL
  • SQLite

This list is not exclusive, as many other databases implement compatible wire protocols. For example, CockroachDB uses the PostgreSQL wire protocol, and MariaDB is based on the MySQL protocol. Both databases are tested and known to work with Jet.

Support for additional databases may be introduced in future releases.

Jet is the easiest, and the fastest way to write complex type-safe SQL queries as a Go code and map database query result into complex object composition.

[!Note] Jet is not an ORM.

Contents

  • Motivation
  • Features
  • Getting Started
    • Prerequisites
    • Installation
    • Quick Start
      • Generate sql builder and model types
      • Lets write some SQL queries in Go
      • Execute query and store result
  • Benefits
  • Dependencies
  • Versioning
  • License
  • Support the Project

Motivation

https://medium.com/@go.jet/jet-5f3667efa0cc

Features

  1. Auto-generated type-safe SQL Builder. Statements supported:

    • SELECT, SELECT_JSON (DISTINCT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, OFFSET, FOR, LOCK_IN_SHARE_MODE, UNION, INTERSECT, EXCEPT, WINDOW, sub-queries)
    • INSERT (VALUES, MODEL, MODELS, QUERY, ON_CONFLICT/ON_DUPLICATE_KEY_UPDATE, RETURNING),
    • UPDATE (SET, MODEL, WHERE, RETURNING),
    • DELETE (WHERE, ORDER_BY, LIMIT, RETURNING),
    • LOCK (IN, NOWAIT), (READ, WRITE)
    • WITH
  2. Auto-generated Data Model types - Go types mapped to database type (table, view or enum), used to store result of database queries. Can be combined to create complex query result destination.

  3. Query execution with result mapping to arbitrary destination.

Getting Started

Prerequisites

To install Jet package, you need to install Go and set your Go workspace first.

Go version 1.24+ is required

Installation

Use the command bellow to add jet as a dependency into go.mod project:

$ go get -u github.com/go-jet/jet/v2

Jet generator can be installed using one of the following methods:

  • ✅ Option 1: Install via go install:
go install github.com/go-jet/jet/v2/cmd/jet@latest

[!Tip] Jet generator is installed to the directory named by the GOBIN environment variable, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH environment variable is not set.

  • ✅ Option 2: Build manually from source and install jet generator to specific folder:
git clone https://github.com/go-jet/jet.git
cd jet && go build -o <target_directory> ./cmd/jet

[!Tip] Make sure target_directory is included in your system’s PATH environment variable to allow global access to the jet command.

Quick Start

For this quick start example we will use PostgreSQL sample 'dvd rental' database. Full database dump can be found in ./tests/testdata/init/postgres/dvds.sql. A schema diagram illustrating the relevant part of the database is available here.

Generate SQL Builder and Model types

To generate jet SQL Builder and Data Model types from running postgres database, we need to call jet generator with postgres connection parameters and destination folder path. Assuming we are running local postgres database, with user user, user password pass, database jetdb and schema dvds we will use this command:

jet -dsn=postgresql://user:pass@localhost:5432/jetdb?sslmode=disable -schema=dvds -path=./.gen
Connecting to postgres database: postgresql://user:pass@localhost:5432/jetdb?sslmode=disable 
Retrieving schema information...
  FOUND 15 table(s), 7 view(s), 1 enum(s)
Cleaning up destination directory...
Generating table sql builder files...
Generating view sql builder files...
Generating enum sql builder files...
Generating table model files...
Generating view model files...
Generating enum model files...
Done

Procedure is similar for MySQL, CockroachDB, MariaDB and SQLite. For example:

jet -source=mysql -dsn="user:pass@tcp(localhost:3306)/dbname" -path=./.gen
jet -dsn=postgres://user:pass@localhost:26257/jetdb?sslmode=disable -schema=dvds -path=./.gen  #cockroachdb
jet -dsn="mariadb://user:pass@tcp(localhost:3306)/dvds" -path=./.gen              # source flag can be omitted if data source appears in dsn
jet -source=sqlite -dsn="/path/to/sqlite/database/file" -schema=dvds -path=./.gen
jet -dsn="file:///path/to/sqlite/database/file" -schema=dvds -path=./.gen         # sqlite database assumed for 'file' data sources

*User has to have a permission to read information schema tables.

As indicated by the command output, Jet will perform the following actions:

  • ✅ Connect to the PostgreSQL database and retrieve metadata for all tables, views, and enums within the dvds schema.
  • ⚠️ Delete all contents in the target schema folder: ./.gen/jetdb/dvds.
  • ⚙️ Generate SQL Builder and Data Model types for each table, view, and enum found in the schema.

Generated files folder structure will look like this:

…

Types from the table, view, and enum packages are used to write type-safe SQL queries in Go, while types from the model types are combined to store results of the SQL queries.

[!Note] It is possible to customize the default Jet generator behavior. All the aspects of generated SQLBuilder and model types are customizable(see wiki).

Let's write some SQL queries in Go

First we need to import postgres SQLBuilder and generated packages from the previous step:

import (
  // dot import so go code would resemble as much as native SQL
  // dot import is not mandatory
  . "github.com/go-jet/jet/v2/examples/quick-start/.gen/jetdb/dvds/table"
  . "github.com/go-jet/jet/v2/postgres"

  "github.com/go-jet/jet/v2/examples/quick-start/.gen/jetdb/dvds/enum"
  "github.com/go-jet/jet/v2/examples/quick-start/.gen/jetdb/dvds/model"  
)

Let's say we want to retrieve the list of all actors who acted in films longer than 180 minutes, film language is 'English', film category is not 'Action' and film rating is not 'R'.

…

[!Tip] Package(dot) import is used, so the statements look as close as possible to the native SQL.

Note that every column has a type. String columns, such as Language.Name and Category.Name can only be compared with string columns and expressions. Similarly, Actor.ActorID, FilmActor.ActorID, Film.Length are integer columns and can only be compared with integer columns and expressions. The same type safety rules apply to arrays and their element types.

How to Get a Parametrized SQL Query from the Statement?

query, args := stmt.Sql()

query - parametrized query
args - query arguments

Click to see `query` and `args`
…
[English Action 180 Trailers]

How to Get Debug SQL from Statement?

debugSql := stmt.DebugSql()

debugSql - this query string can be copy-pasted into sql editor and executed.

[!Warning] Debug SQL is not intended to be used in production. For debug purposes only!!!

Click to see debug sql
…

Execute Query and Store Result

Well-formed SQL is just a first half of the job. Let's see how can we make some sense of result set returned executing above statement. Usually this is the most complex and tedious work, but with Jet it is the easiest.

First, we need to define the structure in which to store the query result. This can be achieved by combining autogenerated model types, or by using custom model types(see wiki for more information).

Let's say this is our desired structure made of autogenerated types:

var dest []struct {
    model.Actor
    
    Films []struct {
        model.Film
        
        Language    model.Language
        Categories  []model.Category
    }
}

The Films field is a slice because an actor can appear in multiple films, and each film is associated with a single language. The Language field, on the other hand, is a single model struct. A Film can belong to multiple categories.

[!Note] There is no limitation of how big or nested destination can be.

Now, let's execute the above statement on an open database connection (or transaction) db and store the result in the dest variable.

err := stmt.Query(db, &dest)
handleError(err)

And that's it.

The dest variable now contains a list of all actors (each with a list of films they acted in). Each film includes information about its language and a list of categories it belongs to. This list is filtered to include only films longer than 180 minutes, where the film language is 'English', the film category is not 'Action' and 'Trailers' are one of the film's special features.

[!Tip]
It is recommended to enable Strict Scan on application startup, especially when destination contains custom model types. For more details, see the wiki.

Lets print dest as a JSON to see:

jsonText, _ := json.MarshalIndent(dest, "", "\t")
fmt.Println(string(jsonText))
…

What if, we also want to have a list of films per category and actors per category, with the same search conditions.
In that case we can reuse above statement stmt, and just change our destination:

var dest2 []struct {
    model.Category

    Films []model.Film
    Actors []model.Actor
}

err = stmt.Query(db, &dest2)
handleError(err)
Click to see `dest2` json
…

Complete code example can be found at ./examples/quick-start/quick-start.go

This example represent probably the most common use case. Detail info about additional statements, features and use cases can be found at project Wiki page.

Benefits

What are the benefits of writing SQL in Go using Jet?
The biggest benefit is speed. Speed is being improved in 3 major areas:

Speed of Development

Writing SQL queries becomes faster and more efficient, as developers benefit from SQL code completion and type safety directly within Go code. Automatic scanning to arbitrary structures eliminates much of the headache and boilerplate required to structure database query results, reducing both complexity and development time.

Speed of Execution

While ORM libraries can introduce significant performance penalties when multiple tables are involved, due to multiple round-trips to the database (i.e., the N+1 query problem), Jet will always perform better. Developers can write queries of any complexity and retrieve results with a single database call. As a result, handler time lost to latency between the server and database remains constant. Handler execution ti

GitHub Issues· 45 open

View all on GitHub
  • #620

    Support stdlib UUIDs

    missing featureUpdated Sep 11, 2026
  • #381

    Please add a PGX adapter

    missing featureUpdated Sep 3, 2026
  • #609

    MySQL: stringQuote doesn't escape backslashes — FixedLiteral values can break out of string literals (injection)

    Updated Aug 30, 2026
  • #220

    Generate table indexes

    missing featureUpdated Jun 7, 2026
  • #537

    Postgres: Returning Old & New Values

    missing featureUpdated May 29, 2026

Highlights

  • •PostgreSQL
  • •Motivation
  • •Features
  • •Getting Started
  • •Prerequisites
  • •Installation
  • •Quick Start
  • •Generate sql builder and model types
  • •Lets write some SQL queries in Go
  • •Execute query and store result

> Tags

Gocockroachdbcode-completioncode-generatorcodegenerator

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category数据库
PricingOpen source

> Related tools

P
PostgreSQL
功能强大的开源关系型数据库
R
Redis
内存数据结构存储,常用作缓存与队列
M
MySQL
广泛使用的开源关系型数据库