DEV Community

Santosh Anand
Santosh Anand

Posted on

Implementing the repository pattern in Go with both in-memory and MySQL repositories

  1. - We define the User struct representing a user entity.
  2. - We define the UserRepository interface with methods for managing users.
  3. - We implement InMemoryUserRepository and MySQLUserRepository to provide in-memory and MySQL-based repositories, respectively.
  4. - NewInMemoryUserRepository and NewMySQLUserRepository are constructor functions for creating instances of the respective repositories.
  5. - We demonstrate how to use both repositories in the main function by inserting users, getting a user by ID, and getting all users.
package main import ( "database/sql" "errors" "fmt" _ "github.com/go-sql-driver/mysql" ) // User represents a user entity type User struct { ID int Username string Email string } // UserRepository defines the methods a user repository must implement type UserRepository interface { Insert(user *User) error GetByID(id int) (*User, error) GetAll() ([]*User, error) } // InMemoryUserRepository is an in-memory implementation of UserRepository type InMemoryUserRepository struct { users []*User } // NewInMemoryUserRepository creates a new instance of InMemoryUserRepository func NewInMemoryUserRepository() *InMemoryUserRepository { return &InMemoryUserRepository{ users: make([]*User, 0), } } // Insert inserts a new user into the repository func (repo *InMemoryUserRepository) Insert(user *User) error { repo.users = append(repo.users, user) return nil } // GetByID retrieves a user by its ID from the repository func (repo *InMemoryUserRepository) GetByID(id int) (*User, error) { for _, user := range repo.users { if user.ID == id { return user, nil } } return nil, errors.New("user not found") } // GetAll retrieves all users from the repository func (repo *InMemoryUserRepository) GetAll() ([]*User, error) { return repo.users, nil } // MySQLUserRepository is a MySQL implementation of UserRepository type MySQLUserRepository struct { db *sql.DB } // NewMySQLUserRepository creates a new instance of MySQLUserRepository func NewMySQLUserRepository(dataSourceName string) (*MySQLUserRepository, error) { db, err := sql.Open("mysql", dataSourceName) if err != nil { return nil, err } return &MySQLUserRepository{ db: db, }, nil } // Insert inserts a new user into the MySQL repository func (repo *MySQLUserRepository) Insert(user *User) error { _, err := repo.db.Exec("INSERT INTO users (id, username, email) VALUES (?, ?, ?)", user.ID, user.Username, user.Email) if err != nil { return err } return nil } // GetByID retrieves a user by its ID from the MySQL repository func (repo *MySQLUserRepository) GetByID(id int) (*User, error) { row := repo.db.QueryRow("SELECT id, username, email FROM users WHERE id = ?", id) user := &User{} err := row.Scan(&user.ID, &user.Username, &user.Email) if err != nil { return nil, err } return user, nil } // GetAll retrieves all users from the MySQL repository func (repo *MySQLUserRepository) GetAll() ([]*User, error) { rows, err := repo.db.Query("SELECT id, username, email FROM users") if err != nil { return nil, err } defer rows.Close() var users []*User for rows.Next() { user := &User{} err := rows.Scan(&user.ID, &user.Username, &user.Email) if err != nil { return nil, err } users = append(users, user) } return users, nil } func main() { // Example usage of in-memory repository memRepo := NewInMemoryUserRepository() memRepo.Insert(&User{ID: 1, Username: "user1", Email: "user1@example.com"}) memRepo.Insert(&User{ID: 2, Username: "user2", Email: "user2@example.com"}) user, err := memRepo.GetByID(1) if err != nil { fmt.Println("Error:", err) } else { fmt.Println("In-Memory User:", user) } allUsers, err := memRepo.GetAll() if err != nil { fmt.Println("Error:", err) } else { fmt.Println("In-Memory All Users:", allUsers) } // Example usage of MySQL repository mysqlRepo, err := NewMySQLUserRepository("user:password@tcp(127.0.0.1:3306)/database_name") if err != nil { fmt.Println("Error:", err) return } mysqlRepo.Insert(&User{ID: 3, Username: "user3", Email: "user3@example.com"}) mysqlRepo.Insert(&User{ID: 4, Username: "user4", Email: "user4@example.com"}) user, err = mysqlRepo.GetByID(3) if err != nil { fmt.Println("Error:", err) } else { fmt.Println("MySQL User:", user) } allUsers, err = mysqlRepo.GetAll() if err != nil { fmt.Println("Error:", err) } else { fmt.Println("MySQL All Users:", allUsers) } } 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)