
sf.database.dialect.DatabaseDialect Maven / Gradle / Ivy
Show all versions of sorm Show documentation
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();
}