Symfony5 系列教程7- 访问数据库

目录

1,  添加数据库访问配置参数

2,创建数据库

3,创建实体类

4,实体映射数据库表

5,命令行执行sql

6,控制器中访问数据层

1,直接访问

2,使用Repository访问

7,持久化数据

8,查询


访问数据库用到的组件是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.phpnamespace 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视频教程,可以关注公众号查看。

文章持续更新,可以微信搜索公众号「 程序员老班长 」查看更多文章。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章