All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sf.database.dialect.DatabaseDialect Maven / Gradle / Ivy

The newest version!
package sf.database.dialect;

import sf.database.dbinfo.ConnectInfo;
import sf.database.dbinfo.DBMetaData;
import sf.database.dbinfo.Feature;
import sf.database.meta.ColumnMapping;

import java.sql.SQLException;
import java.util.Date;

public interface DatabaseDialect {
    /**
     * 得到RDBMS的名称
     * @return
     */
    String getName();

    /**
     * 得到该数据库上该种数据类型的真实实现类型。
     * 比如,在不支持boolean类型的数据库上,会以char类型代替boolean;在不支持blob的数据库上,会以varbinary类型代替blob
     * @param sqlType
     * @return
     */
    int getImplementationSqlType(int sqlType);

    /**
     * 将表达式或值转换为文本形式的缺省值描述
     * @param defaultValue
     * @param sqlType
     * @return
     */
    String toDefaultString(Object defaultValue, int sqlType);

    /**
     * 判断数据库是否不支持某项特性
     * @param feature
     * @return
     */
    boolean notHas(Feature feature);

    /**
     * 判断数据库是否支持某项特性
     * @param feature
     * @return
     */
    boolean has(Feature feature);

    /**
     * 像Oracle,其Catlog是不用的,那么返回null mySQL没有Schema,每个database是一个catlog,那么返回值
     * 同时修正返回的大小写
     * @param schema
     * @return
     */
    String getCatlog(String schema);

    /**
     * 对于表名前缀的XX. MYSQL是作为catlog的,不是作为schema的 同时修正返回的大小写
     * @param schema
     * @return
     */
    String getSchema(String schema);

    /**
     * 获取数据库的默认驱动类
     * @param url Derby根据连接方式的不同,会有两种不同的DriverClass,因此需要传入url
     * @return 驱动类
     */
    String getDriverClass(String url);

    /**
     * 生成数据库连接字串
     * @param host     <=0则会使用默认端口
     * @param port
     * @param pathOrName
     * @return
     */
    String generateUrl(String host, int port, String pathOrName);

    /**
     * Oracle会将所有未加引号的数据库对象名称都按照大写对象名来处理,MySQL则对表名一律转小写,列名则保留原来的大小写。
     * 为了体现这一数据库策略的不同,这里处理大小写的问题。
     * 

* 目前的原则是:凡是涉及 * schema/table/view/sequence/dbname等转换的,都是用此方法,凡是设计列名转换,列别名定义的都用 * @param name * @return */ String getObjectNameToUse(String name); /** * 获得大小写正确的列名 * @param name * @return */ String getColumnNameToUse(ColumnMapping name); /** * 检查数据库是否包含指定的关键字,用来进行检查的对象名称都是按照getColumnNameIncase转换后的,因此对于大小写统一的数据库, * 这里无需考虑传入的大小写问题。 * @param name * @return */ boolean containKeyword(String name); /** * 当使用Timestamp类型的绑定变量操作时,转换为什么值 *

这个功能是干什么用的

* 将java.util.Date转换为java.sql.Timestamp。这个功能本来和数据库方言是无关的,只涉及时间的转换。 * 然而问题在于Oracle中,曾经只有Date类型。而且这个Date是年月日时分秒,但不到毫秒。 * 也就是说,如果你使用Oracle来存储date(到秒),而当你将Date字段作为查询条件时,尴尬就发生了—— * 传入java.sql.Date,会丢失时分秒精度;而传入java.sql.Timestamp作查询条件,有可能是查不到记录的,因为还有毫秒精度,还是查不到数据。 * 因此本方言会将映射到Oracle时的精度缩减到秒。从而解决上述问题。 *

* @param timestamp java.util.Date * @return java.sql.Timestamp */ java.sql.Timestamp toTimestampSqlParam(Date timestamp); /** * 当出现异常时,使用此方法检查这个异常是否因为网络连接异常引起的。 *

*

用途

* 用于内置连接池的刷新——可见自己实现一个连接池其实多么复杂。 * 因为当数据库断开或重启时,往往所有的连接都会失效。此时使用连接池中的连接就会出错。 * 比较典型的场景是数据库重启了一次,此时连接池里的连接看上去都是好好的,但实际上真正在上面执行SQL全都会出错。 *

* 一种办法是当从连接池获得每个连接都对连接进行检查,这种检查必需是通过网络通信的检查,因为此时如果调用 Connection.isClosed()会正常返回false, * 因此这种检查就显得额外占开销,在高并发的OLTP中并不经济。 * 因此试图实现一种更为有效的检查方式,即当任何数据库操作出现错误,并且这个错误是由连接IO引起,那么都要对连接池立刻进行清洗和检查,用这种触发机制来保证连接池的高效。 *

*

未来

* 上述作为一种面向电信项目过程中设计方面的尝试,目前看来我更希望降低本框架的复杂度,让连接池独立出来,去除和连接池的耦合。并且连接池封装了所有的数据库操作,也能自行完成这一逻辑。 * 所以未来版本中可能会去除,连接池应该由更专业的框架去完成。 * @param se 异常 * @return 如果是IO异常,那么返回true */ boolean isIOError(SQLException se); /** * 根据 JDBC的URL,解析出其中的dbname,host,user等信息。目的是为了在不必连接数据库的情况下,得到数据库名称 * @param connectInfo */ public void parseDbInfo(ConnectInfo connectInfo); /** * 返回指定的属性(文本) * @param key 特性名称 * @return 特性文本 */ public String getProperty(DBProperty key); /** * 返回指定的属性(文本) * @param key 特性名称 * @param defaultValue 缺省值 * @return 特性文本 */ public String getProperty(DBProperty key, String defaultValue); /** * 返回指定特性(数值),如果无值返回0 * @param key 特性名称 * @return 数值 */ public int getPropertyInt(DBProperty key); /** * 返回指定数据库特性(数值),如果无值返回0 * @param key 特性名称 * @return 数值 */ public long getPropertyLong(DBProperty key); /** * 不同数据库登录后,所在的默认schema是不一样的 *
    *
  • Oracle是以登录的用户名作为schema的。
  • *
  • mysql是只有catlog不区分schema的。
  • *
  • derby支持匿名访问,此时好像是位于APP这个schema下。
  • *
  • SQL Server默认是在dbo这个schema下
  • *
*
因此对于无法确定当前schema的场合,使用这里提供的schema名称作为当前schema * @return 当前RDBMS的缺省Schema */ String getDefaultSchema(); /** * 针对非绑定变量SQL,生成SQL语句所用的文本值。 Java -> SQL String */ String getSqlDateExpression(Date value); /** * 针对非绑定变量SQL,生成SQL语句所用的文本值。 Java -> SQL String */ String getSqlTimeExpression(Date value); /** * 针对非绑定变量SQL,生成SQL语句所用的文本值。 Java -> SQL String */ String getSqlTimestampExpression(Date value); /** * 初始化方言,根据JDBC接口进一步嗅探出数据库版本和JDBC驱动信息,从而让方言更加适配数据库操作。 * 当有一个数据库实例连接初次创建时调用. Dialect可以通过直接连接数据库判断版本、函数等,调整Dialect内部的一些配置和数据。 * @param db */ void accept(DBMetaData db); /** * 数据库对象是否为大小写敏感的 * 一般来说对应引号中的表名列名都是大小写敏感的。此处仅指没有引号的情况下是否大小写敏感 * @return */ boolean isCaseSensitive(); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy