JavaRush /Kurslar /All lectures for UZ purposes /JDBC amallarini SimpleJdbc klasslari yordamida soddalasht...

JDBC amallarini SimpleJdbc klasslari yordamida soddalashtirish

All lectures for UZ purposes
Daraja, Dars
Mavjud

SimpleJdbcInsert va SimpleJdbcCall klasslari metama'lumotlar orqali konfiguratsiyani soddalashtiradi, bu JDBC driver orqali olinishi mumkin. Ya'ni sozlash ishlari kamroq bo'ladi, ammo agar xohlasangiz, metama'lumotlar ishlovini o'zgartirib yoki o'chirish mumkin.

SimpleJdbcInsert yordamida ma'lumotlarni kiritish

Keling, minimal konfiguratsiyaga ega SimpleJdbcInsert klassidan boshlaymiz. SimpleJdbcInsert namunasi ma'lumotlarga kirish darajasida yaratiladi. Bu misolda setDataSource metodi ushbu boshqaruvchi sifatida ishlatilgan. SimpleJdbcInsert uchun subklass yaratish shart emas. Uning o'rniga yangi namuna yaratish va withTableName metodi orqali jadval nomini belgilash yetarli. Ushbu klass konfiguratsion metodlar fluid uslubida bo'lib, SimpleJdbcInsert namunasi qaytariladi va bu konfiguratsion metodlarni zanjirlash imkonini beradi. Quyida bir misol keltirilgan:

Java
public class JdbcActorDao implements ActorDao {
    private SimpleJdbcInsert insertActor;
    public void setDataSource(DataSource dataSource) {
        this.insertActor = new SimpleJdbcInsert(dataSource).withTableName("t_actor");
    }
    public void add(Actor actor) {
        Map<String, Object> parameters = new HashMap<String, Object>(3);
        parameters.put("id", actor.getId());
        parameters.put("first_name", actor.getFirstName());
        parameters.put("last_name", actor.getLastName());
        insertActor.execute(parameters);
    }
    // ... qo'shimcha metodlar
}
Kotlin
class JdbcActorDao(dataSource: DataSource) : ActorDao {
    private val insertActor = SimpleJdbcInsert(dataSource).withTableName("t_actor")
    fun add(actor: Actor) {
        val parameters = mutableMapOf<String, Any>()
        parameters["id"] = actor.id
        parameters["first_name"] = actor.firstName
        parameters["last_name"] = actor.lastName
        insertActor.execute(parameters)
    }
    // ... qo'shimcha metodlar
}

Bu erda ishlatiladigan execute metodi yagona parametr sifatida oddiy java.util.Map ni qabul qiladi. Muhimi, Map uchun ishlatiladigan kalitlar bazada qanday belgilangani bilan jadval ustunlari nomlariga mos kelishi kerak, chunki metama'lumotlar insert instruktsiyasini yaratishda foydalaniladi.

SimpleJdbcInsert yordamida avtomatik yaratilgan kalitlarni olish

Quyidagi misolda avvalgi misolga o'xshash insert mavjud, lekin id ni o'tkazish o'rniga u avtomatik yaratilgan kalitni olish va uni yangi Actor ob'ektiga o'rnatadi. SimpleJdbcInsert yaratilganda, jadval nomini ko'rsatishdan tashqari, uni usingGeneratedKeyColumns metodi yordamida yaratilgan kalit ustuni nomi belgilangan bo'ladi. Quyidagi ro'yxat bu jarayonni ko'rsatadi:

Java
public class JdbcActorDao implements ActorDao {
    private SimpleJdbcInsert insertActor;
    public void setDataSource(DataSource dataSource) {
        this.insertActor = new SimpleJdbcInsert(dataSource)
                .withTableName("t_actor")
                .usingGeneratedKeyColumns("id");
    }
    public void add(Actor actor) {
        Map<String, Object> parameters = new HashMap<String, Object>(2);
        parameters.put("first_name", actor.getFirstName());
        parameters.put("last_name", actor.getLastName());
        Number newId = insertActor.executeAndReturnKey(parameters);
        actor.setId(newId.longValue());
    }
    // ... qo'shimcha metodlar
}
Kotlin
class JdbcActorDao(dataSource: DataSource) : ActorDao {
    private val insertActor = SimpleJdbcInsert(dataSource)
            .withTableName("t_actor").usingGeneratedKeyColumns("id")
    fun add(actor: Actor): Actor {
        val parameters = mapOf(
                "first_name" to actor.firstName,
                "last_name" to actor.lastName)
        val newId = insertActor.executeAndReturnKey(parameters);
        return actor.copy(id = newId.toLong())
    }
    // ... qo'shimcha metodlar
}

Ikkinchi uslub yordamida injectni amalga oshirishning asosiy farqi shundaki, siz id ni Map ga qo'shmaysiz, balki executeAndReturnKey metodini chaqirasiz. Bu java.lang.Number ob'ektini qaytaradi, yordamida siz domen klassida foydalaniladigan raqamli turdagi misleading yaratishingiz mumkin. Bu erda barcha bazalar Java klassini qaytarishini kutmaslik kerak. java.lang.Number butunlay foydalanish mumkin bo'lgan klassdir. Agar bir nechta avtomatik yaratilgan ustunlar mavjud bo'lsa yoki yaratilgan qiymatlar raqamli bo'lmasa, KeyHolder dan foydalanish mumkin, bu executeAndReturnKeyHolder metod bilan qaytariladi.

SimpleJdbcInsert uchun ustunlarni belgilash

usingColumns metodini ishlatib, qanday ustunlarni qo'shishni cheklash mumkin, quyida keltirilgan:

Java
public class JdbcActorDao implements ActorDao {
    private SimpleJdbcInsert insertActor;
    public void setDataSource(DataSource dataSource) {
        this.insertActor = new SimpleJdbcInsert(dataSource)
                .withTableName("t_actor")
                .usingColumns("first_name", "last_name")
                .usingGeneratedKeyColumns("id");
    }
    public void add(Actor actor) {
        Map<String, Object> parameters = new HashMap<String, Object>(2);
        parameters.put("first_name", actor.getFirstName());
        parameters.put("last_name", actor.getLastName());
        Number newId = insertActor.executeAndReturnKey(parameters);
        actor.setId(newId.longValue());
    }
    // ... qo'shimcha metodlar
}
Kotlin
class JdbcActorDao(dataSource: DataSource) : ActorDao {
    private val insertActor = SimpleJdbcInsert(dataSource)
            .withTableName("t_actor")
            .usingColumns("first_name", "last_name")
            .usingGeneratedKeyColumns("id")
    fun add(actor: Actor): Actor {
        val parameters = mapOf(
                "first_name" to actor.firstName,
                "last_name" to actor.lastName)
        val newId = insertActor.executeAndReturnKey(parameters);
        return actor.copy(id = newId.toLong())
    }
    // ... qo'shimcha metodlar
}

Vazifani bajarish metama'lumotlar yordamida qaysi ustunlardan foydalanilishini belgilash bilan amalga oshirilayotganidek amalga oshiriladi.

Parametr qiymatlarini belgilash uchun SqlParameterSource dan foydalanish

Parametr qiymatlarini belgilash uchun Map dan foydalanish juda yaxshi ishlaydi, lekin bu eng qulay klass emas. Spring interfacening bir nechta SqlParameterSource implementatsiyalarini o'z ichiga oladi, ularni Map o'rniga ishlatish mumkin. Birinchi BeanPropertySqlParameterSource - bu juda qulay klass, agar sizda JavaBean-compatible klass bo'lsa, bu sizning qiymatlaringizni o'z ichiga oladi. U tegishli getter orqali parametr qiymatlarini oladi. Quyidagi misol BeanPropertySqlParameterSource ni qanday ishlatishni ko'rsatadi:

Java
public class JdbcActorDao implements ActorDao {
    private SimpleJdbcInsert insertActor;
    public void setDataSource(DataSource dataSource) {
        this.insertActor = new SimpleJdbcInsert(dataSource)
                .withTableName("t_actor")
                .usingGeneratedKeyColumns("id");
    }
    public void add(Actor actor) {
        SqlParameterSource parameters = new BeanPropertySqlParameterSource(actor);
        Number newId = insertActor.executeAndReturnKey(parameters);
        actor.setId(newId.longValue());
    }
    // ... qo'shimcha metodlar
}
Kotlin
class JdbcActorDao(dataSource: DataSource) : ActorDao {
    private val insertActor = SimpleJdbcInsert(dataSource)
            .withTableName("t_actor")
            .usingGeneratedKeyColumns("id")
    fun add(actor: Actor): Actor {
        val parameters = BeanPropertySqlParameterSource(actor)
        val newId = insertActor.executeAndReturnKey(parameters)
        return actor.copy(id = newId.toLong())
    }
    // ... qo'shimcha metodlar
}

Boshqa bir variant MapSqlParameterSource bo'lib, bu Map ga o'xshaydi, lekin bu birlashtirilgan addValue metodiga ega. Quyidagi misol qanday ishlatilishini ko'rsatadi:

Java
public class JdbcActorDao implements ActorDao {
    private SimpleJdbcInsert insertActor;
    public void setDataSource(DataSource dataSource) {
        this.insertActor = new SimpleJdbcInsert(dataSource)
                .withTableName("t_actor")
                .usingGeneratedKeyColumns("id");
    }
    public void add(Actor actor) {
        SqlParameterSource parameters = new MapSqlParameterSource()
                .addValue("first_name", actor.getFirstName())
                .addValue("last_name", actor.getLastName());
        Number newId = insertActor.executeAndReturnKey(parameters);
        actor.setId(newId.longValue());
    }
    // ... qo'shimcha metodlar
}
Kotlin
class JdbcActorDao(dataSource: DataSource) : ActorDao {
    private val insertActor = SimpleJdbcInsert(dataSource)
            .withTableName("t_actor")
            .usingGeneratedKeyColumns("id")
    fun add(actor: Actor): Actor {
        val parameters = MapSqlParameterSource()
                    .addValue("first_name", actor.firstName)
                    .addValue("last_name", actor.lastName)
        val newId = insertActor.executeAndReturnKey(parameters)
        return actor.copy(id = newId.toLong())
    }
    // ... qo'shimча metodlar
}

Ko'rib turganingizdek, konfiguratsiya bir xil. Ushbu alternativ kirish sinflaridan foydalanish uchun faqat bajarilayotgan kodni o'zgartirish kerak.

SimpleJdbcCall yordamida saqlangan protsedurani chaqirish

SimpleJdbcCall klassi bazadagi metama'lumotlarni IN va OUT parametrlarning nomlarini olish uchun ishlatadi, shuning uchun ularni qo'lda e'lon qilish shart emas. Agar xohlasangiz, parametrlarni e'lon qilishingiz mumkin yoki (masalan, ARRAY yoki STRUCT) ba'zi parametrlar bo'lsa, ular Java klassiga avtomatik ravishda xaritalanmaydi. Birinchi misolda faqat skalyariya qiymatlarni qaytaradigan MySQL bazasidagi oddiy protsedura keltirilgan. Protsedura ko'rsatilgan aktyor yozuvini o'qiydi va first_name, last_name va birth_date ustunlarini OUT parametr sifatida qaytaradi. Quyidagi ro'yxatda so'nggi misol keltirilgan:

CREATE PROCEDURE read_actor (
    IN in_id INTEGER,
    OUT out_first_name VARCHAR(100),
    OUT out_last_name VARCHAR(100),
    OUT out_birth_date DATE)
BEGIN
    SELECT first_name, last_name, birth_date
    INTO out_first_name, out_last_name, out_birth_date
    FROM t_actor where id = in_id;
END;

in_id parametri qidirilayotgan aktyorning id sini o‘z ichiga oladi. OUT parametrlari jadvaldan olingan ma’lumotlarni qaytaradi.

SimpleJdbcInsert ni e'lon qilishni SimpleJdbcInsert ni e'lon qilish bilan bir xil usulda e'lon qilish mumkin. Sizning ma'lumotlarga kirish darajangizni boshlang'ich metodda klass yaratiladi va o’rnatiladi. StoredProcedure klassiga nisbatan, siz hech qanday subklass yaratishingiz shart emas va amaldagi protseduradagi ob'ektlarga qanday murojaat qilish kerakligini aniqlash uchun metama'lumotlar izlashini e'lon qilishingiz shart emas. Quyidagi SimpleJdbcCall konfiguratsiyasi misolda keltirilgan saqlangan protseduradan foydalanadi (DataSource dan tashqari kiritilgan yagona konfiguratsiya parametri saqlangan protseduraning nomidir):

Java
public class JdbcActorDao implements ActorDao {
    private SimpleJdbcCall procReadActor;
    public void setDataSource(DataSource dataSource) {
        this.procReadActor = new SimpleJdbcCall(dataSource)
                .withProcedureName("read_actor");
    }
    public Actor readActor(Long id) {
        SqlParameterSource in = new MapSqlParameterSource()
                .addValue("in_id", id);
        Map out = procReadActor.execute(in);
        Actor actor = new Actor();
        actor.setId(id);
        actor.setFirstName((String) out.get("out_first_name"));
        actor.setLastName((String) out.get("out_last_name"));
        actor.setBirthDate((Date) out.get("out_birth_date"));
        return actor;
    }
    // ... qo'shimcha metodlar
}
Kotlin
class JdbcActorDao(dataSource: DataSource) : ActorDao {
    private val procReadActor = SimpleJdbcCall(dataSource)
            .withProcedureName("read_actor")
    fun readActor(id: Long): Actor {
        val source = MapSqlParameterSource().addValue("in_id", id)
        val output = procReadActor.execute(source)
        return Actor(
                id,
                output["out_first_name"] as String,
                output["out_last_name"] as String,
                output["out_birth_date"] as Date)
    }
        // ... qo'shimcha metodlar
}

execute metodini bajarish uchun yozadigan kod, IN parametrini o'z ichiga olgan SqlParameterSource ni yaratishni o'z ichiga oladi. IN qiymati uchun nomni e'lon qilingan parametr nomi bilan muvofiqlashtirish kerak. Harf kattaligi mos kelishi shart emas, chunki siz protsedurada bazadagi ob'ektlarga qanday murojaat qilish kerakligini bilish uchun metama'lumotlardan foydalanasiz. Protsedura manbai bo'yicha bu bazada qanday saqlanganiga to'g'ri kelmasligi mumkin. Ba'zi bazalar nomlarni katta harfga aylantiradi, boshqalari esa kichik harfda yoki kiritilgan kabi saqlaydi.

execute metod IN parametrlari va OUT parametrlari bo'lgan Map ni qaytaradi, OUT parametrlari saqlangan protsedurada e'lon qilingan nomlar bilan bog'liq. Bu holda out_first_name, out_last_name va out_birth_date.

execute metodi oxirgi qismi olinadigan ma'lumotlar uchun Actor namunasi yaratadi. Yana bir bor, OUT parametrlari nomlarini saqlangan protsedurada qanday berilgan bo'lsa, shunday ishlatish muhimdir. OUT parametrlari, Map'da saqlangan OUT parametrlari nomlari harf kattaligi, bazadagi OUT parametrlari nomlari harf kattaligiga mos keladi, ba'zi bazalarda harfni boshqacha saqlashi mumkin. Kodni platforma bo'ylab mustaqil qilish uchun, harf kattaligini e'tiborsiz qidiruvni bajaring yoki Springni LinkedCaseInsensitiveMap dan foydalanishga buyuring. So'nggi uchun, o'z JdbcTemplate ni yarating va setResultsMapCaseInsensitive xususiyatini true qilib o'rnating. So'ngra bu tayyorlangan JdbcTemplate namunasini SimpleJdbcCall yaratishda foydalanishingiz mumkin. Quyidagi misolda bu konfiguratsiya ko'rsatilgan:

Java
public class JdbcActorDao implements ActorDao {
    private SimpleJdbcCall procReadActor;
    public void setDataSource(DataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.setResultsMapCaseInsensitive(true);
        this.procReadActor = new SimpleJdbcCall(jdbcTemplate)
                .withProcedureName("read_actor");
    }
    // ... qo'shimcha metodlar
}
Kotlin
class JdbcActorDao(dataSource: DataSource) : ActorDao {
    private var procReadActor = SimpleJdbcCall(JdbcTemplate(dataSource).apply {
        isResultsMapCaseInsensitive = true
    }).withProcedureName("read_actor")
    // ... qo'shimcha metodlar
}

Bu harakatni amalga oshirish bilan, qaytarilayotgan parametrlarning nomlari uchun ishlatiladigan harf kattaligi muammolaridan qochasiz.

SimpleJdbcCall dan foydalanish uchun parametrlarni aniq belgilash

Ushbu bobda biz parametrlar qanday metama'lumotlardan chiqib ketilganini muhokama qilgan edik, lekin agar xohlasangiz, ularni aniq belgilashingiz mumkin. Buni SqlParameter ob'ektlarning o'zgaruvchan miqdorini qabul qiluvchi declareParameters metodini ishlatib, SimpleJdbcCall ni yaratish va konfiguratsiya qilish orqali amalga oshirishingiz mumkin. SqlParameter ni qanday aniqlash haqida ko'proq ma'lumot olish uchun quyidagi bo'limni ko'ring.

Ochiq e'lon Spring tomonidan qo'llab-quvvatlanadigan bo'lmagan bazaga ishlatilgan bo'lsa, kerak bo'ladi. Hozirgi vaqtda Spring, Apache Derby, DB2, MySQL, Microsoft SQL Server, Oracle va Sybase uchun saqlangan protsedura chaqirishda metama'lumotlarni qidirishni qo'llab-quvvatlaydi. Biz shuningdek, MySQL, Microsoft SQL Server va Oracle saqlangan funksiyalar uchun metama'lumotlarni qidirishni qo'llab-quvvatlaymiz.

Bir, bir necha yoki barcha parametrlarni aniq e'lon qilishingiz mumkin. Agar parametrlar aniq e'lon qilinmagan bo'lsa, metama'lumotlar ularga ishlov berishda foydalaniladi. Potensial parametrlar uchun barcha metama'lumotlarni qidirish jarayonini atrofidan o'tib, faqat aniq belgilangan parametrlarni ishlatish uchun withoutProcedureColumnMetaDataAccess metodini deklaratsiya qismida chaqirilishi mumkin. Agar bir nechta yoki bir nechta chaqirilish signaturlari bo'lsa, unda useInParameterNames bir signal uchun o'z ichiga olgan IN parametr nomlarini ko'rsatish uchun chaqiriladi.

Quyidagi misolda protsedura chaqiruvining to'liq e'lon qilingan versiyasi va avvalgi misoldan olingan ma'lumotlar ko'rsatilgan:

Java
public class JdbcActorDao implements ActorDao {
    private SimpleJdbcCall procReadActor;
    public void setDataSource(DataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.setResultsMapCaseInsensitive(true);
        this.procReadActor = new SimpleJdbcCall(jdbcTemplate)
                .withProcedureName("read_actor")
                .withoutProcedureColumnMetaDataAccess()
                .useInParameterNames("in_id")
                .declareParameters(
                        new SqlParameter("in_id", Types.NUMERIC),
                        new SqlOutParameter("out_first_name", Types.VARCHAR),
                        new SqlOutParameter("out_last_name", Types.VARCHAR),
                        new SqlOutParameter("out_birth_date", Types.DATE)
                );
    }
    // ... qo'shimcha metodlar
}
Kotlin
class JdbcActorDao(dataSource: DataSource) : ActorDao {
        private val procReadActor = SimpleJdbcCall(JdbcTemplate(dataSource).apply {
            isResultsMapCaseInsensitive = true
        }).withProcedureName("read_actor")
                .withoutProcedureColumnMetaDataAccess()
                .useInParameterNames("in_id")
                .declareParameters(
                        SqlParameter("in_id", Types.NUMERIC),
                        SqlOutParameter("out_first_name", Types.VARCHAR),
                        SqlOutParameter("out_last_name", Types.VARCHAR),
                        SqlOutParameter("out_birth_date", Types.DATE)
    )
        // ... qo'shimcha metodlar
}

Ushbu ikki misolda bajarilish va yakuniy natijalar bir xil. Ikkinchi misolda, barcha ma'lumotlar aniq ko'rsatilgan, metama'lumotlarni ishlatib emas.

SqlParameters ni aniqlash usullari

SimpleJdbc klasslari uchun, hamda ma'lumotlar bazasi amallari uchun SqlParameter yoki uning subklasslaridan birini foydalanishingiz mumkin (bu "JDBC amallarini Java ob'ektlari sifatida modeling" bo'limida ko'rib chiqilgan). Buning uchun asosan parametr nomi va SQL turini konstruktor orqali ko'rsatiladi. SQL turi java.sql.Types konstantalari yordamida belgilanadi. Bu bobda avval ko'rilgan deklaratsiyalar quyidagilarga o'xshaydi:

Java
new SqlParameter("in_id", Types.NUMERIC),
new SqlOutParameter("out_first_name", Types.VARCHAR),
Kotlin
SqlParameter("in_id", Types.NUMERIC),
SqlOutParameter("out_first_name", Types.VARCHAR),

Birinchi qator SqlParameter bilan IN parametrni bildiradi. Siz IN parametrlarni saqlangan protsedura chaqiruvlari va SqlQuery va uning subklasslari yordamida so'rovlar uchun ishlatishingiz mumkin (bu "SqlQuery haqida asosiy ma'lumotlar" bo'limida ko'rib chiqilgan)."

Ikkinchi qator, SqlOutParameter bilan, saqlangan protsedura chaqiruvlarida foydalanish uchun OUT parametrni bildiradi. Shuningdek, InOut parametrlar (InOut parametrlari bo'lgan, protsetura uchun IN qiymatini taqdim etuvchi va qaytaradigan qiymatni qaytaradigan) uchun SqlInOutParameter mavjud.

Faqat SqlParameter va SqlInOutParameter sifatida e'lon qilingan parametrlar qiymatlarini kiritish uchun ishlatiladi. Bu farqli o'laroq StoredProcedure klassdan kelib chiqadi, u (orqaga moslik sabablari tufayli) SqlOutParameter sifatida e'lon qilingan parametrlar uchun qiymatlarni kiritishga imkon beradi.

IN parametrlar uchun, parametr nomi va SQL turi bilan bir qatorda, o'lchamni raqamli ma'lumotlar uchun yoki maxsus ishlab chiqilgan ma'lumotlar bazasi turlari uchun typename ni ko'rsatish mumkin. OUT parametrlari uchun, Ref cursor dan qaytarilgan qatorlarni karta qilish uchun RowMapper ni ko'rsatish mumkin. Yana bir variant - SqlReturnType ni belgilash, bu qaytarilgan qiymatlarga individual ishlov berishga imkon beradi.

SimpleJdbcCall yordamida saqlangan funktsiyani chaqirish

Saqlangan funktsiyani chaqirish saqlangan protsedurani chaqirishga juda o'xshash, faqat protseduraning nomi o'rniga funktsiyaning nomini ko'rsatasiz. withFunctionName metodi konfiguratsiyaning qismi sifatida ishlatilib, funktsiyani chaqirish kerakligini ko'rsatadi, shundan so'ng funktsiyani chaqirish uchun tegishli sozlama qatori yaratiladi. Funktsiyani bajarish uchun (executeFunction) maxsus chaqiruv ishlatiladi, u funktsiyaning qaytariladigan qiymatini belgilangan turdagi ob'ekt sifatida qaytaradi, ya'ni qaytariladigan qiymatni natijaviy Map'dan olish shart emas. Bir xil yordamchi metod (nomi executeObject) faqat bitta OUT parametri bo'lgan saqlangan protseduralar uchun ham mavjud. Quyidagi misol (MySQL uchun) get_actor_name nomli saqlangan funktsiyaga asoslanib, aktyorning to'liq ismini qaytaradi:

CREATE FUNCTION get_actor_name (in_id INTEGER)
RETURNS VARCHAR(200) READS SQL DATA
BEGIN
    DECLARE out_name VARCHAR(200);
    SELECT concat(first_name, ' ', last_name)
        INTO out_name
        FROM t_actor where id = in_id;
    RETURN out_name;
END;

Ushbu funktsiyani chaqirish uchun, biz yana SimpleJdbcCall ni boshlang‘ich metodda yaratamiz, quyidagi misolda ko‘rsatilgani kabi:

Java
public class JdbcActorDao implements ActorDao {
    private SimpleJdbcCall funcGetActorName;
    public void setDataSource(DataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.setResultsMapCaseInsensitive(true);
        this.funcGetActorName = new SimpleJdbcCall(jdbcTemplate)
                .withFunctionName("get_actor_name");
    }
    public String getActorName(Long id) {
        SqlParameterSource in = new MapSqlParameterSource()
                .addValue("in_id", id);
        String name = funcGetActorName.executeFunction(String.class, in);
        return name;
    }
    // ... qo'shimcha metodlar
}
Kotlin
class JdbcActorDao(dataSource: DataSource) : ActorDao {
    private val jdbcTemplate = JdbcTemplate(dataSource).apply {
        isResultsMapCaseInsensitive = true
    }
    private val funcGetActorName = SimpleJdbcCall(jdbcTemplate)
            .withFunctionName("get_actor_name")
    fun getActorName(id: Long): String {
        val source = MapSqlParameterSource().addValue("in_id", id)
        return funcGetActorName.executeFunction(String::class.java, source)
    }
    // ... qo'shimcha metodlar
}

Foydalanilgan executeFunction metodi String ni qaytaradi, bu funktsiya chaqirilishidan qaytarilgan qiymatni o'z ichiga oladi.

SimpleJdbcCall ob'ektidan ResultSet yoki REF kursori qaytarilishi

Result set qaytaradigan saqlangan protsedura yoki funktsiyani chaqirish biroz murakkab vazifa. Ba'zi ma'lumotlar bazalari JDBC ishlovini bajarish paytida result set qaytaradi, boshqalari esa aniq out parametri talab qiladi. Ikkala yondashuv ham natijalarni qator-qatoriga aylantirish va qaytarilgan qatorlarni ishlashni talab qiladi. SimpleJdbcCall yordamida returningResultSet metodini ishlatib, parametr uchun ishlatiladigan RowMapper implementatsiyasini e'lon qilishingiz mumkin. Agar natijalar result set qaytarilishini qayta ishlash paytida qaytarilsa, ismlar ko'rsatilmaydi, shuning uchun qaytarilgan natijalar RowMapper implementatsiyalari e'lon qilingan tartibda mos kelishi kerak. Belgilangan nom natijaviy Map ning qaytarilgan listida ishlov berilgan natijani saqlash uchun ishlatiladi.

MySQL uchun quyidagi misolda hech qanday IN parametrlarni qabul qilmaydigan va t_actor jadvalidan barcha qatorlarni qaytaradigan saqlangan protsedura ishlatilgan:

CREATE PROCEDURE read_all_actors()
BEGIN
 SELECT a.id, a.first_name, a.last_name, a.birth_date FROM t_actor a;
END;

Ushbu protsedurani chaqirish uchun RowMapper ni e'lon qilish mumkin. Xaritalashni xohlagan klass JavaBean qoidalariga amal qilgani uchun, siz kursga moslash uchun zarur bo'lgan klassni newInstance metodiga o'tkazish orqali yaratilgan BeanPropertyRowMapper dan foydalanishingiz mumkin. Quyidagi misol buni qanday qilishni ko'rsatadi:

Java
public class JdbcActorDao implements ActorDao {
    private SimpleJdbcCall procReadAllActors;
    public void setDataSource(DataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.setResultsMapCaseInsensitive(true);
        this.procReadAllActors = new SimpleJdbcCall(jdbcTemplate)
                .withProcedureName("read_all_actors")
                .returningResultSet("actors",
                BeanPropertyRowMapper.newInstance(Actor.class));
    }
    public List getActorsList() {
        Map m = procReadAllActors.execute(new HashMap<String, Object>(0));
        return (List) m.get("actors");
    }
    // ... qo'shimcha metodlar
}
Kotlin
class JdbcActorDao(dataSource: DataSource) : ActorDao {
        private val procReadAllActors = SimpleJdbcCall(JdbcTemplate(dataSource).apply {
            isResultsMapCaseInsensitive = true
        }).withProcedureName("read_all_actors")
                .returningResultSet("actors",
                        BeanPropertyRowMapper.newInstance(Actor::class.java))
    fun getActorsList(): List<Actor> {
        val m = procReadAllActors.execute(mapOf<String, Any>())
        return m["actors"] as List<Actor>
    }
    // ... qo'shimcha metodlar
}

execute chaqiruvi hamda xatto Map ni olishda foydalaniladi, chunki bu chaqiruv hech qanday parametrlarni qabul qilmaydi. So'ngra aktyorlar ro'yxati natijaviy Map'dan olinib, chaqiruv kodiga qaytariladi.

Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION