I'm trying to learn the Repository pattern, and I have some questions regarding my current understanding of it.
- All the examples I've been able to find of database repositories use ORMs, but for a number of reasons, I can't use an ORM in the project I am learning this for. So, when not using an ORM, where should the SQL queries go? My best guess was in the repository class itself, so that's what I did in the example below.
- How's my naming convention for the repository's methods? I stuck with the create/update/delete verbiage of SQL as a sort of placeholder, but is there a better way?
- Because I'm not using an ORM, I need a
setId()
method in my repository. I recognize the danger inherent in allowing id's to be changed after object creation. Right now I prevent that by throwing an exception insetId()
if id is not null. Is that alright or is there a better way? - Am I doing anything just completely wrong in general?
Here is my current implementation, as far as I understand the concepts.
Product.php
<?php
namespace Vendor\Package\Module\Entities;
class Product
{
/** @var int $id */
protected $id;
/** @var string $name */
protected $name;
public function getId()
{
return $this->id;
}
public function setId($id)
{
if ($this->id !== null) {
throw new Exception('id cannot be reset.');
}
$this->id = $id;
return $this;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
}
ProductRepositoryInterface.php
<?php
namespace Vendor\Package\Module\Repositories;
use PDO;
use Vendor\Package\Module\Entities\Product;
interface ProductRepositoryInterface
{
public function findAll();
public function findById($id);
public function create(Product $product);
public function update(Product $product);
public function delete(Product $product);
}
ProductRepository.php
<?php
namespace Vendor\Package\Module\Repositories;
use PDO;
use Vendor\Package\Module\Entities\Product;
class ProductRepository implements ProductRepositoryInterface
{
/** @var PDO $db */
protected $db;
public function __construct(PDO $db)
{
$this->db = $db;
}
/**
* @return array
*/
public function findAll()
{
$stmt = $this->db->query(
'SELECT
id,
name
FROM products
WHERE active = 1'
);
$products = [];
while ($stmt->fetch(PDO::FETCH_ASSOC)) {
$product = new Product();
$product
->setId($result['id'])
->setName($result['name'])
;
}
return $products;
}
/**
* @param int $id
*
* @return Product
*/
public function findById($id)
{
$stmt = $this->db->prepare(
'SELECT
id,
name
FROM products
WHERE id = :id
AND active = 1
LIMIT 1'
);
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$product = new Product();
$product
->setId($result['id'])
->setName($result['name'])
;
}
/**
* @param Product $product
*
* @return int
*/
public function create(Product $product)
{
$stmt = $this->db->prepare(
'INSERT INTO products (
name
) VALUES (
:name
)'
);
$stmt->bindValue(':name', $product->getName(), PDO::PARAM_STR);
$stmt->execute();
$id = $this->db->lastInsertId();
$product->setId($id);
return $id;
}
/**
* @param Product $product
*
* @return bool
*/
public function update(Product $product)
{
$stmt = $this->db->prepare(
'UPDATE products SET
name = :name
WHERE id = :id
AND active = 1'
);
$stmt->bindValue(':name', $product->getName(), PDO::PARAM_STR);
$stmt->bindValue(':id', $product->getId(), PDO::PARAM_INT);
return $stmt->execute();
}
/**
* @param Product $product
*
* @return bool
*/
public function delete(Product $product)
{
$stmt = $this->db->prepare(
'UPDATE products SET
active = 0
WHERE id = :id
AND active = 1'
);
$stmt->bindValue(':id', $product->getId(), PDO::PARAM_INT);
return $stmt->execute();
}
}
demo.php
<?php
use Vendor\Package\Module\Entities\Product;
use Vendor\Package\Module\Repositories\ProductRepository;
$repository = new ProductRepository($db);
// Create
if (
isset($_POST['create'])
&& isset($_POST['name'])
) {
$product = new Product();
$product
->setName($_POST['name'])
;
$repository->create($product);
}
// Update
if (
isset($_POST['update'])
&& isset($_POST['id'])
&& isset($_POST['name'])
) {
$product = new Product();
$product
->setId($_POST['id'])
->setName($_POST['name'])
;
$repository->update($product);
}
// Delete
if (
isset($_POST['delete'])
&& isset($_POST['id'])
) {
$product = new Product();
$product
->setId($_POST['id'])
;
$repository->delete($product);
}
Aucun commentaire:
Enregistrer un commentaire