欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

CodeIgniter Doctrine2基本使用(一)(转)

程序员文章站 2022-05-11 17:33:06
CodeIgniter Doctrine2基本使用(一) 之前写了一篇文章叫作《CodeIgniter 3.0整合Doctrine2》里面介绍了一些简单的Doctrine2的用法,当然我也已经把它运用到项目上去了。下面我就写一些Doctrine2在CodeIgniter框架上的一些使用及感受吧... ......

CodeIgniter Doctrine2基本使用(一)

之前写了一篇文章叫作《CodeIgniter 3.0整合Doctrine2》里面介绍了一些简单的Doctrine2的用法,当然我也已经把它运用到项目上去了。下面我就写一些Doctrine2在CodeIgniter框架上的一些使用及感受吧...

在项目上运用了一段时间后发现,好像代码比格变高了呃,连同事都说你这种写法好像很高级的样纸呃,并且代码特别好看。(嘿嘿,心里偷着乐)虽然现在运用的广度还不是很大,但逐渐的我会把它给运动到所有模块上去,现新功能或新模块都使用了Doctrine ORM结构。新的结构确实可以少写很多代码,虽然运行的效率并不怎么高,不过总会有办法解决的。下面我将对一些我用过或现在正在用的一些东西进行一些简单的讲街,本人文采烂,能力有限看不明白也请谅解谅解...

Doctrine2 简单的用法

创建一个实体 Entity

比如我们现在需要一个渠道channel的数据表,表里面有很多字段那我在 model/Entity 目录创建一个 Channel.php 的文件

// Channel.php 部分代码
namespace Entity;
use Entity\Repository\ChannelRepository;
/**
 * Channel
 *
 * @Table(name="channel", options={"collate"="utf8_general_ci","charset"="utf8"}, uniqueConstraints={@UniqueConstraint(name="channel_code", columns={"channel_code"})})
 * @Entity(repositoryClass="Entity\Repository\ChannelRepository")
 */
 class Channel {
 
 	/**
     * @var integer
     *
     * @Column(name="channel_id", type="integer", nullable=false, options={"comment": "渠道id"})
     * @Id
     * @GeneratedValue(strategy="NONE")
     */
    private $channelId;

    /**
     * @var integer
     *
     * @Column(name="channel_tag", type="integer", nullable=false, options={"comment": "渠道标识"})
     * @Id
     * @GeneratedValue(strategy="NONE")
     */
    private $channelTag;

    /**
     * @var string
     *
     * @Column(name="channel_name", type="string", length=128, nullable=false, options={"comment": "渠道名称"})
     */
    private $channelName;
    
    /**
     * @var string
     *
     * @Column(name="channel_time", type="datetime", nullable=false, options={"comment": "渠道创建时间"})
     */
    private $channelTime;
    
    public function __construct()
    {
    	$this->channelTime = new \DateTime('now');
    }

 }

OK 先写三个字段吧,然后我们进入 ./app目录执行 php doctrine 命令会显示一些doctrine可以使用的一些命令,然后我们现在要创建每个字段的 getter 和 setter 方法,所以我们执行命令

php doctrine orm:generate:entities ./models/ --update-entities="true" --generate-methods="true"

当然可以执行 php doctrine orm:generate:entities --help 查看 orm:generate:entities 的用法; --update-entities="true" 表示需要更新实体 --generate-methods="true" 表示更新或生成每个成员属性的 getter 和 setter 方法(我猜的,因为之前不生成方法时我找了好长时间才知道是怎么回事),对了这里还写了一个构造函数,缺省设置了一个时间,当 new Channnel()的时候就不再需要set这个时间字断了

生成功能后Channel这个实体应该会多出7个方法:

	/**
     * Get channelId
     *
     * @return integer
     */
    public function getChannelId()
    {
        return $this->channelId;
    }

    /**
     * Set channelTag
     *
     * @param integer $channelTag
     *
     * @return Channel
     */
    public function setChannelTag($channelTag)
    {
        $this->channelTag = $channelTag;

        return $this;
    }

    /**
     * Get channelTag
     *
     * @return integer
     */
    public function getChannelTag()
    {
        return $this->channelTag;
    }

    /**
     * Set channelName
     *
     * @param string $channelName
     *
     * @return Channel
     */
    public function setChannelName($channelName)
    {
        $this->channelName = $channelName;

        return $this;
    }

    /**
     * Get channelName
     *
     * @return string
     */
    public function getChannelName()
    {
        return $this->channelName;
    }
	
	/**
     * Set channelTime
     *
     * @param \DateTime $channelTime
     *
     * @return Detail
     */
    public function setCreateTime($channelTime)
    {
        $this->channelTime = $channelTime;

        return $this;
    }

    /**
     * Get channelTime
     *
     * @return \DateTime
     */
    public function getChannelTime()
    {
        return $this->channelTime;
    }

getter 是获取这个字段的值,setter 是设置该字段的值,咱们回到上面的成员属性看比如:

	/**
     * @var string
     *
     * @Column(name="channel_name", type="string", length=128, nullable=false, options={"comment": "渠道名称"})
     */
    private $channelName;

注释里有 @var string 这个表示它返回的会是什么,这不重要,重要的看下面这个 @Column 这个很重要,是必须设置的;括号里边就是对这个成员属性的相关设置也就是这个字段的属性。

  • name: 表字段名(string)
  • type: 表字段类型(string,integer,datetime,text,bigint等等)
  • length: 表字段长度(整型)
  • nullable: 是否为空(true or false)
  • unique: 是否唯一(true or false)
  • precision: (暂时不知道是干啥的只设置过0)
  • scale: (与上个字段一样为0吧)
  • options: 这里可以设置很多东西,我好像只设置过 commint 跟 default 这两个参数

OK明白上面的东西后我们就生成SQL语句吧执行命令 php doctrine orm:schema-tool:create --dump-sql 生成建表语句,如果想直接创建表的话把后面的参数 --dump-sql去掉就行了; php doctrine orm:schema-tool:update --dump-sql 这条命令与上面生成SQL语句的命令一样这是打印出有更新的字段如果不想打印把后面的参数 --dump-sql去掉就直接更新数据库表了;

这样我们表就建好了;

Repository

在最上面的Channel类的注释里有没有发现 @Entity(repositoryClass="Entity\Repository\ChannelRepository")这么一段参数; 这个就是可以自己扩展的库,也就相当于自己在CI框架里写的MODEL类,如果我们要使用它的话需要执行一条创建对它进行创建:

php doctrine orm:generate:repositories ./model

执行上面命令后会把./model下面的所有实体如果设置了@Entity的实例全部创建一个 Repository 类库;

// ./app/model/Entity/Repository/ChannelRepository.php
namespace Entity\Repository;

use Doctrine\ORM\EntityRepository;
//use Doctrine\ORM\Query\Expr\Join;

/**
 * ChannelRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class ChannelRepository extends EntityRepository
{
}

然后我们再回到 Channel 实体把刚刚创建的 ChannelRepository 库给引用进来并继承它;

use Entity\Repository\ChannelRepository;
class Channel extends ChannelRepository{}

这样的话,当我们加载一个实体后就可以实现这个实体里自己写的扩展方法了,非常 方便呢,后面我会讲;

OK创建实体基本的方法大概就是上在这些,如有不清楚的地方请大家在下面评论区留言。。。

加载实体

既然我们实体及实体库已经创建好了,那要如何使用它呢?

首先先把需要用的这个实体给加载进来,我们可以使用: $this->em->getRepository 方法,当然前提是你必须先加载Doctrine这个类库文章《CodeIgniter 3.0整合Doctrine2》好像有讲,可以去看看,不想看的话我下面再写一下

后面写的 $this->em 的由来
平时我们在CI创建一个控制器时需要继承一个父控制器一般在 ./app/core/MY_Controller.php 不要问我为什么要这样写,不明白的回去把CodeIgniter框架抄写三遍
然后我们在 MY_Controller 控制器的 __function() 方法载入 Doctrine 扩展类可以参考下面代码

// ./app/core/MY_Controller.php
class MY_Controller extends Controller {

	protected $em;
	
	function __construct()
	{
		parent::__construct();
		$this->load->library('doctrine');
        /** @var  $em Doctrine\ORM\EntityManager */
        $em = $this->doctrine->em;
        $this->em = $em;
	}
}



然后我们就可以使用 $em 这个成员了;

要如何使用呢?

比如我们创建一个控制器就叫 channel.php 好了

class Channel extends MY_Controller{
	function __construct()
	{
		parent::__construct();
	}
	
	public function index()
	{
		/** @var  $channelRepository Entity\Channel */
		$channelRepository = $this->em->getRepository('Entity\Channel');
		
		$channelRepository->findAll();
		
	}
}

为什么要加 /** @var $channelRepository Entity\Channel */这样一个注释呢?

大家可别小看这种注释,很有用的,不信的话你按住command+鼠标左键点一下试试(在大多IDE上都是支持的,Sublime Text也可以使用)

好了,加载实体基本上就算是讲完了。

操作实体

上面我们已经把实体给加载进来了,现在我们要对数据库过行相关操作;其实呢我们操作实体就相当于是在操作数据库表,每一个实体就相当于是一张表,它于表是一种映射关系。

插入一条数据

持入一条数据首先需要把这个实体实例化,也就是new 一下这个实体我们才能使用它,比如以下代码:

/** @var  $channel Entity\Channel */
$channel = new \Entity\Channel();

$channel->setChannelTag()
	->setChannelName();
	
$this->em->persist( $channel );
$this->em->flush();

OK我来简单的讲解一下上面的代码,这里我们需要吧。我们知道这张表一共有四个字段分别是

  • channelId
  • channelTag
  • channelName
  • channelTime

然后我们需要分别对这些字段设置一些值,那我们就需要用到 Entity\Channel 这个实体里刚刚生成的 setter 方法了。 那为什么我只set了两直字段呢?

  1. channel_id 是一个主键我们不需要对它进行操作,可以看到主建是没有setter方法的所以不需要设置这个字段的值,执行前它是空的如果成功拷入数据后这个字段就会是刚刚插入后返回的ID
  2. channel_time 上面已经讲到了 我们在 Entity\Channel 这个实体的构造函数里已经对它进行赋值了,所以它是有内容的,不信的话你 var_dump($channel) 这个实体看它的成员的值

设置完后我们需要调用 $this->em->persist($channel) 这人方法把设置好的 Entity\Channel 这个实体塞进去,注意:此时并没有执行SQL语句进入数据。我们需要调用一下 $this->em->flush() 这个方法执行SQL语句,如果想看它生成的是什么样的SQL的话可以进入数据库输入以下命令:

  • show variables like '%gene%';
Variable_name Value
general_log OFF
general_log_file /opt/rh/mysql55/root/var/lib/mysql/default.log

我们可以看到现在所有的数据库操作日志状态是OFF 我们需要所它设置成 ON,执行以下命令

  • set global general_log = ON;

/opt/rh/mysql55/root/var/lib/mysql/default.log这个就是操作日志,我们可以 tail -f一下它然后可以可看到以后我们地数据库的所有操作了。

查询操作

原文链接:https://lattecake.com/post/20044