18. اپلیکیشن وب MVC در معماری سهلایه – مثال ۴، پستگرس
18.1. پایگاه داده Postgres
در این نسخه، فهرست افراد را در یک جدول پایگاه داده Postgres به نام 8.x [http://www.postgres.org] ذخیره خواهیم کرد. اسکرینشاتهای زیر از کلاینت EMS PostgreSQL Manager Lite [http://www.sqlmanager.net/fr/products/postgresql/manager]، یک کلاینت مدیریتی رایگان برای SGBD Postgres، گرفته شدهاند.
این پایگاه داده [dbpersonnes] نام دارد. این پایگاه داده شامل جدولی به نام [PERSONNES] است:

جدول [PERSONNES] شامل فهرست افرادی است که توسط وباپلیکیشن مدیریت میشوند. این جدول با استفاده از دستورات زیر SQL ایجاد شده است:
ما در مورد این جدول توضیح بیشتری نمیدهیم، زیرا مشابه جدول نوع Firebird به نام [PERSONNES] است که قبلاً در مورد آن بحث شد. با این حال، باید توجه داشت که نامهای ستون و جدول در گیومه قرار دارند. علاوه بر این، این نامها به حروف بزرگ و کوچک حساس هستند. ممکن است این رفتار Postgres 8.x قابل پیکربندی باشد. من بیشتر در این مورد تحقیق نکردهام.
جدول [PERSONNES] ممکن است محتوای زیر را داشته باشد:

علاوه بر جدول [PERSONNES]، پایگاه داده [dbpersonnes] حاوی ابجکتی به نام [SEQ_ID] است که به آن «ترتیب» (sequence) گفته میشود. این تولیدکننده اعداد صحیح متوالی را تولید میکند که از آنها برای تخصیص مقدار به کلید اصلی [ID] از کلاس [PERSONNES] استفاده خواهیم کرد. بیایید یک مثال بزنیم تا نحوه کار آن را نشان دهیم:
![]() |
![]() |
میتوانیم ببینیم که مقدار [Next value] در دنباله [SEQ_ID] تغییر کرده است (برای تازهسازی روی آن دوبار کلیک کنید + F5):
![]() |
سفارش SQL
بنابراین مقدار زیر را برای دنباله [SEQ_ID] برمیگرداند. ما از این مقدار در فایل [personnes-postgres.xml] استفاده خواهیم کرد، که سفارشهای SQL صادر شده بر روی SGBD را گردآوری میکند.
18.2. پروژهٔ Eclipse برای لایههای [dao] و [service]
برای توسعه لایههای [dao] و [service] اپلیکیشن خود با استفاده از پایگاه داده Postgres 8.x، از پروژه Eclipse زیر [spring-mvc-39] استفاده خواهیم کرد:

این پروژه یک پروژه ساده جاوا است، نه یک پروژه وب تامکت.
پوشه [src]
این پوشه حاوی کد منبع لایههای [dao] و [service] است:

هر فایلی که در نامش «[postgres]» باشد ممکن است نسبت به نسخه Firebird تغییر کرده باشد یا نکرده باشد. در ادامه، فایلهای تغییرشده را توضیح میدهیم.
پوشه [database]
این پوشه حاوی اسکریپت ایجاد پایگاه داده Postgres افراد است:
![]()
پوشه [lib]
این پوشه شامل آرشیوهای مورد نیاز برنامه است:
![]() |
توجه داشته باشید که درایور JDBC Postgres 8.x با نام SGBD نیز گنجانده شده است. تمام این آرشیوها بخشی از پروژه Eclipse با نام Classpath را تشکیل میدهند.
18.3. لایه [dao]
لایه [dao] به شرح زیر است:

ما تنها تغییرات را نسبت به نسخه [Firebird] برجسته میکنیم.
فایل نگاشت [personne-postgres.xml] به شرح زیر است:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap
PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-2.dtd">
<!-- لطفاً توجه داشته باشید – PostgreSQL 8 نیاز دارد که نام ستونها دقیقاً نوشته شوند
et des tables ainsi que des guillemets autour de ces noms -->
<sqlMap>
<!-- نام مستعار کلاس [Personne] -->
<typeAlias alias="Personne.classe"
type="istia.st.mvc.personnes.entites.Personne"/>
<!-- جدول نگاشت [PERSONNES] - شیء [Personne] -->
<resultMap id="Personne.map"
class="istia.st.mvc.personnes.entites.Personne">
<result property="id" column="ID" />
<result property="version" column="VERSION" />
<result property="nom" column="NOM"/>
<result property="prenom" column="PRENOM"/>
<result property="dateNaissance" column="DATENAISSANCE"/>
<result property="marie" column="MARIE"/>
<result property="nbEnfants" column="NBENFANTS"/>
</resultMap>
<!-- فهرست همه افراد -->
<select id="Personne.getAll" resultMap="Personne.map" > select "ID",
"VERSION", "NOM", "PRENOM", "DATENAISSANCE", "MARIE", "NBENFANTS" FROM
"PERSONNES"</select>
<!--بازیابی یک شخص خاص -->
<select id="Personne.getOne" resultMap="Personne.map" >select "ID",
"VERSION", "NOM", "PRENOM", "DATENAISSANCE", "MARIE", "NBENFANTS" FROM
"PERSONNES" WHERE "ID"=#مقدار#</select>
<!-- افزودن یک شخص -->
<insert id="Personne.insertOne" parameterClass="Personne.classe">
<selectKey keyProperty="id">
SELECT nextval('"SEQ_ID"') as value
</selectKey>
insert into "PERSONNES"("ID", "VERSION",
"NOM", "PRENOM", "DATENAISSANCE", "MARIE", "NBENFANTS") VALUES(#شناسه#,
#نسخه#, #نام خانوادگی#, #نام#, #dateNaissance#, #نام خانوادگی پس از ازدواج#, #nbEnfants#)
</insert>
<!-- بهروزرسانی یک شخص -->
<update id="Personne.updateOne" parameterClass="Personne.classe"> update
"PERSONNES" set "VERSION"=#نسخه#+1, "NOM"=#نام خانوادگی#, "PRENOM"=#نام#,
"DATENAISSANCE"=#dateNaissance#, "MARIE"=#ماري#, "NBENFANTS"=#nbEnfants#
WHERE "ID"=#id# و "VERSION"=#version#</update>
<!-- حذف یک شخص -->
<delete id="Personne.deleteOne" parameterClass="int"> delete FROM
"PERSONNES" WHERE "ID"=#value# </delete>
</sqlMap>
محتوا همانند [personnes-firebird.xml] است، با تفاوتهای جزئی زیر:
- نام ستونها و جدولها در گیومه قرار دارند و نسبت به حروف بزرگ و کوچک حساس هستند
- ترتیب SQL " Personne.insertOne " در خطوط 34–41 تغییر کرده است. روش تولید کلید اصلی با Postgres با روشی که در Firebird استفاده میشود متفاوت است:
- خط ۳۶: توالی SQL [SELECT nextval('"SEQ_ID"')] کلید اصلی را فراهم میکند. سینتکس [as value] الزامی است. [value] نمایانگر کلید حاصل است. این مقدار به فیلد شیء [Personne] که توسط ویژگی [keyProperty] (خط ۳۵) مشخص شده است، اختصاص داده میشود؛ در این مورد، فیلد [id].
- دستورهای SQL درون تگ <insert> به ترتیبی که با آنها برخورد میشود اجرا میگردند. بنابراین، SELECT قبل از INSERT اجرا میشود. در زمان عملیات درج، فیلد [id] از شیء [Personne] بنابراین توسط دستور SQL SELECT بهروزرسانی شده خواهد بود.
- خطوط ۳۸–۴۰: درج شیء [Personne]
کلاس پیادهسازی [DaoImplCommon] از لایه [dao] همان است که در نسخه [Firebird] بررسی شده است.
پیکربندی لایه [dao] برای SGBD و [Postgres] تطبیق داده شده است. در نتیجه، فایل پیکربندی [spring-config-test-dao-postgres.xml] به شرح زیر است:
<?xml version="1.0" encoding="ISO_8859-1"?>
<!DOCTYPE beans SYSTEM "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- منبع داده DBCP -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>org.postgresql.Driver</value>
</property>
<property name="url">
<value>jdbc:postgresql:dbpersonnes</value>
</property>
<property name="username">
<value>postgres</value>
</property>
<property name="password">
<value>postgres</value>
</property>
</bean>
<!-- SqlMapCllient -->
<bean id="sqlMapClient"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource">
<ref local="dataSource"/>
</property>
<property name="configLocation">
<value>classpath:sql-map-config-postgres.xml</value>
</property>
</bean>
<!-- دسترسی کلاسها برای لایه [dao] -->
<bean id="dao" class="istia.st.mvc.personnes.dao.DaoImplCommon">
<property name="sqlMapClient">
<ref local="sqlMapClient"/>
</property>
</bean>
</beans>
- خطوط ۵–۱۹: بیان [dataSource] اکنون به پایگاه داده [Postgres] [dbpersonnes] اشاره میکند که مدیر آن [postgres] با رمز عبور [postgres] است. خواننده باید این پیکربندی را برای مطابقت با محیط خود تغییر دهد.
- خط ۳۱: کلاس [DaoImplCommon] کلاس پیادهسازی برای لایه [dao] است
پس از اعمال این تغییرات، میتوانیم به مرحلهٔ تست برویم.
18.4. آزمایشها برای لایههای [dao] و [service]
تستهای لایههای [dao] و [service] مشابه نسخه [Firebird] هستند. بیایید نمونه Postgres با شناسه SGBD را اجرا کرده و سپس تستهای Eclipse را اجرا کنیم. نتایج حاصل به شرح زیر است:
![]() |
میتوانیم ببینیم که تستها با پیادهسازی [DaoImplCommon] با موفقیت پاس شدهاند. ما نیازی به مشتقسازی این کلاس نخواهیم داشت، همانطور که در مورد SGBD و [Firebird] ضروری بود.
18.5. آزمون اپلیکیشن [web]
برای تست اپلیکیشن وب با SGBD و [Postgres]، ما یک پروژه Eclipse به نام [mvc-personnes-04B] را به روشی مشابه با روشی که برای ساخت پروژه [mvc-personnes-03B] با پایگاه داده Firebird استفاده شد، ایجاد میکنیم (به بخش 17.7 مراجعه کنید). با این حال، ما نیازی به بازسازی آرشیوهای [personnes-dao.jar] و [personnes-service.jar] نداریم. این به این دلیل است که ما هیچ کلاسی را در ارتباط با پروژه [mvc-personnes-03B] تغییر ندادهایم. صرفاً آرشیو [personnes-dao.jar] حاوی کلاس [DaoImplFirebird] است که اکنون بلااستفاده شده است.

ما در حال استقرار پروژه وب [mvc-personnes-04B] در Tomcat هستیم:
![]() | ![]() |
ما اکنون برای تست آمادهایم . محتویات جدول [PERSONNES] به شرح زیر است:

تامکت در حال اجرا است. با استفاده از یک مرورگر وب، به آدرس [http://localhost:8080/mvc-personnes-04B] دسترسی پیدا میکنیم:

ما اضافه میکنیم یک فرد جدید را از طریق لینک [Ajout] اضافه میکنیم:
![]() | ![]() |
ما افزودن را در پایگاه داده بررسی میکنیم:

از خواننده دعوت میشود تا آزمایشهای بیشتری را انجام دهد: [modification, suppression].








