JavaRush /Блоги Java /Random-TG /JDBC ё дар куҷо ҳамааш оғоз мешавад
Viacheslav
Сатҳи

JDBC ё дар куҷо ҳамааш оғоз мешавад

Дар гурӯҳ нашр шудааст
Дар ҷаҳони муосир ҳеҷ роҳе бе нигоҳдории маълумот вуҷуд надорад. Ва таърихи кор бо пойгоҳи додаҳо хеле пештар, бо пайдоиши JDBC оғоз ёфт. Ман пешниҳод мекунам, ки чизеро ба ёд орам, ки ҳеҷ як чаҳорчӯбаи муосири дар болои JDBC сохташуда бидуни он кор карда наметавонад. Илова бар ин, ҳатто ҳангоми кор бо онҳо, баъзан ба шумо имкони «баргаштан ба решаҳои худ» лозим аст. Умедворам, ки ин барраси ҳамчун муқаддима кӯмак мекунад ё ба тоза кардани хотираи шумо кӯмак мекунад.
JDBC ё дар куҷо ҳамааш оғоз мешавад - 1

Муқаддима

Яке аз ҳадафҳои асосии забони барномасозӣ ҳифз ва коркарди информатсия мебошад. Барои беҳтар фаҳмидани он, ки нигоҳдории маълумот чӣ гуна кор мекунад, барои назария ва меъмории барномаҳо каме вақт сарф кардан лозим аст. Масалан, шумо метавонед адабиётро хонед, аз ҷумла китоби " Дастур оид ба меъмори нармафзор: Меъмори нармафзори бомуваффақият тавассути татбиқи арки муассир шудан... " аз ҷониби Ҷозеф Ингено. Тавре ки гуфта шуд, сатҳи муайяни маълумот ё "қабати маълумот" вуҷуд дорад. Он дорои ҷои нигоҳдории додаҳо (масалан, пойгоҳи додаҳои SQL) ва асбобҳо барои кор бо мағозаи додаҳо (масалан, JDBC, ки муҳокима карда мешавад). Инчунин дар вебсайти Microsoft мақолае мавҷуд аст: " Тарҳрезии қабати устувории инфрасохтор ", ки ҳалли меъмории ҷудо кардани қабати иловагиро аз сатҳи маълумот - қабати доимӣ тавсиф мекунад. Дар ин ҳолат, сатҳи маълумот сатҳи нигоҳдории худи маълумот аст, дар ҳоле ки қабати доимӣ як сатҳи абстраксия барои кор бо маълумот аз нигоҳдорӣ аз сатҳи сатҳи маълумот мебошад. Қабати доимӣ метавонад қолаби "DAO" ё ORM-ҳои гуногунро дар бар гирад. Аммо ORM мавзӯи баҳси дигар аст. Тавре ки шумо аллакай фаҳмидед, сатҳи маълумот аввал пайдо шуд. Аз замони JDK 1.1, JDBC (Java DataBase Connectivity - пайвастшавӣ ба пойгоҳи додаҳо дар Java) дар ҷаҳони Java пайдо шуд. Ин стандарт барои ҳамкории барномаҳои Java бо DBMS-ҳои гуногун мебошад, ки дар шакли бастаҳои java.sql ва javax.sql, ки ба Java SE дохил карда шудаанд, амалӣ карда мешавад:
JDBC ё дар куҷо ҳамааш оғоз мешавад - 2
Ин стандарт бо мушаххасоти " JSR 221 JDBC 4.1 API " тавсиф шудааст. Ин мушаххасот ба мо мегӯяд, ки API JDBC дастрасии барномавӣ ба пойгоҳи додаҳои релятсионӣ аз барномаҳои дар Java навишташударо таъмин мекунад. Он инчунин мегӯяд, ки API JDBC як қисми платформаи Java аст ва аз ин рӯ ба Java SE ва Java EE дохил карда шудааст. API-и JDBC дар ду баста таъмин карда шудааст: java.sql ва javax.sql. Пас биёед бо онҳо шинос шавем.
JDBC ё дар куҷо ҳамааш оғоз мешавад - 3

Оғози кор

Барои фаҳмидани он ки API-и JDBC умуман чист, ба мо як барномаи Java лозим аст. Истифодаи яке аз системаҳои васлкунии лоиҳа аз ҳама қулай аст. Масалан, биёед Gradle -ро истифода барем . Шумо метавонед бештар дар бораи Gradle дар шарҳи кӯтоҳ хонед: " Муқаддимаи мухтасар ба Gradle ". Аввалан, биёед лоиҳаи нави Gradle-ро оғоз кунем. Азбаски функсияи Gradle тавассути плагинҳо амалӣ карда мешавад, мо бояд барои оғозёбӣ " Gradle Build Init Plugin " -ро истифода барем:
gradle init --type java-application
Пас аз ин, биёед скрипти сохтмонро кушоем - файли build.gradle , ки лоиҳаи моро ва тарзи кор бо он тавсиф мекунад. Мо ба блоки " dependencies " таваҷҷӯҳ дорем , ки дар он вобастагӣ тавсиф шудаанд - яъне он китобхонаҳо/чаҳорчӯбаҳо/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 ҳангоми сохтани лоиҳа ба таври худкор барои мо тавлид мекунад. Ва инчунин аз он сабаб, ки guava китобхонаи алоҳидаест, ки ба Java SE дохил карда нашудааст. JUnit инчунин ба Java SE дохил карда нашудааст. Аммо мо JDBC аз қуттӣ дорем, яъне он қисми Java SE аст. Маълум мешавад, ки мо JDBC дорем. бузург. Ба мо боз чӣ лозим аст? Чунин диаграммаи аҷибе вуҷуд дорад:
JDBC ё дар куҷо ҳамааш оғоз мешавад - 4
Тавре ки мо мебинем, ва ин мантиқист, базаи маълумот ҷузъи беруна аст, ки барои Java SE модарӣ нест. Ин ба таври оддӣ шарҳ дода мешавад - шумораи зиёди пойгоҳи додаҳо вуҷуд доранд ва шумо метавонед бо дилхоҳ кор кунед. Масалан, PostgreSQL, Oracle, MySQL, H2 вуҷуд дорад. Ҳар яке аз ин пойгоҳи додаҳо аз ҷониби як ширкати алоҳида бо номи фурӯшандагони пойгоҳи додаҳо таъмин карда мешавад. Ҳар як пойгоҳи додаҳо бо забони барномасозии худ навишта шудааст (на ҳатман Java). Барои он ки бо пойгоҳи додаҳо аз барномаи Java кор карда тавонанд, провайдери базаи маълумот драйвери махсусро менависад, ки адаптери тасвирии худ аст. Чунин шахсони мувофиқи JDBC (яъне онҳое, ки драйвери JDBC доранд) инчунин "Махзани маълумоти JDBC-Мувофиқ" номида мешаванд. Дар ин ҷо мо метавонем бо дастгоҳҳои компютерӣ муқоиса кунем. Масалан, дар блокнот тугмаи "Чоп кардан" мавҷуд аст. Ҳар дафъае, ки шумо онро пахш мекунед, барнома ба системаи оператсионӣ хабар медиҳад, ки замимаи блокнот чоп кардан мехоҳад. Ва шумо принтер доред. Барои таълим додани системаи оператсионии шумо бо як принтери Canon ё HP, ба шумо драйверҳои гуногун лозим мешавад. Аммо барои шумо, ҳамчун корбар, ҳеҷ чиз тағир намеёбад. Шумо ба ҳар ҳол ҳамон тугмаро пахш мекунед. Ҳамин бо JDBC. Шумо ҳамон codeро иҷро карда истодаед, танҳо он аст, ки пойгоҳи додаҳои гуногун метавонанд дар зери сарпӯш кор кунанд. Ман фикр мекунам, ки ин як равиши хеле равшан аст. Ҳар як чунин драйвери JDBC як навъ артефакт, китобхона, файли jar мебошад. Ин вобастагии лоиҳаи мост. Масалан, мо метавонем пойгоҳи додаи " H2 Database "-ро интихоб кунем ва он гоҳ мо бояд вобастагии зеринро илова кунем:
dependencies {
    implementation 'com.h2database:h2:1.4.197'
Чӣ тавр пайдо кардани вобастагӣ ва чӣ гуна тасвир кардани он дар вебсайтҳои расмии провайдери пойгоҳи додаҳо ё дар " Maven Central " нишон дода шудааст. Ронандаи JDBC, тавре ки шумо мефаҳмед, пойгоҳи додаҳо нест. Аммо ӯ танҳо роҳнамоии он аст. Аммо чунин чизе вуҷуд дорад " Дар базаҳои хотира ". Инҳо пойгоҳи додаҳоянд, ки дар хотира дар тӯли умри барномаи шумо мавҷуданд. Одатан, ин одатан барои санҷиш ё омӯзиш истифода мешавад. Ин ба шумо имкон медиҳад, ки аз насб кардани serverи пойгоҳи додаҳо дар мошин канорагирӣ кунед. Ин барои мо барои шиносоӣ бо JDBC хеле мувофиқ аст. Пас, қуттии мо омода аст ва мо оғоз мекунем.
JDBC ё дар куҷо ҳамааш оғоз мешавад - 5

Пайвастшавӣ

Ҳамин тавр, мо як драйвери JDBC дорем, мо API JDBC дорем. Тавре ки мо дар хотир дорем, JDBC маънои Java DataBase Connectivity мебошад. Аз ин рӯ, ҳамааш аз Пайвастшавӣ оғоз мешавад - қобorяти барқарор кардани пайваст. Ва пайвастшавӣ Пайвастшавӣ аст. Биёед бори дигар ба матни мушаххасоти JDBC муроҷиат кунем ва ба ҷадвали мундариҷа назар кунем. Дар боби " Баррасии БОБИ 4 " (баррасӣ) мо ба бахши " 4.1 Таъсиси пайвастшавӣ " (барқарор кардани пайвастшавӣ) меравем, гуфта мешавад, ки ду роҳи пайвастшавӣ ба базаи маълумот мавҷуд аст:
  • Тавассути DriverManager
  • Тавассути DataSource
Биёед бо DriverManager кор кунем. Тавре ки гуфта шуд, DriverManager ба шумо имкон медиҳад, ки ба пойгоҳи додаҳо дар URL-и муайян пайваст шавед ва инчунин Драйверҳои JDBC-ро, ки дар CLASSPATH ёфт шудаанд, бор мекунад (ва пеш аз JDBC 4.0, шумо бояд синфи драйверро худатон бор кунед). Дар бораи пайвастшавӣ ба базаи маълумот боби алоҳидаи "БОБИ 9 Пайвастшавӣ" мавҷуд аст. Мо ба он таваҷҷӯҳ дорем, ки чӣ тавр тавассути DriverManager пайваст шудан мумкин аст, бинобар ин мо ба бахши "9.3 Синфи DriverManager" таваҷҷӯҳ дорем. Он нишон медиҳад, ки чӣ тавр мо метавонем ба пойгоҳи додаҳо дастрасӣ пайдо кунем:
Connection con = DriverManager.getConnection(url, user, passwd);
Параметрҳоро аз вебсайти пойгоҳи додаи мо интихоб кардан мумкин аст. Дар ҳолати мо, ин H2 - " H2 Cheat Sheet " аст. Биёед ба синфи AppTest, ки аз ҷониби Gradle таҳия шудааст, мегузарем. Он дорои санҷишҳои 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 бо Пайвастшавӣ дар оғози санҷиш пешниҳод кунем, ки мо онҳоро пас аз санҷиш нашр хоҳем кард. Барои ин ба мо ду эзоҳ лозим аст: @Pefore ва @After Биёед ба синфи AppTest майдони нав илова кунем, ки пайвасти JDBC-ро барои санҷишҳо нигоҳ медорад:
private static Connection connection;
Ва биёед усулҳои навро илова кунем:
@Before
public void init() throws SQLException {
	connection = getNewConnection();
}
@After
public void close() throws SQLException {
	connection.close();
}
Ҳоло, ҳама гуна усули санҷиш кафолат дода мешавад, ки пайвасти JDBC дошта бошад ва набояд онро ҳар дафъа эҷод кунад.
JDBC ё дар куҷо ҳамааш оғоз мешавад - 6

Изҳорот

Минбаъд мо ба Изҳорот ё ифодаҳо таваҷҷӯҳ дорем. Онҳо дар ҳуҷҷатҳо дар боби " Баёноти БОБИ 13 " тавсиф шудаанд. Аввалан, он мегӯяд, ки якчанд намуд ё намуди изҳорот вуҷуд дорад:
  • Изҳорот: Ифодаи SQL, ки параметрҳоро дар бар намегирад
  • PreparedStatement: Изҳороти омодашудаи SQL, ки дорои параметрҳои воридотӣ мебошад
  • CallableStatement: Ифодаи SQL бо қобorяти ба даст овардани арзиши бозгашт аз SQL Stored Procedures.
Ҳамин тавр, бо доштани пайвастшавӣ мо метавонем дар доираи ин пайваст ягон дархостро иҷро кунем. Аз ин рӯ, мантиқист, ки мо дар аввал намунаи ифодаи SQL-ро аз Пайвастшавӣ ба даст меорем. Шумо бояд аз сохтани ҷадвал оғоз кунед. Биёед дархости сохтани ҷадвалро ҳамчун тағирёбандаи String тавсиф кунем. Чӣ тавр бояд кард? Биёед якчанд дарсро истифода барем, ба монанди " 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, на сифр сар карда). Дар санҷиши охирин мо ҳамчун нишонаи он, ки натиҷа вуҷуд дорад ё не. Аммо натиҷаи дархост дар API JDBC чӣ гуна нишон дода мешавад? Ва он ҳамчун ResultSet пешниҳод карда мешавад.
JDBC ё дар куҷо ҳамааш оғоз мешавад - 7

Натиҷаҳо

Консепсияи ResultSet дар мушаххасоти JDBC API дар боби "БОБ 15 Маҷмӯаҳои натиҷаҳо" тавсиф шудааст. Пеш аз ҳама, дар он гуфта мешавад, ки ResultSet усулҳои дарёфт ва коркарди натиҷаҳои дархостҳои иҷрошударо пешниҳод мекунад. Яъне, агар усули иҷро ба мо дуруст баргардад, мо метавонем 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: Истифодаи an objectҳои RowSet ". Вариантҳои гуногуни истифода вуҷуд доранд. Масалан, соддатарин ҳолат метавонад чунин бошад:
@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 ба симбиози изҳорот (мо фармонро тавассути он нишон додем) ва фармони иҷрошуда монанд аст. Тавассути он мо курсорро идора мекунем (бо даъвати усули навбатӣ) ва аз он маълумот мегирем. На танҳо ин равиш ҷолиб аст, балки татбиқи имконпазир низ мебошад. Масалан, CachedRowSet. Он "кандашуда" аст (яъне он пайвасти доимиро ба пойгоҳи додаҳо истифода намебарад) ва ҳамоҳангсозии возеҳро бо пойгоҳи додаҳо талаб мекунад:
CachedRowSet jdbcRsCached = new CachedRowSetImpl();
jdbcRsCached.acceptChanges(connection);
Шумо метавонед бештар дар дастури вебсайти Oracle хонед: " Истифодаи CachedRowSetObjects ".
JDBC ё дар куҷо ҳамааш оғоз мешавад - 8

Метамаълумот

Илова ба дархостҳо, пайвастшавӣ ба пойгоҳи додаҳо (яъне, намунаи синфи Пайвастшавӣ) дастрасӣ ба метамаълумотро таъмин мекунад - маълумот дар бораи чӣ гуна конфигуратсия ва ташкor махзани мо. Аммо аввал, биёед якчанд нуктаҳои асосиро қайд кунем: URL барои пайвастшавӣ ба базаи мо: "jdbc:h2:mem:test". тест номи базаи мост. Барои API JDBC, ин директория аст. Ва ном бо ҳарфи калон хоҳад буд, яъне TEST. Схемаи пешфарз барои H2 PUBLIC аст. Акнун биёед санҷишеро нависед, ки ҳамаи ҷадвалҳои корбарро нишон медиҳад. Чаро одат? Чунки базаи маълумотҳо на танҳо ҷадвалҳои корбаронро (онҳоеро, ки мо худамон бо истифодаи ифодаҳои ҷадвал офаридаем), балки ҷадвалҳои системавӣ низ дар бар мегиранд. Онҳо барои нигоҳ доштани маълумоти система дар бораи сохтори пойгоҳи додаҳо заруранд. Ҳар як базаи маълумот метавонад чунин ҷадвалҳои системаро ба таври гуногун нигоҳ дорад. Масалан, дар 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 Ҳавзи пайвастшавӣ" мебошад. Он инчунин асоснокии асосии зарурати ҳавзи пайвастро пешниҳод мекунад. Ҳар як Coonection пайвасти ҷисмонӣ ба пойгоҳи додаҳо мебошад. Таъсис ва бастани он кори хеле «гарон» аст. JDBC танҳо API-и пайвасткуниро таъмин мекунад. Аз ин рӯ, интихоби амалӣ аз они мо боқӣ мемонад. Масалан, чунин татбиқҳо HikariCP ро дар бар мегиранд . Бинобар ин, мо бояд ба вобастагии лоиҳаи худ ҳавз илова кунем:
dependencies {
    implementation 'com.h2database:h2:1.4.197'
    implementation 'com.zaxxer:HikariCP:3.3.1'
    testImplementation 'junit:junit:4.12'
}
Акнун мо бояд ин ҳавзро бо ягон роҳ истифода барем. Барои ин ба шумо лозим аст, ки манбаи маълумотро оғоз кунед, ки ҳамчун манбаи маълумот низ маълум аст:
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 транзаксия кай оғоз мешавад? Тавре ки дар мушаххасот гуфта мешавад, ин бевосита аз ҷониби Driver JDBC идора карда мешавад. Аммо одатан, амалиёти нав вақте оғоз мешавад, ки изҳороти кунунии SQL транзаксияро талаб мекунад ва транзаксия ҳанӯз сохта нашудааст. Муомилот кай ба охир мерасад? Ин аз ҷониби атрибути худкоркунӣ назорат карда мешавад. Агар autocommit фаъол бошад, транзаксия пас аз "анҷоми" изҳороти SQL анҷом мешавад. Маънои "иҷрошуда" аз намуди ифодаи SQL вобаста аст:
  • Забони коркарди маълумот, ки бо номи DML маълум аст (Insert, Update, Delete)
    Амалиёт бо анҷоми амал анҷом дода мешавад.
  • Изҳоротҳоро интихоб кунед
    Амалиёт ҳангоми баста шудани ResultSet анҷом мешавад ( ResultSet#close )
  • CallableStatement ва ифодаҳое, ки натиҷаҳои сершуморро бармегардонанд
    Вақте ки ҳамаи ResultSets алоқаманд баста шудаанд ва ҳама баромадҳо гирифта шудаанд (аз ҷумла шумораи навсозиҳо)
Маҳз ҳамин тавр API JDBC рафтор мекунад. Мисли маъмул, биёед барои ин санҷиш нависед:
@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

Сатҳи изолятсия

Биёед зерфасли "10.2 Сатҳи изолятсияи транзаксия" -и мушаххасоти JDBC -ро кушоем. Дар ин ҷо, пеш аз гузаштан, ман мехоҳам дар бораи чунин чизе ба монанди ACID ёдовар шавам. ACID талаботро барои системаи транзаксионӣ тавсиф мекунад.
  • Atomicity:
    Ягон транзаксия қисман ба система анҷом дода намешавад. Ё ҳамаи зерамалҳои он иҷро мешаванд, ё ҳеҷ кадоме иҷро намешаванд.
  • Пайвастагӣ:
    Ҳар як амалиёти муваффақ, тибқи таъриф, танҳо натиҷаҳои дурустро сабт мекунад.
  • Ҷудокунӣ:
    Ҳангоми иҷро шудани транзаксия, транзаксияҳои ҳамзамон набояд ба натиҷаи он таъсир расонанд.
  • Давомнокӣ:
    Агар транзаксия бомуваффақият анҷом дода шавад, тағиротҳои ба он воридшуда бо сабаби ягон нокомӣ бекор карда намешаванд.
Ҳангоми сухан дар бораи сатҳи изолятсияи транзаксия, мо дар бораи талаботи "ҷудокунӣ" сухан меронем. Ҷудокунӣ як талаботи гаронбаҳост, аз ин рӯ дар пойгоҳи додаҳои воқеӣ режимҳое мавҷуданд, ки транзаксияро комилан ҷудо намекунанд (сатҳи изолятсияи Хониши такрорӣ ва пасттар). Википедиа дорои шарҳи аълои мушкилотест, ки ҳангоми кор бо транзаксияҳо метавонанд ба миён оянд. Дар ин ҷо бештар хондан меарзад: " Мушкилоти дастрасии мувозӣ бо истифода аз транзаксияҳо ." Пеш аз навиштани санҷиши худ, биёед скрипти Gradle Build-ро каме тағир диҳем: блокро бо хосиятҳо, яъне бо танзимоти лоиҳаи худ илова кунед:
ext {
    h2Version = '1.3.176' // 1.4.177
    hikariVersion = '3.3.1'
    junitVersion = '4.12'
}
Баъдан, мо инро дар versionҳо истифода мебарем:
dependencies {
    implementation "com.h2database:h2:${h2Version}"
    implementation "com.zaxxer:HikariCP:${hikariVersion}"
    testImplementation "junit:junit:${junitVersion}"
}
Шумо шояд пай бурда бошед, ки versionи 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). Ва сатҳи транзаксия метавонад танҳо кор накунад. Дар хотир доред, ки мо versionи драйвери пойгоҳи додаҳои H2-ро нишон дода будем? Агар мо онро ба h2Version = '1.4.177' ва болотар бардорем, он гоҳ READ UNCOMMITTED кор намекунад, гарчанде ки мо codeро тағир надодаем. Ин бори дигар исбот мекунад, ки интихоби фурӯшанда ва versionи драйвер на танҳо ҳарфҳо, балки он воқеан муайян мекунад, ки дархостҳои шумо чӣ гуна иҷро мешаванд. Шумо метавонед дар бораи чӣ гуна ислоҳ кардани ин рафтор дар versionи 1.4.177 ва чӣ гуна он дар versionҳои баландтар кор намекунад, дар инҷо хонед: " Дастгирии READ UNCOMMITTED сатҳи изолятсия дар реҷаи MVStore ".
JDBC ё дар куҷо ҳамааш оғоз мешавад - 12

Хатти поён

Тавре ки мо мебинем, JDBC як воситаи пурқувват дар дасти Java барои кор бо пойгоҳи додаҳо мебошад. Умедворам, ки ин баррасии кӯтоҳ ба шумо нуқтаи ибтидоӣ медиҳад ё ба тоза кардани хотираатон кӯмак мекунад. Хуб, барои хӯрокхӯрӣ, баъзе маводи иловагӣ: #Вячеслав
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION