JavaRush /جاوا بلاگ /Random-SD /JDBC يا جتي اهو سڀ شروع ٿئي ٿو
Viacheslav
سطح

JDBC يا جتي اهو سڀ شروع ٿئي ٿو

گروپ ۾ شايع ٿيل
جديد دنيا ۾، ڊيٽا اسٽوريج کان سواء ڪو طريقو ناهي. ۽ ڊيٽابيس سان ڪم ڪرڻ جي تاريخ تمام گهڻو اڳ شروع ٿي، JDBC جي اچڻ سان. مان ڪجهه ياد ڪرڻ جي تجويز پيش ڪريان ٿو ته JDBC جي چوٽي تي ٺهيل ڪو به جديد فريم ورڪ بغير نٿو ڪري سگهي. اضافي طور تي، جيتوڻيڪ جڏهن انهن سان گڏ ڪم ڪري، ڪڏهن ڪڏهن توهان کي "پنهنجي جڙڙن ڏانهن موٽڻ" جو موقعو گهربل هجي. مون کي اميد آهي ته هي جائزو هڪ تعارف جي طور تي مدد ڪندو يا توهان جي يادگيري کي تازو ڪرڻ ۾ مدد ڪندو.
JDBC يا جتي اهو سڀ شروع ٿئي ٿو - 1

تعارف

هڪ پروگرامنگ ٻولي جو بنيادي مقصد معلومات کي محفوظ ڪرڻ ۽ پروسيسنگ ڪرڻ آهي. بهتر سمجھڻ لاءِ ته ڊيٽا اسٽوريج ڪيئن ڪم ڪري ٿي، اهو ٿورڙو وقت گذارڻ جي قابل آهي ايپليڪيشنن جي نظريي ۽ فن تعمير تي. مثال طور، توهان ادب پڙهي سگهو ٿا، يعني ڪتاب ” سافٽ ويئر آرڪيٽيڪٽ جو هينڊ بُڪ: هڪ ڪامياب سافٽ ويئر آرڪيٽيڪٽ بڻيو مؤثر آرڪيٽ لاڳو ڪري... “ جوزف انگينو جو. جيئن چيو ويو آهي، اتي هڪ خاص ڊيٽا ٽائر يا "ڊيٽا پرت" آهي. ان ۾ ڊيٽا کي ذخيرو ڪرڻ لاء هڪ جڳهه شامل آهي (مثال طور، هڪ SQL ڊيٽابيس) ۽ ڊيٽا اسٽور سان ڪم ڪرڻ لاء اوزار (مثال طور، JDBC، جنهن تي بحث ڪيو ويندو). Microsoft جي ويب سائيٽ تي پڻ هڪ مضمون آهي: “ انفراسٽرڪچر پرسسٽنس پرت کي ڊزائين ڪرڻ ”، جيڪو بيان ڪري ٿو هڪ اضافي پرت کي ڊيٽا ٽائر کان الڳ ڪرڻ جو آرڪيٽيڪچرل حل - The Persistence Layer. انهي صورت ۾، ڊيٽا ٽائر خود ڊيٽا جي اسٽوريج جي سطح آهي، جڏهن ته پرسسٽنس پرت ڊيٽا ٽائر جي سطح کان اسٽوريج مان ڊيٽا سان ڪم ڪرڻ لاء تجزيه جي ڪجهه سطح آهي. مستقل پرت ۾ شامل ٿي سگھي ٿو "DAO" ٽيمپليٽ يا مختلف ORMs. پر ORM هڪ ٻئي بحث لاء هڪ موضوع آهي. جئين توهان اڳ ۾ ئي سمجهي چڪا هوندا، ڊيٽا ٽائر پهريون ڀيرو ظاهر ٿيو. JDK 1.1 جي وقت کان وٺي، JDBC (Java DataBase Connectivity - جاوا ۾ ڊيٽابيس جو ڪنيڪشن) جاوا دنيا ۾ ظاهر ٿيو آهي. هي مختلف ڊي بي ايم ايس سان جاوا ايپليڪيشنن جي رابطي لاءِ هڪ معيار آهي، جاوا SE ۾ شامل java.sql ۽ javax.sql پيڪيجز جي صورت ۾ لاڳو ڪيو ويو آهي:
JDBC يا جتي اهو سڀ شروع ٿئي ٿو - 2
هي معيار وضاحت سان بيان ڪيو ويو آهي " JSR 221 JDBC 4.1 API ". هي وضاحت اسان کي ٻڌائي ٿي ته JDBC API جاوا ۾ لکيل پروگرامن مان لاڳاپيل ڊيٽابيس تائين پروگراماتي رسائي فراهم ڪري ٿي. اهو پڻ ٻڌائي ٿو ته JDBC API جاوا پليٽ فارم جو حصو آهي ۽ تنهن ڪري جاوا SE ۽ Java EE ۾ شامل آهي. JDBC API ٻن پيڪيجز ۾ مهيا ڪئي وئي آهي: java.sql ۽ javax.sql. اچو ته پوءِ انهن کي سڃاڻون.
JDBC يا جتي اهو سڀ شروع ٿئي ٿو - 3

ڪم جي شروعات

سمجھڻ لاءِ ته JDBC API عام طور تي ڇا آھي، اسان کي جاوا ايپليڪيشن جي ضرورت آھي. اهو سڀ کان وڌيڪ آسان آهي استعمال ڪرڻ لاء هڪ منصوبي اسيمبليء جي نظام مان. مثال طور، اچو ته استعمال ڪريون Gradle . توھان وڌيڪ پڙھي سگھوٿا Gradle بابت ھن مختصر جائزي ۾: " Gradle جو مختصر تعارف ". پهرين، اچو ته هڪ نئون Gradle پروجيڪٽ شروع ڪريون. جيئن ته Gradle ڪارڪردگي پلگ ان ذريعي لاڳو ڪئي وئي آهي، اسان کي استعمال ڪرڻ جي ضرورت آهي " Gradle Build Init Plugin " شروعات لاءِ:
gradle init --type java-application
ان کان پوء، اچو ته بلڊ اسڪرپٽ کوليو - build.gradle فائل ، جيڪو اسان جي منصوبي کي بيان ڪري ٿو ۽ ان سان ڪيئن ڪم ڪجي. اسان " انحصار " بلاڪ ۾ دلچسپي رکون ٿا، جتي انحصار بيان ڪيو ويو آهي - اهو آهي، اهي لائبريريون/فريم ورڪ/api، جن کان سواء اسان ڪم نٿا ڪري سگهون ۽ جن تي اسان انحصار ڪريون ٿا. ڊفالٽ طور اسان ڪجهه ڏسندا سين جيئن:
dependencies {
    // This dependency is found on compile classpath of this component and consumers.
    implementation 'com.google.guava:guava:26.0-jre'
    // Use JUnit test framework
    testImplementation 'junit:junit:4.12'
}
اسان هي هتي ڇو ڏسي رهيا آهيون؟ اهي اسان جي پروجيڪٽ جا انحصار آهن جيڪي پروجيڪٽ ٺاهڻ وقت Gradle خود بخود اسان لاءِ ٺاهيا آهن. ۽ اهو پڻ ڇاڪاڻ ته گووا هڪ الڳ لائبريري آهي جيڪا جاوا SE سان شامل ناهي. JUnit پڻ Java SE سان شامل نه آهي. پر اسان وٽ آهي JDBC دٻي کان ٻاهر، اهو آهي، اهو جاوا SE جو حصو آهي. اهو ظاهر ٿئي ٿو ته اسان وٽ JDBC آهي. زبردست. اسان کي ٻيو ڇا گهرجي؟ اتي هڪ اهڙي شاندار خاڪو آهي:
JDBC يا جتي اهو سڀ شروع ٿئي ٿو - 4
جيئن ته اسان ڏسي سگهون ٿا، ۽ اهو منطقي آهي، ڊيٽابيس هڪ خارجي جزو آهي جيڪو جاوا SE ڏانهن نه آهي. اهو آسان طور تي بيان ڪيو ويو آهي - ڊيٽابيس جو هڪ وڏو تعداد آهي ۽ توهان ڪنهن سان گڏ ڪم ڪري سگهو ٿا. مثال طور، اتي آهي PostgreSQL، Oracle، MySQL، H2. انهن مان هر هڪ ڊيٽابيس هڪ الڳ ڪمپني طرفان فراهم ڪيو ويندو آهي جنهن کي ڊيٽابيس وينڊرز سڏيو ويندو آهي. هر ڊيٽابيس کي پنهنجي پروگرامنگ ٻولي ۾ لکيو ويو آهي (ضروري ناهي ته جاوا). جاوا ايپليڪيشن مان ڊيٽابيس سان ڪم ڪرڻ جي قابل ٿيڻ لاء، ڊيٽابيس فراهم ڪندڙ هڪ خاص ڊرائيور لکي ٿو، جيڪو پنهنجي تصوير اڊاپٽر آهي. اهڙا JDBC مطابقت رکندڙ (يعني، جن وٽ JDBC ڊرائيور آهن) کي پڻ سڏيو ويندو آهي "JDBC-Compliant Database". هتي اسان ڪمپيوٽر ڊوائيسز سان هڪ قياس ٺاهي سگهون ٿا. مثال طور، هڪ نوٽ پيڊ ۾ هڪ "پرنٽ" بٽڻ آهي. هر دفعي توهان ان کي دٻايو، پروگرام آپريٽنگ سسٽم کي ٻڌائي ٿو ته نوٽ پيڊ ايپليڪيشن پرنٽ ڪرڻ چاهي ٿي. ۽ توهان وٽ هڪ پرنٽر آهي. توهان جي آپريٽنگ سسٽم کي سيکارڻ لاءِ هڪ ڪينن يا HP پرنٽر سان هڪجهڙائي سان رابطو ڪرڻ لاءِ، توهان کي مختلف ڊرائيورن جي ضرورت پوندي. پر توهان لاءِ صارف جي حيثيت ۾ ڪجھ به نه بدليو ويندو. توھان اڃا تائين ساڳيو بٽڻ دٻايو. ساڳيو JDBC سان. توهان هڪ ئي ڪوڊ هلائي رهيا آهيو، اهو صرف اهو آهي ته مختلف ڊيٽابيس شايد هود جي هيٺان هلائي رهيا آهن. منهنجو خيال آهي ته اهو هڪ تمام واضح طريقو آهي. هر هڪ JDBC ڊرائيور ڪجهه قسم جي آرٽيڪل، لائبريري، جار فائل آهي. هي اسان جي منصوبي لاء انحصار آهي. مثال طور، اسان ڊيٽابيس کي منتخب ڪري سگھون ٿا " H2 Database " ۽ پوء اسان کي ھن طرح ھڪڙي انحصار شامل ڪرڻ جي ضرورت آھي:
dependencies {
    implementation 'com.h2database:h2:1.4.197'
انحصار کي ڪيئن ڳولهجي ۽ ان کي ڪيئن بيان ڪجي ڊيٽابيس فراهم ڪندڙ جي سرڪاري ويب سائيٽن تي يا " Maven Central " تي. JDBC ڊرائيور هڪ ڊيٽابيس نه آهي، جيئن توهان سمجهي رهيا آهيو. پر هو ان لاءِ فقط هڪ رهنما آهي. پر اتي هڪ شيء آهي " ميموري ڊيٽابيس ۾ ". اهي ڊيٽابيس آهن جيڪي ميموري ۾ موجود آهن توهان جي ايپليڪيشن جي زندگيءَ لاءِ. عام طور تي، هي اڪثر ڪري جاچ يا تربيت جي مقصدن لاء استعمال ڪيو ويندو آهي. هي توهان کي مشين تي هڪ الڳ ڊيٽابيس سرور نصب ڪرڻ کان بچڻ جي اجازت ڏئي ٿو. جيڪو اسان لاءِ JDBC سان واقفيت حاصل ڪرڻ لاءِ تمام موزون آهي. تنهنڪري اسان جو سينڊ باڪس تيار آهي ۽ اسان شروع ڪريون ٿا.
JDBC يا جتي اهو سڀ شروع ٿئي ٿو - 5

ڪنيڪشن

تنهن ڪري، اسان وٽ هڪ JDBC ڊرائيور آهي، اسان وٽ هڪ JDBC API آهي. جيئن اسان کي ياد آهي، JDBC جاوا ڊيٽا بيس ڪنيڪشن لاء بيٺل آهي. تنهن ڪري، اهو سڀ ڪنيڪشن سان شروع ٿئي ٿو - ڪنيڪشن قائم ڪرڻ جي صلاحيت. ۽ ڪنيڪشن آهي ڪنيڪشن. اچو ته ٻيهر JDBC وضاحت جي متن ڏانهن وڃو ۽ مواد جي جدول کي ڏسو. باب ۾ " باب 4 جائزو " (نظرثاني) اسان سيڪشن ڏانهن ڦيرايو " 4.1 ڪنيڪشن قائم ڪرڻ " (ڪنيڪشن قائم ڪرڻ) اهو چيو ويندو آهي ته ڊيٽابيس سان ڳنڍڻ جا ٻه طريقا آهن:
  • ڊرائيور مئنيجر ذريعي
  • DataSource ذريعي
اچو ته ڊيل ڪريون ڊرائيور مئنيجر سان. جيئن چيو ويو آهي، ڊرائيور مئنيجر توهان کي مخصوص URL تي ڊيٽابيس سان ڳنڍڻ جي اجازت ڏئي ٿو، ۽ JDBC ڊرائيورز کي پڻ لوڊ ڪري ٿو جيڪو اهو CLASSPATH ۾ مليو (۽ ان کان اڳ، JDBC 4.0 کان اڳ، توهان کي ڊرائيور ڪلاس کي پاڻ لوڊ ڪرڻو پوندو). ڊيٽابيس سان ڳنڍڻ بابت هڪ الڳ باب ”باب 9 ڪنيڪشن“ آهي. اسان دلچسپي رکون ٿا ته ڊرائيور مئنيجر ذريعي ڪنيڪشن ڪيئن حاصل ڪجي، تنهنڪري اسان سيڪشن ۾ دلچسپي رکون ٿا "9.3 ڊرائيور مئنيجر ڪلاس". اهو ظاهر ڪري ٿو ته اسان ڊيٽابيس تائين رسائي ڪيئن ڪري سگهون ٿا:
Connection con = DriverManager.getConnection(url, user, passwd);
پيٽرول اسان کي منتخب ڪيل ڊيٽابيس جي ويب سائيٽ تان وٺي سگھجن ٿا. اسان جي حالت ۾، هي آهي H2 - " H2 چيٽ شيٽ ". اچو ته Gradle پاران تيار ڪيل AppTest ڪلاس ڏانھن وڃو. اهو JUnit ٽيسٽ تي مشتمل آهي. هڪ JUnit ٽيسٽ هڪ طريقو آهي جيڪو هڪ تشريح سان نشان لڳل آهي @Test. يونٽ ٽيسٽ هن جائزي جو موضوع نه آهن، تنهنڪري اسان صرف پنهنجو پاڻ کي سمجهڻ تائين محدود ڪنداسين ته اهي طريقا آهن جيڪي هڪ خاص طريقي سان بيان ڪيا ويا آهن، جن جو مقصد ڪنهن شيء کي جانچڻ آهي. JDBC جي وضاحت ۽ H2 ويب سائيٽ جي مطابق، اسان چيڪ ڪنداسين ته اسان ڊيٽابيس سان ڪنيڪشن حاصل ڪيو آهي. اچو ته ڪنيڪشن حاصل ڪرڻ جو طريقو لکون:
private Connection getNewConnection() throws SQLException {
	String url = "jdbc:h2:mem:test";
	String user = "sa";
	String passwd = "sa";
	return DriverManager.getConnection(url, user, passwd);
}
ھاڻي اچو ته ھن طريقي لاءِ ھڪ ٽيسٽ لکون جيڪو چيڪ ڪندو ته ڪنيڪشن اصل ۾ قائم آھي.
@Test
public void shouldGetJdbcConnection() throws SQLException {
	try(Connection connection = getNewConnection()) {
		assertTrue(connection.isValid(1));
		assertFalse(connection.isClosed());
	}
}
هي امتحان، جڏهن عمل ڪيو ويندو، تصديق ڪندو ته نتيجو ڪنيڪشن صحيح آهي (صحيح ٺاهيل) ۽ اهو بند نه آهي. وسيلن سان ڪوشش ڪرڻ سان اسان وسيلن کي ڇڏينداسين جڏهن اسان کي انهن جي وڌيڪ ضرورت نه هوندي. اهو اسان کي ڳنڍڻ واري ڪنيڪشن ۽ ميموري ليڪ کان بچائيندو. جيئن ته ڊيٽابيس سان گڏ ڪنهن به عمل کي ڪنيڪشن جي ضرورت آهي، اچو ته باقي ٽيسٽ طريقا مهيا ڪريون @Test سان نشان لڳل هڪ ڪنيڪشن سان ٽيسٽ جي شروعات ۾، جنهن کي اسين ٽيسٽ کان پوءِ جاري ڪنداسين. هن کي ڪرڻ لاءِ، اسان کي ٻن تشريحن جي ضرورت آهي: @Before ۽ @After اچو ته AppTest ڪلاس ۾ هڪ نئين فيلڊ شامل ڪريون جيڪي ٽيسٽن لاءِ JDBC ڪنيڪشن محفوظ ڪندا:
private static Connection connection;
۽ اچو ته نوان طريقا شامل ڪريو:
@Before
public void init() throws SQLException {
	connection = getNewConnection();
}
@After
public void close() throws SQLException {
	connection.close();
}
هاڻي، ڪنهن به ٽيسٽ جو طريقو جي ڊي بي سي ڪنيڪشن هجڻ جي ضمانت ڏني وئي آهي ۽ ان کي هر وقت پاڻ کي ٺاهڻ جي ضرورت ناهي.
JDBC يا جتي اهو سڀ شروع ٿئي ٿو - 6

بيان

اڳيون اسان بيانن يا اظهار ۾ دلچسپي وٺندا آهيون. اهي باب " باب 13 بيان " ۾ دستاويز ۾ بيان ڪيا ويا آهن . سڀ کان پهرين، اهو چوي ٿو ته بيانن جا ڪيترائي قسم يا قسم آهن:
  • بيان: SQL ايڪسپريشن جنهن ۾ ڪو به پيٽرول ڪونهي
  • PreparedStatement : تيار ڪيل SQL بيان جنهن ۾ ان پٽ پيٽرول شامل آهن
  • CallableStatement: SQL ايڪسپريشن سان گڏ SQL اسٽور ٿيل پروسيجرز مان واپسي جي قيمت حاصل ڪرڻ جي صلاحيت سان.
تنهن ڪري، هڪ ڪنيڪشن هجڻ سان، اسان هن ڪنيڪشن جي فريم ورڪ ۾ ڪجهه درخواست تي عمل ڪري سگهون ٿا. تنهن ڪري، اهو منطقي آهي ته اسان شروعاتي طور تي ڪنيڪشن مان SQL اظهار جو هڪ مثال حاصل ڪريون. توھان کي ھڪڙي ٽيبل ٺاھڻ سان شروع ڪرڻ جي ضرورت آھي. اچو ته بيان ڪريون ٽيبل ٺاهڻ جي درخواست کي String variable جي طور تي. اهو ڪيئن ڪجي؟ اچو ته ڪجھ سبق استعمال ڪريون جهڙوڪ " sqltutorial.org "، " sqlbolt.com "، " postgresqltutorial.com "، " codecademy.com ". اچو ته استعمال ڪريون، مثال طور، SQL ڪورس مان هڪ مثال khanacademy.org تي . اچو ته ڊيٽابيس ۾ ايڪسپريشن کي عمل ۾ آڻڻ لاءِ هڪ طريقو شامل ڪريون:
private int executeUpdate(String query) throws SQLException {
	Statement statement = connection.createStatement();
	// Для Insert, Update, Delete
	int result = statement.executeUpdate(query);
	return result;
}
اچو ته اڳئين طريقي کي استعمال ڪندي ٽيسٽ ٽيبل ٺاهڻ لاءِ هڪ طريقو شامل ڪريون:
private void createCustomerTable() throws SQLException {
	String customerTableQuery = "CREATE TABLE customers " +
                "(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)";
	String customerEntryQuery = "INSERT INTO customers " +
                "VALUES (73, 'Brian', 33)";
	executeUpdate(customerTableQuery);
	executeUpdate(customerEntryQuery);
}
هاڻي اچو ته هن کي جانچيون:
@Test
public void shouldCreateCustomerTable() throws SQLException {
	createCustomerTable();
	connection.createStatement().execute("SELECT * FROM customers");
}
هاڻي اچو ته درخواست تي عمل ڪريون، ۽ جيتوڻيڪ هڪ پيٽرولر سان:
@Test
public void shouldSelectData() throws SQLException {
 	createCustomerTable();
 	String query = "SELECT * FROM customers WHERE name = ?";
	PreparedStatement statement = connection.prepareStatement(query);
	statement.setString(1, "Brian");
	boolean hasResult = statement.execute();
	assertTrue(hasResult);
}
JDBC PreparedStatement لاءِ نامزد ٿيل پيرا ميٽرن کي سپورٽ نٿو ڪري، ان ڪري پيراميٽر پاڻ سوالن ذريعي بيان ڪيا ويا آهن، ۽ قيمت جي وضاحت ڪندي اسان سوالن جي انڊيڪس کي ظاهر ڪريون ٿا (1 کان شروع ٿئي ٿو، صفر نه). آخري امتحان ۾ اسان کي صحيح طور تي هڪ اشارو مليو ته ڇا نتيجو آهي. پر JDBC API ۾ سوال جو نتيجو ڪيئن پيش ڪيو ويو آهي؟ ۽ اهو هڪ نتيجو سيٽ جي طور تي پيش ڪيو ويو آهي.
JDBC يا جتي اهو سڀ شروع ٿئي ٿو - 7

نتيجو سيٽ

نتيجو سيٽ جو تصور JDBC API وضاحت ۾ باب "باب 15 نتيجا سيٽ" ۾ بيان ڪيو ويو آهي. سڀ کان پهريان، اهو چوي ٿو ته ResultSet جاري ڪيل سوالن جي نتيجن کي ٻيهر حاصل ڪرڻ ۽ ترتيب ڏيڻ لاء طريقا مهيا ڪري ٿو. اهو آهي، جيڪڏهن عمل ڪرڻ جو طريقو اسان ڏانهن صحيح موٽيو، ته پوء اسان حاصل ڪري سگهون ٿا هڪ نتيجو سيٽ. اچو ته ڪال کي CreateCustomerTable() ميٿڊ ۾ init ميٿڊ ۾ منتقل ڪريون، جنهن کي @Before طور نشان لڳايو ويو آهي. هاڻي اچو ته اسان جي shouldSelectData ٽيسٽ کي حتمي شڪل ڏيو:
@Test
public void shouldSelectData() throws SQLException {
	String query = "SELECT * FROM customers WHERE name = ?";
	PreparedStatement statement = connection.prepareStatement(query);
	statement.setString(1, "Brian");
	boolean hasResult = statement.execute();
	assertTrue(hasResult);
	// Обработаем результат
	ResultSet resultSet = statement.getResultSet();
	resultSet.next();
	int age = resultSet.getInt("age");
	assertEquals(33, age);
}
اهو هتي قابل ذڪر آهي ته ايندڙ هڪ طريقو آهي جنهن کي "ڪرسر" سڏيو ويندو آهي. ResultSet ۾ ڪرسر ڪجهه قطار ڏانهن اشارو ڪري ٿو. اهڙيء طرح، هڪ لڪير پڙهڻ لاء، توهان کي ان تي تمام گهڻو ڪرسر رکڻو پوندو. جڏهن ڪرسر کي منتقل ڪيو ويو آهي، ڪرسر منتقل ڪرڻ جو طريقو صحيح آهي جيڪڏهن ڪرسر صحيح آهي (درست، صحيح)، اهو آهي، اهو ڊيٽا ڏانهن اشارو ڪري ٿو. جيڪڏهن اهو غلط آهي، پوء ڪو به ڊيٽا ناهي، اهو آهي، ڪرسر ڊيٽا ڏانهن اشارو نه آهي. جيڪڏهن اسان غلط ڪرسر سان ڊيٽا حاصل ڪرڻ جي ڪوشش ڪنداسين، اسان کي غلطي ملندي: ڪو به ڊيٽا موجود ناهي اهو پڻ دلچسپ آهي ته ResultSet ذريعي توهان قطار کي اپڊيٽ ڪري يا داخل ڪري سگهو ٿا:
@Test
public void shouldInsertInResultSet() throws SQLException {
	Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
	ResultSet resultSet = statement.executeQuery("SELECT * FROM customers");
	resultSet.moveToInsertRow();
	resultSet.updateLong("id", 3L);
	resultSet.updateString("name", "John");
	resultSet.updateInt("age", 18);
	resultSet.insertRow();
	resultSet.moveToCurrentRow();
}

قطار سيٽ

ResultSet کان علاوه، JDBC RowSet جو تصور متعارف ڪرايو. توھان وڌيڪ پڙھي سگھوٿا ھتي: " JDBC Basics: RowSet Objects استعمال ڪندي ". استعمال جا مختلف قسم آهن. مثال طور، سادو ڪيس هن طرح نظر اچي سگهي ٿو:
@Test
public void shouldUseRowSet() throws SQLException {
 	JdbcRowSet jdbcRs = new JdbcRowSetImpl(connection);
 	jdbcRs.setCommand("SELECT * FROM customers");
	jdbcRs.execute();
	jdbcRs.next();
	String name = jdbcRs.getString("name");
	assertEquals("Brian", name);
}
جئين توهان ڏسي سگهو ٿا، RowSet بيان جي هڪ symbiosis سان ملندڙ جلندڙ آهي (اسان ان جي ذريعي حڪم ڏنو آهي) ۽ حڪم جاري ڪيو ويو آهي. ان جي ذريعي اسان ڪرسر کي ڪنٽرول ڪريون ٿا (ايندڙ طريقي سان ڪال ڪندي) ۽ ان مان ڊيٽا حاصل ڪريون ٿا. نه رڳو اهو طريقو دلچسپ آهي، پر ممڪن لاڳو ڪرڻ پڻ. مثال طور، CachedRowSet. اهو "منقطع" آهي (اهو آهي، اهو ڊيٽابيس سان مسلسل ڪنيڪشن استعمال نٿو ڪري) ۽ ڊيٽابيس سان واضح هم وقت سازي جي ضرورت آهي:
CachedRowSet jdbcRsCached = new CachedRowSetImpl();
jdbcRsCached.acceptChanges(connection);
توھان وڌيڪ پڙھي سگھوٿا سبق ۾ Oracle ويب سائيٽ تي: " CachedRowSetObjects استعمال ڪندي ".
JDBC يا جتي اهو سڀ شروع ٿئي ٿو - 8

ميٽاداٽا

سوالن کان علاوه، ڊيٽابيس سان هڪ ڪنيڪشن (يعني ڪنيڪشن ڪلاس جو هڪ مثال) ميٽا ڊيٽا تائين پهچ مهيا ڪري ٿو - ڊيٽا جي باري ۾ ته اسان جي ڊيٽابيس کي ڪيئن ترتيب ۽ منظم ڪيو ويو آهي. پر پهرين، اچو ته ڪجهه اهم نقطن جو ذڪر ڪريون: اسان جي ڊيٽابيس سان ڳنڍڻ لاءِ URL: "jdbc:h2:mem:test". test اسان جي ڊيٽابيس جو نالو آهي. JDBC API لاءِ، هي هڪ ڊاريڪٽري آهي. ۽ نالو هوندو وڏي اکر ۾، يعني TEST. H2 لاءِ ڊفالٽ اسڪيما عوامي آھي. ھاڻي اچو ته ھڪ ٽيسٽ لکون جيڪو ڏيکاري ٿو سڀ يوزر ٽيبل. رواج ڇو؟ ڇاڪاڻ ته ڊيٽابيس ۾ نه رڳو استعمال ڪندڙ ٽيبل (جيڪي اسان پاڻ ٺاهيا آهن انهن کي ٺاهيل ٽيبل ايڪسپريشن استعمال ڪندي)، پر سسٽم ٽيبل پڻ. اهي ڊيٽابيس جي جوڙجڪ بابت سسٽم جي معلومات کي ذخيرو ڪرڻ لاء ضروري آهن. هر ڊيٽابيس اهڙي سسٽم ٽيبل کي مختلف طريقي سان محفوظ ڪري سگهي ٿو. مثال طور، H2 ۾ اهي ذخيرو ٿيل آهن " INFORMATION_SCHEMA " اسڪيما. دلچسپ ڳالهه اها آهي ته انفارميشن اسڪيما هڪ عام طريقو آهي، پر Oracle هڪ مختلف رستو اختيار ڪيو. توهان هتي وڌيڪ پڙهي سگهو ٿا: " INFORMATION_SCHEMA ۽ Oracle ". اچو ته هڪ امتحان لکون جيڪو صارف جي ٽيبل تي ميٽا ڊيٽا وصول ڪري ٿو:
@Test
public void shoudGetMetadata() throws SQLException {
	// У нас URL = "jdbc:h2:mem:test", где test - название БД
	// Название БД = catalog
	DatabaseMetaData metaData = connection.getMetaData();
	ResultSet result = metaData.getTables("TEST", "PUBLIC", "%", null);
	List<String> tables = new ArrayList<>();
	while(result.next()) {
		tables.add(result.getString(2) + "." + result.getString(3));
	}
	assertTrue(tables.contains("PUBLIC.CUSTOMERS"));
}
JDBC يا جتي اهو سڀ شروع ٿئي ٿو - 9

ڪنيڪشن پول

JDBC وضاحتن ۾ ڪنيڪشن پول ۾ ھڪڙو سيڪشن آھي جنھن کي "باب 11 ڪنيڪشن پولنگ" سڏيو ويندو آھي. اهو پڻ ڪنيڪشن پول جي ضرورت لاء بنيادي جواز مهيا ڪري ٿو. هر ڪوونڪشن ڊيٽابيس سان هڪ جسماني ڪنيڪشن آهي. ان جي تخليق ۽ بندش ڪافي هڪ "مهانگي" نوڪري آهي. JDBC صرف هڪ ڪنيڪشن پولنگ API مهيا ڪري ٿو. تنهن ڪري، عمل درآمد جو انتخاب اسان جي رهي ٿو. مثال طور، اهڙن عملن ۾ شامل آهن HikariCP . ان جي مطابق، اسان کي اسان جي منصوبي جي انحصار ۾ پول شامل ڪرڻ جي ضرورت پوندي.
dependencies {
    implementation 'com.h2database:h2:1.4.197'
    implementation 'com.zaxxer:HikariCP:3.3.1'
    testImplementation 'junit:junit:4.12'
}
هاڻي اسان کي ڪنهن به طرح هن تلاء کي استعمال ڪرڻ جي ضرورت آهي. هن کي ڪرڻ لاءِ، توهان کي ڊيٽا ماخذ کي شروع ڪرڻ جي ضرورت آهي، جنهن کي Datasource طور سڃاتو وڃي ٿو:
private DataSource getDatasource() {
	HikariConfig config = new HikariConfig();
	config.setUsername("sa");
	config.setPassword("sa");
	config.setJdbcUrl("jdbc:h2:mem:test");
	DataSource ds = new HikariDataSource(config);
	return ds;
}
۽ اچو ته پول مان ڪنيڪشن حاصل ڪرڻ لاءِ ٽيسٽ لکون:
@Test
public void shouldGetConnectionFromDataSource() throws SQLException {
	DataSource datasource = getDatasource();
	try (Connection con = datasource.getConnection()) {
		assertTrue(con.isValid(1));
	}
}
JDBC يا جتي اهو سڀ شروع ٿئي ٿو - 10

معاملو

JDBC بابت سڀ کان وڌيڪ دلچسپ شين مان هڪ ٽرانزيڪشن آهي. JDBC وضاحت ۾، انهن کي باب "باب 10 ٽرانزيڪشن" تفويض ڪيو ويو آهي. سڀ کان پهريان، اهو سمجهڻ جي قابل آهي ته ٽرانزيڪشن ڇا آهي. هڪ ٽرانزيڪشن ڊيٽا تي منطقي طور تي گڏيل ترتيب واري عملن جو هڪ گروپ آهي، مڪمل طور تي پروسيس ٿيل يا منسوخ ڪيو ويو آهي. جڏهن JDBC استعمال ڪندي ٽرانزيڪشن شروع ٿئي ٿي؟ جيئن بيان ڪيل بيان، اهو سڌو سنئون JDBC ڊرائيور طرفان سنڀاليو ويو آهي. پر عام طور تي، هڪ نئون ٽرانزيڪشن شروع ٿئي ٿو جڏهن موجوده SQL بيان هڪ ٽرانزيڪشن جي ضرورت آهي ۽ ٽرانزيڪشن اڃا تائين پيدا نه ڪيو ويو آهي. ٽرانزيڪشن ڪڏهن ختم ٿئي ٿي؟ اهو خودڪار ڪمٽ وصف طرفان ڪنٽرول ڪيو ويندو آهي. جيڪڏهن خودڪار ڪميٽي فعال آهي، ٽرانزيڪشن مڪمل ڪيو ويندو SQL بيان "مڪمل" ٿيڻ کان پوء. ڇا "ٿيو" جو مطلب آهي SQL اظهار جي قسم تي منحصر آهي:
  • ڊيٽا جي ڦيرڦار جي ٻولي، جنهن کي DML پڻ سڏيو ويندو آهي (داخل ڪريو، تازه ڪاري ڪريو، حذف ڪريو)
    ٽرانزيڪشن مڪمل ڪيو ويندو آهي جيئن ئي عمل مڪمل ٿئي ٿي.
  • بيان چونڊيو
    ٽرانزيڪشن مڪمل ٿي ويندي آهي جڏهن نتيجو سيٽ بند ڪيو ويندو آهي ( ResultSet#close )
  • CallableStatement ۽ ايڪسپريسشن جيڪي گھڻا نتيجا موٽائيندا آھن
    جڏھن سڀ لاڳاپيل ResultSets بند ڪيا ويا آھن ۽ سڀ آئوٽ پُٽ مليا آھن (بشمول تازه ڪارين جو تعداد)
اهو بلڪل آهي JDBC API ڪيئن عمل ڪندو آهي. هميشه وانگر، اچو ته هن لاء هڪ امتحان لکون:
@Test
public void shouldCommitTransaction() throws SQLException {
	connection.setAutoCommit(false);
	String query = "INSERT INTO customers VALUES (1, 'Max', 20)";
	connection.createStatement().executeUpdate(query);
	connection.commit();
	Statement statement = connection.createStatement();
 	statement.execute("SELECT * FROM customers");
	ResultSet resultSet = statement.getResultSet();
	int count = 0;
	while(resultSet.next()) {
		count++;
	}
	assertEquals(2, count);
}
اهو سادو آهي. پر اهو سچ آهي جيستائين اسان وٽ صرف هڪ ٽرانزيڪشن آهي. ڇا ڪجي جڏهن انهن مان ڪيترائي آهن؟ انهن کي هڪ ٻئي کان الڳ ڪرڻ جي ضرورت آهي. تنهن ڪري، اچو ته ٽرانزيڪشن جي اڪيلائي جي سطح بابت ڳالهايون ۽ ڪيئن JDBC انهن سان معاملو ڪري ٿو.
JDBC يا جتي اهو سڀ شروع ٿئي ٿو - 11

موصليت جي سطح

اچو ته JDBC وضاحت جي سب سيڪشن ”10.2 ٽرانزيڪشن آئسوليشن ليولز“ کي کوليون. هتي، اڳتي وڌڻ کان اڳ، مان ACID طور هڪ اهڙي شيء بابت ياد رکڻ چاهيندس. ACID ھڪڙي ٽرانزيڪشنل سسٽم جي ضرورتن کي بيان ڪري ٿو.
  • Atomicity:
    ڪابه ٽرانزيڪشن جزوي طور تي سسٽم سان انجام نه ڏني ويندي. يا ته ان جا سڀ ذيلي آپريشن ڪيا ويندا، يا ڪو به انجام نه ڏنو ويندو.
  • مطابقت:
    هر ڪامياب ٽرانزيڪشن، تعريف سان، صرف صحيح نتيجا رڪارڊ ڪري ٿو.
  • اڪيلائي:
    جڏهن هڪ ٽرانزيڪشن هلندڙ آهي، سمورو ٽرانزيڪشن ان جي نتيجن کي متاثر نه ڪرڻ گهرجي.
  • Durability:
    جيڪڏهن هڪ ٽرانزيڪشن ڪاميابيءَ سان مڪمل ٿي وڃي ٿي، ته ان ۾ ڪيل تبديليون ڪنهن به ناڪامي جي ڪري رد نه ڪيون وينديون.
جڏهن ٽرانزيڪشن جي اڪيلائي جي سطحن بابت ڳالهائيندي، اسان "اڪيلائي" جي گهرج بابت ڳالهائي رهيا آهيون. اڪيلائي هڪ قيمتي گهرج آهي، تنهن ڪري حقيقي ڊيٽابيس ۾ اهڙا طريقا آهن جيڪي مڪمل طور تي هڪ ٽرانزيڪشن کي الڳ نه ڪندا آهن (ٻيهر پڙهي سگهجي ٿو اڪيلائي جي سطح ۽ هيٺيون). وڪيپيڊيا وٽ انهن مسئلن جي هڪ بهترين وضاحت آهي جيڪي ٽرانزيڪشن سان ڪم ڪرڻ وقت پيدا ٿي سگهن ٿيون. اهو هتي وڌيڪ پڙهڻ جي قابل آهي: " ٽرانزيڪشن استعمال ڪندي متوازي رسائي جا مسئلا ." ان کان اڳ جو اسان اسان جي ٽيسٽ لکون، اچو ته اسان جي گريڊل بلڊ اسڪرپٽ کي ٿورو تبديل ڪريون: پراپرٽيز سان هڪ بلاڪ شامل ڪريو، يعني اسان جي پروجيڪٽ جي سيٽنگن سان:
ext {
    h2Version = '1.3.176' // 1.4.177
    hikariVersion = '3.3.1'
    junitVersion = '4.12'
}
اڳيون، اسان هن نسخن ۾ استعمال ڪندا آهيون:
dependencies {
    implementation "com.h2database:h2:${h2Version}"
    implementation "com.zaxxer:HikariCP:${hikariVersion}"
    testImplementation "junit:junit:${junitVersion}"
}
توهان شايد محسوس ڪيو آهي ته h2 نسخو گهٽ ٿي چڪو آهي. اسان بعد ۾ ڏسنداسين ڇو. پوءِ توهان اڪيلائي جي سطح کي ڪيئن لاڳو ڪندا آهيو؟ اچو ته فوري طور تي هڪ ننڍڙو عملي مثال ڏسو:
@Test
public void shouldGetReadUncommited() throws SQLException {
	Connection first = getNewConnection();
	assertTrue(first.getMetaData().supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED));
	first.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
	first.setAutoCommit(false);
	// Транзакиця на подключение. Поэтому первая транзакция с ReadUncommited вносит изменения
	String insertQuery = "INSERT INTO customers VALUES (5, 'Max', 15)";
	first.createStatement().executeUpdate(insertQuery);
	// Вторая транзакция пытается их увидеть
	int rowCount = 0;
	JdbcRowSet jdbcRs = new JdbcRowSetImpl(getNewConnection());
	jdbcRs.setCommand("SELECT * FROM customers");
	jdbcRs.execute();
	while (jdbcRs.next()) {
		rowCount++;
	}
	assertEquals(2, rowCount);
}
دلچسپ ڳالهه اها آهي ته، هي امتحان ناڪام ٿي سگهي ٿو هڪ وينڊر تي جيڪو سپورٽ نٿو ڪري TRANSACTION_READ_UNCOMMITTED (مثال طور، sqlite يا HSQL). ۽ ٽرانزيڪشن جي سطح شايد ڪم نه ڪري سگھي. ياد رکو اسان H2 ڊيٽابيس ڊرائيور جو نسخو اشارو ڪيو؟ جيڪڏهن اسان ان کي وڌايو h2Version = '1.4.177' ۽ وڌيڪ، پوءِ READ UNCOMMITTED ڪم ڪرڻ بند ڪري ڇڏيندو، جيتوڻيڪ اسان ڪوڊ تبديل نه ڪيو آهي. اهو هڪ ڀيرو ٻيهر ثابت ٿئي ٿو ته وينڊر ۽ ڊرائيور ورزن جو انتخاب صرف خط نه آهي، اهو اصل ۾ طئي ڪندو ته توهان جي درخواستن تي عمل ڪيو ويندو. توھان پڙھي سگھوٿا ھن رويي کي ڪيئن درست ڪجي ورجن 1.4.177 ۾ ۽ اھو ڪيئن ڪم نٿو ڪري ھتي اعليٰ ورزن ۾: ” سپورٽ ڪريو READ UNCOMMITTED isolation level in MVStore mode “.
JDBC يا جتي اهو سڀ شروع ٿئي ٿو - 12

هيٺين لائن

جئين اسان ڏسي سگهون ٿا، JDBC هڪ طاقتور اوزار آهي جاوا جي هٿن ۾ ڊيٽابيس سان ڪم ڪرڻ لاء. مون کي اميد آهي ته هي مختصر جائزو توهان کي شروعاتي نقطي ڏيڻ ۾ مدد ڏيندو يا توهان جي يادگيري کي تازو ڪرڻ ۾ مدد ڪندو. خير، ناشتي لاء، ڪجهه اضافي مواد: #وياچسلاو
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION