日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

1 前言

ObjectiveSQL 是一個(gè)JAVA ORM 框架,它不僅是Active Record 模式在Java 中的應(yīng)用,同時(shí)還針對復(fù)雜SQL 編程提供近乎完美的解決方案,使得Java 代碼與SQL 語句有機(jī)的結(jié)合,改變了傳統(tǒng)SQL 的編程模型(以字符串拼接為主的編程模型)。

ObjectiveSQL 項(xiàng)目分為兩部分:一部分是運(yùn)行期Maven 依賴 objective-sql 或 objsql-springboot,主要實(shí)現(xiàn)了基礎(chǔ)的ORM 特性和SQL 編程模型,另一部分是IntelliJ IDEA 插件,兼容Java 運(yùn)算符重載和動(dòng)態(tài)代碼提示。

java開發(fā)之Java ORM 框架推薦

 

ObjectiveSQL 主要解決:

  • 動(dòng)態(tài)代碼生成:基于領(lǐng)域模型(Domain Model),自動(dòng)生成簡單SQL 編程代碼,使應(yīng)用系統(tǒng)開發(fā)只關(guān)注自身的業(yè)務(wù)特性,提升開發(fā)效率
  • 可編程SQL:將SQL 中的控制原語、謂詞、函數(shù)以及過程化邏輯等抽象為Java 中的高級(jí)類型,與Java 融為一體,使得SQL 成為真正過程化、邏輯型編程語言,可封裝、可復(fù)用以及單元測試
  • 表達(dá)式語法一致性:Java 語法與SQL 語法等價(jià)替換,包括:數(shù)學(xué)計(jì)算、函數(shù)調(diào)用、比較與邏輯計(jì)算表達(dá)式,Java 表達(dá)式可以直接轉(zhuǎn)換為SQL 表達(dá)式。

2 依賴安裝

2.1 IntelliJ IDEA 插件安裝

Preferences/Settings -> Plugins -> Search with "ObjectiveSql" in market -> Install

2.2 Maven 集成

獨(dú)立應(yīng)用程序,請將下列代碼添加至dependencies:

<!-- In standalone -->
<dependency>
    <groupId>com.github.braisdom</groupId>
    <artifactId>objective-sql</artifactId>
    <version>{objsql.version}</version>
</dependency>

Spring Boot 集成項(xiàng)目,請將下列代碼添加至dependencies:

<!-- In Spring Boot, you need add spring-jdbc dependency before -->
<dependency>
  <groupId>com.github.braisdom</groupId>
  <artifactId>objsql-springboot</artifactId>
  <version>{objsql.version}</version>
</dependency>

最新版本請?jiān)L問 ObjectiveSQL,ObjSqlSpringBoot

2.3 Maven Compiler 參數(shù)配置

請將下列代碼添加至pom.xml 中的 <build> / <plugins> 結(jié)點(diǎn)下:

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
        <source>8</source>
        <target>8</target>
        <encoding>UTF-8</encoding>
        <compilerArgs>
            <arg>-Xplugin:JavaOO</arg>
        </compilerArgs>
        <annotationProcessorPaths>
            <path>
                <groupId>com.github.braisdom</groupId>
                <artifactId>objective-sql</artifactId>
                <version>${objsql.version}</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

3 數(shù)據(jù)庫連接注入

3.1 獨(dú)立應(yīng)用系統(tǒng)

以MySQL 為例,基于 ConnectionFactory 構(gòu)造數(shù)據(jù)連接獲取邏輯,并將其注入Databases。

private static class MySQLConnectionFactory implements ConnectionFactory {

    @Override
    public Connection getConnection(String dataSourceName) throws SQLException {
        try {
            String url = "jdbc:mysql://localhost:4406/objective_sql";
            String user = "root";
            String password = "******";
            return DriverManager.getConnection(url, user, password);
        } catch (SQLException e) {
            throw e;
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }
}

Databases.installConnectionFactory(new MySQLConnectionFactory());

getConnection 方法中的的 dataSourceName 參數(shù)僅在多數(shù)據(jù)源的場景下使用,getConnection 方法可以根據(jù)不同的 dataSourceName 返回不同的數(shù)據(jù)庫連接,其它場景下可以忽略該參數(shù)。

3.2 集成Spring Boot

應(yīng)用系統(tǒng)基于Spring Boot 框架開發(fā)時(shí),無需手動(dòng)注入數(shù)據(jù)源,請按下列方法進(jìn)行配置即可:

spring:
  profiles:
    name: objective-sql-example
    active: development

  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:4406/objective_sql
    username: root
    password: ******
    hikari:
      idle-timeout: 10000
      maximum-pool-size: 10
      minimum-idle: 5
      pool-name: Master

    # Configurations for multiple databases
    extensions:
      # The name of data source, which will match with @DomainModel definition 
      slave:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:4406/objective_sql
        username: root
        password: ******
        hikari:
          idle-timeout: 10000
          maximum-pool-size: 10
          minimum-idle: 5
          pool-name: Slave

其中 extensions 標(biāo)記僅當(dāng)多數(shù)據(jù)源時(shí)需要配置,而slave 作為數(shù)據(jù)源名稱,應(yīng)該與DomainModel 中定義的數(shù)據(jù)源名稱匹配,或者通過DomainModelDescriptro 中動(dòng)態(tài)數(shù)據(jù)源名稱匹配。

4 簡單SQL 編程指南

ObjectiveSQL 提供的簡單SQL 編程主要針對單表的相關(guān)SQL 使用,通過動(dòng)態(tài)生成的Java API 為應(yīng)用系統(tǒng)的開發(fā)提供便捷的開發(fā)體驗(yàn)。

4.1 命名約定

4.1.1 類名與表名

缺省情況下,ObjectiveSQL 以駝峰與下劃線的形式對Java 元素與數(shù)據(jù)庫元素進(jìn)行互相轉(zhuǎn)換,示例如下:

1)Java 定義如下:

class Member {
        private String memberNo;
    private String name;
}

2)數(shù)據(jù)庫表定義如下:

create table members (
        member_no varchar not null,
    name varchar
);

類名:Member 在數(shù)據(jù)庫中對應(yīng)的名稱為 members,而字段名memberNo 對應(yīng)的列名為 member_no,而字段名name 沒有任何變化

4.1.1 關(guān)聯(lián)對象

1)Java 定義如下:

class Member {
        private String memberNo;
    private String name;

    @Relation(relationType = RelationType.HAS_MANY)
    private List<Order> orders;
}

class Order {
        private String no;
    private Long memberId;

    @Relation(relationType = RelationType.BELONGS_TO)
    private Member member;
}

2)數(shù)據(jù)庫表定義如下:

create table members (
        member_no varchar not null,
    name varchar
);

create table members (
        member_no varchar not null,
    member_id int(10) not null,
    name varchar
);

通過上面的結(jié)構(gòu)定義,可以看出幾個(gè)關(guān)鍵特征:

  • 用于承載HAS_MANY 關(guān)聯(lián)對象的實(shí)例變量members 是由類型轉(zhuǎn)換成復(fù)數(shù),而BELONGS_TO 與HAS_ONE則為單數(shù)
  • Order 類中存在一個(gè)外鍵對應(yīng)的實(shí)例變量memberId,同時(shí)在表中也存在一個(gè)member_id與其對應(yīng)
  • 其它規(guī)則與類與表轉(zhuǎn)換的規(guī)則一致

注意:所有類名在轉(zhuǎn)換為復(fù)雜時(shí),遵循英文的規(guī)律,例如:person 對應(yīng) pepole

4.2 領(lǐng)域模型定義

@DomainModel
public class Member {
    @Size(min = 5, max = 20)
    private String no;

    @Queryable
    private String name;
    private Integer gender;
    private String mobile;

    @Transient
    private String otherInfo;

    @Relation(relationType = RelationType.HAS_MANY)
    private List<Order> orders;
}

ObjectiveSQL 會(huì)根據(jù)上述模型定義,自動(dòng)生成基礎(chǔ)的SQL 編程相關(guān)方法和SQL 抽象模型定義

4.3 數(shù)據(jù)查詢

Member.countAll();
Member.count("name = ?", "braisdom");

Member.queryByPrimaryKey(1);
Member.queryFirst("id > ?", 1);
Member.query("id > ?", 1);
Member.queryAll();

4.4 數(shù)據(jù)更新

Member.create(newMember);
Member.create(newMember, true); // Create a member without validating
Member.create(Member.newInstanceFrom(memberHash));
Member.create(new Member[]{newMember1, newMember2, newMember3}, false);

Member.update(1L, newMember, true); // Update a member by primary key and skip validationg
Member.update("name = ?", "name = ?", newName, oldName);

Member.destroy(1L); // Delete a member by primary key
Member.destroy("name = ?", "Mary");

4.5 事務(wù)

4.5.1 基于Annotation 的事務(wù)

// The method will be executed in a database thransaction
@Transactional
public static void makeOrder(Order order, OrderLine... orderLines) throws SQLException {
  Order.create(order, false);
  OrderLine.create(orderLines, false);
}

4.5.2 手動(dòng)事務(wù)管理

// Transaction executing manually
Databases.executeTransactionally(((connection, sqlExecutor) -> {
      Member.update(1L, newMember, true);
      Member.update("name = ?", "name = ?", newName, oldName);
    return null;
}));

4.6 關(guān)聯(lián)對象查詢

Member.queryAll(Member.HAS_MANY_ORDERS);
Member.queryFirst("id > ?", Member.HAS_MANY_ORDERS, 1);
Member.query("id > ?", Member.HAS_MANY_ORDERS, 1);

Member.queryByPrimaryKey(1, Member.HAS_MANY_ORDERS);
Member.queryByName("braisdom", Member.HAS_MANY_ORDERS);

上述代碼中的 Member.HAS_MANY_ORDERS 屬性為ObjectiveSQL 自動(dòng)生成,在特殊情況下,可以基于
com.github.braisdom.objsql.relation.Relationship 自定義關(guān)聯(lián)關(guān)系的構(gòu)建邏輯。

4.7 分頁查詢

// Create a Page instance with current page and page size
Page page = Page.create(0, 10);
PagedList<Member> members = Member.pagedQueryAll(page, Member.HAS_MANY_ORDERS);
PagedList<Member> members = Member.pagedQuery(page, "name = ?", "braisdom");

4.8 Query 接口編程

Query query = Member.createQuery();
query.project("name").groupBy("name").having("COUNT(*) > 0").orderBy("name DESC");

List<Member> members = query.execute(Member.HAS_MANY_ORDERS);

// Paged querying with querying dynamically
Paginator paginator = Databases.getPaginator();
Page page = Page.create(0, 10);
PagedList<Member> pagedMembers = paginator
                      .paginate(page, query, Member.class, Member.HAS_MANY_ORDERS);

針對SQL 中的分組和排序,需要通過Query 接口完成,同時(shí)Query 接口也可以進(jìn)行分頁和關(guān)聯(lián)對象查詢。

4.9 Validation

ObjectiveSQL Validation 內(nèi)部集成了Jakarta Bean Validation

詳細(xì)使用方法請參考:
https://beanvalidation.org/

4.9.1 手工調(diào)用 `validate` 方法

Member newMember = new Member()
        .setNo("100")
        .setName("Pamela")
        .setGender(1)
        .setMobile("15011112222");

// Violations occurred in field 'no'
Validator.Violation[] violations = newMember.validate();

4.9.2 創(chuàng)建對象時(shí) `validate`

Member newMember = new Member()
        .setNo("100000")
        .setName("Pamela")
        .setGender(1)
        .setMobile("15011112222");

Member.create(newMember); 
Member.create(newMember, true); // Skip validation

4.10 自定義SQL

Member.execute("DELETE FROM members WHERE name = ?", "Pamela");

5 復(fù)雜SQL 編程指南

ObjectiveSQL 提供的復(fù)雜SQL 編程,其實(shí)是對SQL 語法的一種抽象和建模,以Java API 形式進(jìn)行互相作用,使得復(fù)雜SQL 不再以字符串的形式出現(xiàn)在Java 中,從而實(shí)現(xiàn)動(dòng)態(tài)化SQL 變得清晰易理解,不同的業(yè)務(wù)系統(tǒng)也可以基于ObjectiveSQL 對自身業(yè)務(wù)的再抽象和建模,實(shí)現(xiàn)SQL 邏輯的復(fù)用。

5.1 JOIN 查詢

5.1.1 隱式 Join

Member.Table member = Member.asTable();
Order.Table order = Order.asTable();

Select select = new Select();

select.project(member.no, member.name, count().as("order_count"))
        .from(member, order)
        .where(member.id.eq(order.memberId))
        .groupBy(member.no, member.name);

List<Member> members = select.execute(Member.class);
SELECT `T0`.`NO` , `T0`.`name` , COUNT(*) AS `order_count`
FROM `members` AS `T0`, `orders` AS `T1`
WHERE (`T0`.`id` = `T1`.`member_id` )
GROUP BY `T0`.`NO` , `T0`.`name`

5.1.2 顯式Join

Member.Table member = Member.asTable();
Order.Table order = Order.asTable();

Select select = new Select();

select.project(member.no, member.name, count().as("order_count"))
        .from(member)
        .leftOuterJoin(order, order.memberId.eq(member.id))
        .groupBy(member.no, member.name);

List<Member> members = select.execute(Member.class);
SELECT `T0`.`NO` , `T0`.`name` , COUNT(*) AS `order_count`
FROM `members` AS `T0`
LEFT OUTER JOIN `orders` AS `T1` ON (`T1`.`member_id` = `T0`.`id` )
GROUP BY `T0`.`NO` , `T0`.`name`

5.2 分頁查詢

Member.Table member = Member.asTable();
Order.Table order = Order.asTable();

Paginator<Member> paginator = Databases.getPaginator();
Page page = Page.create(0, 20);

Select select = new Select();

select.project(member.no, member.name, count().as("order_count"))
        .from(member, order)
        .where(member.id.eq(order.memberId))
        .groupBy(member.no, member.name);

PagedList<Member> members = paginator.paginate(page, select, Member.class);
-- Counting SQL
SELECT COUNT(*) AS count_
FROM (
    SELECT
        `T0`.`NO`,
        `T0`.`name`,
        COUNT(*) AS `order_count`
    FROM `members` AS `T0`, `orders` AS `T1`
    WHERE (`T0`.`id` = `T1`.`member_id`)
    GROUP BY `T0`.`NO`, `T0`.`name`
) T
-- Querying SQL
SELECT `T0`.`NO`, `T0`.`name`, COUNT(*) AS `order_count`
FROM `members` AS `T0`, `orders` AS `T1`
WHERE (`T0`.`id` = `T1`.`member_id`)
GROUP BY `T0`.`NO`, `T0`.`name`
LIMIT 0, 20

5.3 復(fù)雜表達(dá)式查詢

ObjectiveSQL 通過運(yùn)算符重域技術(shù)使得Expression 也可以參與各類運(yùn)算符計(jì)算,從而使得Java 代碼變得簡單易懂,而不是通過各類運(yùn)算符方法進(jìn)行計(jì)算。ObjectiveSQL 表達(dá)式計(jì)算時(shí)并不能夠與SQL 表達(dá)完匹配,默認(rèn)情況下所有表達(dá)式均可以進(jìn)行算術(shù)運(yùn)算,在IntelliJ IDEA 中并不能給出完整的提醒,例如:JoinExpression 也可以進(jìn)行算術(shù)運(yùn)算,此時(shí)在IntelliJ IDEA 中并不會(huì)出現(xiàn)語法錯(cuò)誤的提醒,但在執(zhí)行運(yùn)算過程中會(huì)拋出
UnsupportedArithmeticalException,該異常為RuntimeException 的子類。

Order.Table orderTable = Order.asTable();
Select select = new Select();

select.project((sum(orderTable.amount) / sum(orderTable.quantity) * 100).as("unit_amount"))
        .from(orderTable)
        .where(orderTable.quantity > 30 &&
                orderTable.salesAt.between("2020-05-01 00:00:00", "2020-05-02 23:59:59"))
        .groupBy(orderTable.memberId);

List<Order> orders = select.execute(Order.class);
SELECT ((((SUM(`T0`.`amount` ) / SUM(`T0`.`quantity` ) )) * 100)) AS unit_amount
FROM `orders` AS `T0`
WHERE ((`T0`.`quantity` > 30)
    AND `T0`.`sales_at` BETWEEN '2020-05-01 00:00:00' AND '2020-05-02 23:59:59' )
GROUP BY `T0`.`member_id`

5.4 動(dòng)態(tài)查詢

所謂動(dòng)態(tài)查詢,實(shí)際上就是表達(dá)式的構(gòu)建過程跟隨著參數(shù)的有無而變化,基于這種使用場景,ObjectiveSQL 設(shè)計(jì)了一個(gè)永真的邏輯表達(dá)式EternalExpression ,永真表達(dá)式是程序上的一種巧妙設(shè)計(jì),使得代碼邏輯變得更清晰,即使所有參數(shù)均未賦值,整個(gè)表達(dá)式也會(huì)存在一個(gè)永的表達(dá),確保最終SQL 語句的正常。

String[] filteredNo = {"202000001", "202000002", "202000003"};
int filteredQuantity = 0;

Order.Table orderTable = Order.asTable();
Select select = new Select();
LogicalExpression eternalExpression = new EternalExpression();

if(filteredNo.length > 0) {
    eternalExpression = eternalExpression.and(orderTable.no.in(filteredNo));
}

if(filteredQuantity != 0) {
    eternalExpression = eternalExpression.and(orderTable > filteredQuantity);
}

select.project((sum(orderTable.amount) / sum(orderTable.quantity) * 100).as("unit_amount"))
        .from(orderTable)
        .where(eternalExpression)
        .groupBy(orderTable.memberId);

List<Order> orders = select.execute(Order.class);
SELECT ((((SUM(`T0`.`amount` ) / SUM(`T0`.`quantity` ) )) * 100)) AS unit_amount
FROM `orders` AS `T0`
WHERE ((1 = 1) AND `T0`.`NO` IN ('202000001', '202000002', '202000003') )
GROUP BY `T0`.`member_id`

6 高級(jí)使用

6.1 日志集成

由于 ObjectiveSQL 無法決定應(yīng)用系統(tǒng)使用哪一個(gè)日志框架,所以O(shè)bjectiveSQL 并未集成任何第三方日志框架,確認(rèn)使用JDK 自身的日志框架,如果應(yīng)用系統(tǒng)需要使用自身的日志框架,并在系統(tǒng)啟動(dòng)完成后注入ObjectiveSQL,請按下列方式集成(以Slf4j 為例)。

6.1.1 LoggerFactory 擴(kuò)展實(shí)現(xiàn)

public class ObjLoggerFactoryImpl implements LoggerFactory {

    private class ObjLoggerImpl implements Logger {

        private final org.slf4j.Logger logger;

        public ObjLoggerImpl(org.slf4j.Logger logger) {
            this.logger = logger;
        }

        @Override
        public void debug(long elapsedTime, String sql, Object[] params) {
            logger.debug(createLogContent(elapsedTime, sql, params));
        }

        @Override
        public void info(long elapsedTime, String sql, Object[] params) {
            logger.info(createLogContent(elapsedTime, sql, params));
        }

        @Override
        public void error(String message, Throwable throwable) {
            logger.error(message, throwable);
        }

        private String createLogContent(long elapsedTime, String sql, Object[] params) {
            String[] paramStrings = Arrays.stream(params)
                    .map(param -> String.valueOf(param)).toArray(String[]::new);
            String paramString = String.join(",", paramStrings);
            return String.format("[%dms] %s, with: [%s]",
                    elapsedTime, sql, String.join(",",
                    paramString.length() > 100 ? StringUtil
                            .truncate(paramString, 99) : paramString));
        }
    }

    @Override
    public Logger create(Class<?> clazz) {
        org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(clazz);
        return new ObjLoggerImpl(logger);
    }
}

6.1.1 普通應(yīng)用程序注入方式

public class Application {

    public static void main(String[] args) {
        Databases.installLoggerFactory(new ObjLoggerFactoryImpl());
        // others
    }
}

6.1.2 Spring Boot 應(yīng)用程序注入方式

@SpringBootApplication
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(Application.class);
        springApplication.addListeners(new ApplicationListener<ApplicationReadyEvent>() {

            @Override
            public void onApplicationEvent(ApplicationReadyEvent event) {
                Databases.installLoggerFactory(new ObjLoggerFactoryImpl());
            }
        });
        springApplication.run(args);
    }
}

6.2 基于SQL 語句的對象緩存

應(yīng)用系統(tǒng)中對時(shí)間性不強(qiáng)的數(shù)據(jù)會(huì)進(jìn)行數(shù)據(jù)緩存,通常會(huì)將數(shù)據(jù)緩存至redis 中,針對些特性,可以擴(kuò)展ObjectiveSQL 的 SQLExecutor 接口輕易實(shí)現(xiàn)。

6.1.1 SQLExecutor 擴(kuò)展實(shí)現(xiàn)

public class CacheableSQLExecutor<T> extends DefaultSQLExecutor<T> {

    private static final List<Class<? extends Serializable>> CACHEABLE_CLASSES =
            Arrays.asList(new Class[]{Member.class});
    private static final Integer CACHED_OBJECT_EXPIRED = 60;
    private static final String KEY_SHA = "SHA";

    private Jedis jedis = new Jedis("localhost", 6379);
    private MessageDigest messageDigest;

    public CacheableSQLExecutor() {
        try {
            messageDigest = MessageDigest.getInstance(KEY_SHA);
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalArgumentException(e.getMessage(), e);
        }
    }

    @Override
    public List<T> query(Connection connection, String sql,
                         TableRowAdapter tableRowAdapter, Object... params) 
      throws SQLException {
        Class<?> domainClass = tableRowAdapter.getDomainModelClass();

        if (CACHEABLE_CLASSES.contains(domainClass)) {
            if(!Serializable.class.isAssignableFrom(domainClass)) {
                throw new IllegalArgumentException(String
                                                   .format("The %s cannot be serialized"));
            }

            messageDigest.update(sql.getBytes());

            String hashedSqlId = new BigInteger(messageDigest.digest()).toString(64);
            byte[] rawObjects = jedis.get(hashedSqlId.getBytes());

            if (rawObjects != null) {
                return (List<T>) SerializationUtils.deserialize(rawObjects);
            } else {
                List<T> objects = super.query(connection, sql, tableRowAdapter, params);
                byte[] encodedObjects = SerializationUtils.serialize(objects);
                SetParams expiredParams = SetParams.setParams().ex(CACHED_OBJECT_EXPIRED);

                jedis.set(hashedSqlId.getBytes(), encodedObjects, expiredParams);

                return objects;
            }
        }
        return super.query(connection, sql, tableRowAdapter, params);
    }
}

6.1.1 注入方式

public class Application {

    public static void main(String[] args) {
        Databases.installSqlExecutor(new CacheableSQLExecutor());
        // others
    }
}

Spring Boot 的注入方式去 LogFactory 的注入方式相同

6.3 ColumnTransition 擴(kuò)展

ColumnTransition 是ObjectiveSQL 對外提供的一種數(shù)據(jù)類型轉(zhuǎn)的擴(kuò)展接口,該接口的詳細(xì)定義請參考:ColumnTransition.java ,以日期形式為例,介紹ColumnTransition 的擴(kuò)展方式。

public class SqlDateTimeTransition<T> implements ColumnTransition<T> {

    @Override
    public Object sinking(DatabaseMetaData databaseMetaData, T object,
                          TableRowAdapter tableRowDescriptor, 
                          String fieldName, FieldValue fieldValue) 
      throws SQLException {
        String databaseName = databaseMetaData.getDatabaseProductName();
        if (fieldValue != null && fieldValue.getValue() != null) {
            if (SQLite.equals(databaseName) || Oracle.equals(databaseName)) {
                return fieldValue;
            } else if (PostgreSQL.equals(databaseName)) {
                if (fieldValue.getValue() instanceof Timestamp) {
                    return fieldValue.getValue();
                } else if (fieldValue.getValue() instanceof Long) {
                    Instant value = Instant.ofEpochMilli((Long) fieldValue.getValue());
                    return Timestamp.from(value);
                } else {
                    return Timestamp.valueOf(String.valueOf(fieldValue.getValue()));
                }
            } else {
                return fieldValue;
            }
        }
        return null;
    }

    @Override
    public Object rising(DatabaseMetaData databaseMetaData, 
                         ResultSetMetaData resultSetMetaData,
                         T object, TableRowAdapter tableRowDescriptor, 
                         String columnName, Object columnValue) throws SQLException {
        String databaseName = databaseMetaData.getDatabaseProductName();
        try {
            if (columnValue != null) {
                if (SQLite.equals(databaseName)) {
                   Instant value = Instant
                     .ofEpochMilli(Long.valueOf(String.valueOf(columnValue)))
                    return Timestamp.from(value);
                } else {
                    return columnValue;
                }
            }
        } catch (DateTimeParseException ex) {
            String message = String.format("Invalid raw DataTime of '%s' from database: %s",
                    columnName, columnValue);
            throw new IllegalArgumentException(message, ex);
        }
        return null;
    }
}

sinking 方法是將Java 中的值,轉(zhuǎn)換為數(shù)據(jù)庫所能接受的值,rising則為將數(shù)據(jù)庫中的值,轉(zhuǎn)換為Java 所能接受的值。

文章轉(zhuǎn)自:架構(gòu)師必備

分享到:
標(biāo)簽:java
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評(píng)定2018-06-03

通用課目體育訓(xùn)練成績評(píng)定