X
تبلیغات

سادگی و امنیت SQLبا استفاده از slick

اسلیک (Slick) روشی برای نوشتن پرس و جو های اس کیو ال به صورت رشته هایی با API مناسب برای مدیریت ارتباطات و تهیه نتایج است که با اسکالا یکپارچه شده است. در اینجا به نحوه ی کار با اسلیک خواهیم پرداخت.

اسلیک بر پایه ی بسته ی اتصال یکپارچه زبان اسکالا (Scala Language-Integrated Connection Kit) می باشد. این کتابخانه ای کاربری (FRM) در اسکالاست که کار با پایگاه داده های رابطه ای را آسان می کند. اسلیک روشی برای نوشتن پرس و جو های اس کیو ال، تهیه نتایج و استفاده از یک زبان پرس و جو است که به خوبی با اسکالا یکپارچه شده است. شما می توانید پرس و جو های پایگاه داده ی خود را به جای اس کیو ال، در اسکالا بنویسید تا از قابلیت های بررسی استاتیک، ایمنی زمان کامپایل و سایر امکانات اسکالا بهره مند شوید. اسلیک دارای کامپایلر جستجوهای توسعه پذیر است که می تواند برای بک اندهای گوناگون کد تولید کند.
در حالت معمول، پرس و جو های اس کیو ال در حین اجرای برنامه (runtime)، تنها
cialis 20mg زمانی که واقعا اجرا شوند، بررسی خواهند شد. اما با کمک کتابخانه های موجود در اسلیک، بررسی های ایستا در زمان کامپایل رخ می دهد و از وقفه و شکستن کد (break) در زمان اجرا جلوگیری می کند. بنابراین هنگام استفاده از اسکالا به جای اس کیو ال معمول، برای پرس و جو ها، شما از ویژگی های امنیت و ترکیب در زمان کامپایل بهره مند خواهید شد.
دو ویژگی کلیدی در اسلیک، امنیت نوع و قابلیت ترکیب پرس و جو هاست. اسلیک با کامپایلر scala-to-sql همراه است که اجازه می دهد تا یک زیر مجموعه (کاملا کاربردی) از زبان اسکالا به پرس و جو های اس کیو ال کامپایل شود. با استفاده از کتابخانه های استاندارد در دسترس، توسعه دهندگان اسکالا می توانند با دانشی کم و بدون نیاز به دانستن اس کیو ال یا بخاطر آوردن نحوه ی نگارش خاصی، پرس و جو های زیادی را برای تمام پایگاه داده های ارتباطی پشتیبانی شده بنویسند. چنین پرس و جو هایی در اسلیک قابل خواندن هستند، بدین معنا که شما می توانید آنها را نوشته و در قطعات و توابع متفاوت بارها بکار ببرید تا از تکرار کد جلوگیری شود مانند استفاده از join به جای ترکیبات پیچیده ی رشته های اس کیو ال.
واقعیت این است که این پرس و جو ها ایمنی نوع دارند بدین معنا که نه تنها مشکلات زمان کامپایل را شناسایی می کنند بلکه آسیب های تزریق دستورات اس کیو ال را نیز حذف می کنند.

تبدیل اسکالا به اس کیو ال در زمان کامپایل

اسلیک کامپایلر اسکالا به اس کیو ال را برای پیاده سازی ویژگی پرس و جو در حالت امن اجرا میکند. کامپایلر در زمان اجرای اسکالا اجرا شده و زمانی را به خود اختصاص می دهد که حتی می تواند برای درخواست های پیچیده دو یا چندین بار کامپایل را انجام دهد. اینکه کامپایلر تنها یک بار در هر فرآیند تعریف شده و قبل از آن اجرا شود می تواند بسیار مفید باشد، برای مثال، به جای اینکه بارها و بارها اجرا شود، تنها یکبار در زمان راه اندازی برنامه اجرا شود. پرس و جوهای کامپایل شده به شما این امکان را می دهند که اس کیو ال تولید شده را ذخیره کرده و مجدداً استفاده کنید.
اسلیک به شما این امکان را می دهد تا هنگام کار با مجموعه های اسکالا با اطلاعات ذخیره شده در ارتباط باشید. علاوه براین، از mysql و postgreSQL نیز به خوبی پشتیبانی می کند.
برای استفاده از کتابخانه ی اسلیک، چنانچه از پایگاه داده MySQL استفاده می کنید بایستی از کد زیر استفاده کنید:


import slick.driver.MySQLDriver


و اگر از پایگاه داده ی Postgres استفاده می کنید بایستی کد زیر را وارد کنید:


import slick.driver.PostgresDriver


lifted embedding، یک استاندارد API برای پرس و جوهای نوع امن و بروزرسانی در اسلیک است. زمانی که این استاندارد با اسلیک ترکیب شود، اسلیک در برابر تزریق دستورات sql، راهکارهای محافظتی در نظر خواهد گرفت. با این حال، اگر به اس کیو ال در حالت ساده نیاز داشته باشید، به شما اجازه می دهد تا ریسک تزریق دستورات sql را بپذیرید.

تزریق به دیتابیس (SQL Injection) چیست؟

تزریق به پایگاه داده یا دیتابیس (SQL Injection) نوعی از حملات وب است که در آن فرد حمله کننده یا هکر می‌تواند اقدام به اجرا کردن دستورات دلخواه و مخرب خود بر روی پایگاه داده وب سایت مورد هدف کند. در این حمله، حمله کننده با استفاده از دانش خود (یا تنها با استفاده از یک برنامه ساده!) می‌تواند از نقض‌های امنیتی موجود در کدهای نوشته شده توسط برنامه نویس سایت استفاده کرده و به اصطلاح آن‌ها را اکسپلویت کند. چون در این حمله هکر درواقع به کد اسکیوال، کد دلخواه خود را اضافه می‌کند، تزریق SQL نام گرفته است.
یک حمله موفق اس کیو ال اینجکشن می‌تواند به راحتی سبب افشای داده‌های مهم در دیتابیس (ازجمله رمزهای عبور، اطلاعات فردی کاربران و …)، اضافه کردن داده‌های دلخواه حمله کننده به دیتابیس یا حذف کردن داده‌های خاص از دیتابیس گردد.

Lifted Embedding

اسلیک مجموعه های شما را گرفته و آنها را به اشیاء Rep، تبدیل کرده و یا اصطلاحاً آنها را درون اشیاء Rep ، lifts می کند. نوع اصلی داده حفظ شده و به سازنده ی Rep منتقل می شود، که در هنگام برقراری ارتباط با پایگاه داده اجازه ی ایمنی نوع و تمیز جدایی بین کد و داده ها را می دهد. مثال زیر نشان می دهد که پس از lifting، اسلیک داده های integer، string و Double را چگونه در نظر می گیرد.


private[example] class EmployeeTable(tag: Tag) extends Table[Employee](tag, "experienced_employee"){
val id = column[Int]("id",O.PrimaryKey)
val name = column[String]("name")
val experience = column[Double]("experience")
def * = (id,name,experience) <> (Employee.tupled, Employee.unapply)
}


پس از انجام عمل lifting، داده های int به صورت Rep[Int]، داده های string به صورت Rep[String] و داده های Double به شکل Rep[Double] تبدیل می شود.

مثال های اس کیو ال و اسلیک

به عنوان مثال جداول Person و address را در نظر بگیرید.
جدول Person(is,name,age,address_Id) به جدول Address(is,street,city) ارجاع داده می شود. این طرح پایگاه داده با استفاده از کد زیر به اسلیک نگاشت می شود:


type Person = (Int,String,Int,Int)
class People(tag: Tag) extends Table[Person](tag, "PERSON") {
def id = column[Int]("ID", O.PrimaryKey, O.AutoInc)
def name = column[String]("NAME")
def age = column[Int]("AGE")
def addressId = column[Int]("ADDRESS_ID")
def * = (id,name,age,addressId)
def address = foreignKey("ADDRESS",addressId,addresses)(_.id)
}
lazy val people = TableQuery[People] type Address = (Int,String,String)
class Addresses(tag: Tag) extends Table[Address](tag, "ADDRESS") {
def id = column[Int]("ID", O.PrimaryKey, O.AutoInc)
def street = column[String]("STREET")
def city = column[String]("CITY")
def * = (id,street,city)
}
lazy val addresses = TableQuery[Addresses] }


برخی از مهمترین پرس و جوهای اس کیو ال و کوئری های نوع امن در اسلیک به شرح زیر هستند:

INSERT

در اس کیو ال:


sqlu"""insert into PERSON (NAME, AGE, ADDRESS_ID) values ('John', 12345, 1) """


با استفاده از اسلیک، شما باید ابتدا یک پرس و جو بنویسید. به جای ایجاد یک اکشن که نتیجه ی این پرس و جو را نمایش دهد، شما باید با استفاده از علامت += و درج مقادیری که مدنظر شماست، عمل درج را انجام دهید. استفاده از ++= به شما این امکان را می دهد که هربار چند ردیف داده را درج کنید.


people.map(p => (p.name, p.age, p.addressId)) += ("xyz",12345,1)


UPDATE

در اس کیو ال:


sqlu"""update PERSON set NAME='John', AGE=54321 where NAME='James' """


در اسلیک، بروزرسانی ها براساس پرس و جوی انتخاب شده و فیلتر آنچه باید به روز شود، انجام می گیرد. به جای اجرای پرس و جو و گرفتن داده ها، در اسلیک از عمل .update برای جایگزینی یا اصطلاحاً بروزرسانی استفاده می شود.


people.filter(_.name === "xyz").map(p => (p.name,p.age)).update(("abc",54321))


DELETE

در اس کیو ال:


sqlu"""delete PERSON where NAME='John' """


در اسلیک، این عمل براساس پرس و جوی انتخاب شده و فیلتر آنچه که باید حذف شود، صورت می گیرد. به جای اینکه نتایج پرس و جو دریافت شود، از عمل delete برای حذف سطرهای انتخابی استفاده می شود.


people.filter(p => p.name === "John") .delete


* SELECT

در اس کیو ال:


sql"select * from PERSON".as[Person]


در اسلیک، معادل عمل  * select ،گرفتن نتایج جدول مدنظر می باشد:

people.result

SELECT

در اس کیو ال:


sql"""select AGE, concat(concat(concat(NAME,' ('),ID),')') from PERSON """.as[(Int,String)]


هنگام استفاده از اسلیک، برای عمل انتخاب، معادل آن در اسکالا، یعنی map استفاده می شود:


people.map(p => (p.age, p.name ++ " (" ++ p.id.asColumnOf[String] ++ ")")).result


WHERE

در اس کیو ال:


sql"select * from PERSON where AGE >= 18 AND NAME = 'C. Vogt'".as[Person]


هنگام کار با اسلیک، به جای where از معادل آن در اسکالا، یعنی filter استفاده می شود. علاوه براین، برای مقایسه به جای استفاده از == از === استفاده می شود.


people.filter(p => p.age >= 18 && p.name === "abc").result


ORDER BY

در اس کیو ال:


sql"select * from PERSON order by AGE asc, NAME".as[Person]


در اسلیک، به جای order By از معادل آن در اسکالا، یعنی sortBy استفاده می شود. اسلیک از دو متد .asc و .desc برای مرتب سازی استفاده می کند.


people.sortBy(p => (p.age.asc, p.name)).result


GROUP BY

در اس کیو ال:


sql"""select ADDRESS_ID, AVG(AGE) from PERSON group by ADDRESS_ID""".as[(Int,Option[Int])]


در اسلیک، استفاده از GroupBy نگاشتی از کلیدهای گروه بندی را به صورت لیست هایی شامل چندین ردیف برای هر گروه برمی گرداند. تبدیل خودکار ستون های جداگانه درون مجموعه ها وجود ندارد. در اسکالا و اسلیک این امر باید صریحاً با نگاشتی از گروه به ستون دلخواه، انجام شود و سپس مانند اس کیو ال اجازه ی تجمیع داده خواهد شد.



people.groupBy(p => p.addressId).map{ case (addressId, group) => (addressId, group.map(_.age).avg) }


Having

در اس کیو ال:


sql"""select ADDRESS_ID from PERSON group by ADDRESS_ID having avg(AGE) > 50""".as[Int]


اسلیک روش های مختلفی برای where و having ندارد. برای دستیابی به معانی معادل having، شما باید بعد از group by و نگاشت، به شکل زیر از فیلتر استفاده کنید.



people.groupBy(p => p.addressId).map{ case (addressId, group) => (addressId,group.map(_.age).avg) }.
ادامه مطلب
برچسب ها : آموزش کدهای SQLاز مبتدی تا پیشرفته ،
+ تعداد بازدید : ۴۵۹ |
نوشته شده توسط alisaadat در چهارشنبه ۱۸ بهمن ۱۳۹۶ و ساعت ۲۰:۱۱
ارسال نظر
نام شما :
آدرس وب سایت :
پست الکترونیک :
پیام شما :
کد امنیتی :