目錄
訪問數據庫用到的組件是doctrine,這個堪比java界的hibernate,裏面的很過概念都有相同之處,在下面的文章描述裏面,有對這兩者結合起來進行對比。
1, 添加數據庫訪問配置參數
在項目的根目錄下,不是config目錄,打開裏面的 .env文件,裏面配置好訪問數據庫的參數。
# customize this line!
DATABASE_URL="mysql://db_user:[email protected]:3306/db_name"
# to use sqlite:
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db"
2,創建數據庫
可以手工在數據庫客戶端命令行裏面創建,也可以使用doctrine創建。
如果需爲創建的數據庫添加參數的話,建議使用命令行創建,比如:定義頁面大小,數據存放位置等等。
php bin/console doctrine:database:create
3,創建實體類
可以手工在開發環境裏面創建,也可以使用symfony自帶的命令進行創建。
php bin/console make:entity
在這新建的實體類爲Product:
// src/Entity/Product.php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
*/
class Product
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\Column(type="integer")
*/
private $price;
public function getId()
{
return $this->id;
}
// ... getter and setter 方法省略掉
}
每個實體類必須有一個id,用註解 @ORM\Id ,
實體類的每個屬性都有註解ORM\Column)進行標註,證明它是一個表的列。
@ORM\Column(type="string", length=255)
這個註解是標註這個列的數據類型是string,最大長度是255,對應的數據庫的類型不見得是string,這個看各個數據庫廠商的規範,一般都是varchar。
跟數據庫的實際類型的對應表,可以看doctrine文檔。
https://www.doctrine-project.org/projects/doctrine-dbal/en/2.10/reference/types.html#types
@ORM\Column(type="integer")
這個註解是標註這個列的數據類型是integer,對應的數據庫的類型可以從doctrine的官方文檔裏面看到。
4,實體映射數據庫表
Product這個實體類信息跟數據庫中的表數據是對應的,這個工作是由orm框架doctrine來完成的。
5,命令行執行sql
php bin/console doctrine:query:sql 'SELECT * FROM product'
這個是在命令行裏面,執行sql。
6,控制器中訪問數據層
1,直接訪問
$product = $this->getDoctrine()
->getRepository(Product::class)
->find($id);
上面這行代碼,就是直接使用doctrine對象,訪問數據層。
2,使用Repository訪問
Repository相當於java裏面的Dao,數據訪問層。
// src/Controller/ProductController.php
// ...
use App\Repository\ProductRepository;
/**
* @Route("/product/{id}", name="product_show")
*/
public function show($id, ProductRepository $productRepository)
{
$product = $productRepository
->find($id);
// ...
}
上面代碼就是創建了ProductRepository這個類,這也是我們在項目中常用的方法,這個類的對象注入容器中,在控制器中就能很方便獲取到。、
也可以使用上面第一種,利用doctrine對象獲取。
$repository = $this->getDoctrine()->getRepository(Product::class);
7,持久化數據
使用doctrine對象管理者持久化數據:
包括對增加,刪除,修改。
$entityManager->flush();
對象是有狀態的,這個類似hibernate裏面的對象狀態:transient(瞬時狀態),persistent(持久化狀態)以及detached(遊離狀態)。
在doctrine裏面,沒有文檔明確這樣對狀態定義,實際上是一回事。如果讀過hibernate源碼的時候,能明白,這種被hibernate管理的對象並不是一個原生的對象,是一個利用字節碼生成的對象,這種對象裏面才能持有數據訪問會話。
初學的時候,對 cascade ,inverse 這兩個關鍵字都感覺很難理解,學個orm框架使用,還被強制要求理解這麼多概念,這就加大了學習的曲線。
在doctrine裏面,也是有着cascade ,inverse ,跟hibernate是一回事。
具體的怎麼理解,後面文章再解釋,doctrine是一個獨立的框架,不是幾句話就能說明白,我們這裏只是關心,怎樣和symfony緊密結合調用。
8,查詢
doctrine提供了一個查詢接口,看下這個代碼:
$qb = $this->createQueryBuilder('p')
->where('p.price > :price')
->setParameter('price', $price)
->orderBy('p.price', 'ASC');
創建了一個查詢構造器,裏面傳遞了where參數,查詢參數,排序方式。
doctrine底層會把這種東西翻譯成數據庫的查詢sql。
同時也支持使用原生sql ,代碼如下:
$conn = $this->getEntityManager()->getConnection();
$sql = '
SELECT * FROM product p
WHERE p.price > :price
ORDER BY p.price ASC
';
$stmt = $conn->prepare($sql);
$stmt->execute(['price' => $price]);
// returns an array of arrays (i.e. a raw data set)
return $stmt->fetchAll();
注: 老班長開始更新錄製的symfony視頻教程,可以關注公衆號查看。
文章持續更新,可以微信搜索公衆號「 程序員老班長 」查看更多文章。