数据库-转换sql语句

文章描述:主要说明转换成SQL语句的过程。----必要信息(数据库名,表名,条件)转换成SQL语句

一些界面上数据增删改查的操作往往只需要输入一数据库名,表名,加条件就可以进行数据查询了,在这背后是怎么实现了呢,这些程序有些是使用封装的方法,有些直接输入sql语句进行操作,封装的方法最后也是将查询条件(上面输入操作)转换为SQL语句用Statement对象对应方法进行相关操作

而Statement对象获得SQL语句后怎么执行查询(这个不归statement管了),Statement这里是通过jdbc(或者其他驱动如:ODBC等)将SQL语句放入数据库,由数据库进行解释操作。这个速度较慢

preparedstatement:是java这边将原始的SQL语句进行解释,然后将中间码录入数据库,数据库直接执行,这样速度相比statement这种方式会更快!!!

我是一条分割线^_^



在android中,提供了一些方便数据操作,不需要程序员写sql语句,只需要写如关键参数+条件。后面执行过程不需要我们考虑。

如android中的SQLite操作SQLiteDatabase封装很多方法

insert(String table, String nullColumnHack, ContentValues initialValues )//Convenience method for inserting a row into the database.

简单的方法对于插入一行数据到数据库中

@param table:表名

@param nullColumnHack:要强行插入null值的列名

@param initialValues :是一个HashMap存储的键值对,里面的key代表columnName列名,value代表在该行的key值所对应列要插入的值

一般情况下nullColumnHack为null

ContentValues contentValues = new ContentValues();
String name="我是书的名字";
contentValues.put("bookName",name);
insert("book",null,contentvalues)

上面insert语句最后会转化为SQL语句

insert into book(bookName) values("我是书的名字")

当然这个转换过程不是这样了。

StringBuilder sql = new StringBuilder();//StringBuilder一个可变的字符序列
sql.append("INSERT");
sql.append(CONFLICT_VALUES[conflictAlgorithm]);
sql.append(" INTO ");
sql.append(table);
sql.append(‘(‘);
Object[] bindArgs = null;//bindArgs存放的是value[]数组,要插入的数据
int size = (initialValues != null && initialValues.size() > 0)
                    ? initialValues.size() : 0;
if (size > 0) {
                bindArgs = new Object[size];
                int i = 0;
                for (String colName : initialValues.keySet()) {//循环添加列名对应insert into table(colName1,..2,...colN)括号里面的所有列名
                    sql.append((i > 0) ? "," : "");
                    sql.append(colName);
                    bindArgs[i++] = initialValues.get(colName);//将要插入的数据全部复制到bindArgs数组中
                }
                sql.append(‘)‘);
                sql.append(" VALUES (");
                for (i = 0; i < size; i++) {
                    sql.append((i > 0) ? ",?" : "?");
                }
} else {
                sql.append(nullColumnHack + ") VALUES (NULL");
           }
            sql.append(‘)‘);

上面形成sql语句是insert into book(bookName) values(?),还有生成一个数据数组bindArgs。

如果数据initialValues 的值为null,则会执行insert into book(nullColumnHack) values(NULL)强行将列的值设为null

----到最后,会将statement对象和bindArgs数据进行绑定最后给数据库解释执行

感觉其它封装的数据库类原理和这个都是相似的吧

总结:

执行数据库操作的步奏:

  1构造Statement对象

2statement来执行某种(增删改查etc.)操作

3通过session调用到连接池中某个connection的execute相关方法。

4在connection中重新构建PreparedStatement(其实该对象才真正指向sqlite中的stmt),绑定数据和PreparedStament对象,调用Native方法底层JNI

PS:

android中sqlite的内部流程

打开数据库操作Android SQLite 打开、操作分析

SQLiteDatabase.openDataBase
SQLiteDatabase.open
SQLiteDatabase.openInner
SQLiteConnectionPool.open
SQLiteConnectionPool.openConnectionLocked打开连接池
SQLiteConnection.open
nativeOpen最后调用底层打开

执行数据库操作

SQLiteStatement statement = new SQLiteStatement()时,使得该SQLiteDatabase的某个connection拥有对应的PreparedStatement.

statement.execute()时,会在SQLiteDatabase的多个connection中找到含有对应PreparedStatement的connection来使用.

假如该connection恰巧被其他线程使用了,得到的是另一个connection,其会重新acquirePreparedStatement。

DatabaseUtils.getSqlStatementType(mSql)这个mSql语句为select

db.getThreadSession().prepare//SQLiteSeesion
SQLiteConnection.prepare
SQLiteConnection.acquirePreparedStatement(sql)
----SQLiteConnection中操作
statement=SQLiteConnection.mPreparedStatementCache.get(sql)
if(statement!=null)
{
    if (!statement.mInUse) { // 并且不在使用中
            return statement;  // 返回该statement
        }
skipCache = true; // 如果已在使用 另备一份并不再缓存
}
 final int statementPtr = nativePrepareStatement(mConnectionPtr, sql); //native
    try {
        final int numParameters = nativeGetParameterCount(mConnectionPtr, statementPtr);
        final int type = DatabaseUtils.getSqlStatementType(sql);
        final boolean readOnly = nativeIsReadOnly(mConnectionPtr, statementPtr);
        statement = obtainPreparedStatement(sql, statementPtr, numParameters, type, readOnly); // 从池中获取一个statement,并将其从池中移除
        if (!skipCache && isCacheable(type)) {
            mPreparedStatementCache.put(sql, statement); // 将statement放入缓存中
            statement.mInCache = true;
        }
 statement.mInUse = true;
    return statement;  ------获得PreparedStatement

SQLiteOpenHelper保证一个实例里只有一个SQLiteDatabase

SQLiteDatabase.openDatabase的过程是构建SQLiteDatabase对象的过程,实质是构建SQLiteDatabase的成员变量SQLiteConnectionPool的过程,该过程是一个获取primaryConnection的过程。

每个线程有自己的SQLiteSession且只有一个,每个SQLiteSession在某一时刻最多只有一个SQLiteConnection(需要时从连接池获取,用完返还),保证了一个线程在某一时刻只有一个SQLiteConnection连接到某一SQLiteDatabase。事务同样通过Session来实现,故线程之间的事务是独立的

SQLiteConnectionPool掌管某个SQLiteDatabase的连接池。确保PrimaryConnection只有一个,如果空闲则将其返回,如果正被其他session使用则返回空,如果没有则新建。对于非PrimaryConnection,将会在连接池中优先选取stmt相同的,如果没有相同的获取池中最后一个,如果池子已经空了(此时多个线程同时用着多个连接),新建一个非主连接。

不知道有没有错,先记着两片不同文章,

Android SQLite 打开、操作分析

Android sqlite数据库连接池连接异常分析

时间: 2024-10-12 04:41:41

数据库-转换sql语句的相关文章

在线数据库表(sql语句)生成java实体类工具

相信每个做java开发的读者,都接触过SQL建表语句,尤其是在项目开发初期,因为数据库是项目的基石. 在现代项目开发中,出现了许多ORM框架,通过简单的实体映射,即可实现与数据库的交互,然而我们最初设计的一定是数据库表结构,而不是实体类.实体类仅仅是对底层数据结构的有损压缩,它仅仅是数据载体,不具备数据归档能力. 因此,很多时候,我们需要将原始的SQL建表语句转换成java实体类,这项工作看似简单,但若人工完成,工作量也是相当可观的,而且难免会出现差错. 到目前为止,笔者还没有发现比较靠谱的此类

在线数据库表(sql语句)生成java实体类工具 - 参考手册

SQL建表语句 说明 格式良好的SQL建表语句,可以是直接从PowerDesigner.Navicat等工具中导出SQL建表语句.所谓格式良好,是指建表指令与表名必须在一行,字段名称.类型.注释必须在一行,因为这个工具是用正则实现的,并不是语法解析器,当然,以后有时间的话,会改进成解析器. 举例 -- ---------------------------- -- Table structure for t_activity -- ---------------------------- DRO

SQL Server 【附】创建&quot;商品管理数据库&quot;、&quot;学生选课数据库&quot;的SQL语句

附:(创建“商品管理数据库”的SQL语句) --建立"商品管理数据库"数据库-- create database 商品管理数据库 on(name='商品管理数据库_m', filename='D:\商品管理系统\商品管理数据库_m.mdf', size=6mb,filegrowth=1mb,maxsize=unlimited) log on(name='商品管理数据库_l', filename='D:\商品管理系统\商品管理数据库_l.ldf', size=1,filegrowth=1

清理数据库事务——SQL语句

清除流程内部的所有相关数据 eg1: declare @procedureTemp table ( [ProcedureCode] varchar(10) ) declare @ProcedureCode varchar(10) INSERT into @procedureTemp SELECT ProcedureCode FROM WorkFlowProcedure WHILE EXISTS(select [ProcedureCode] from @procedureTemp) begin -

[数据库]简单SQL语句总结

1.在查询结果中显示列名:a.用as关键字:select name as '姓名'   from students order by ageb.直接表示:select name '姓名'   from students order by age 2.精确查找:a.用in限定范围:select * from students where native in ('湖南', '四川') b.between...and:select * from students where age between 2

Oracle数据库常用Sql语句大全

一,数据控制语句 (DML) 部分 1.INSERT  (往数据表里插入记录的语句) INSERT INTO 表名(字段名1, 字段名2, --) VALUES ( 值1, 值2, --); INSERT INTO 表名(字段名1, 字段名2, --)  SELECT (字段名1, 字段名2, --) FROM 另外的表名; 字符串类型的字段值必须用单引号括起来, 例如: 'GOOD DAY' 如果字段值里包含单引号' 需要进行字符串转换, 我们把它替换成两个单引号''. 字符串类型的字段值超过

Oracle 数据库常用sql语句及知识

<Oracle 数据库> 一.常用sql语句: 1.连接系统管理员账号:conn system/system(安装时口令); 2.创建新账号:create user Leo(账号名) identified by Leo(密码): 3.给新账号授权:grant connect,resource to Leo; 4.从某个账户收权:revoke resource from Leo; 5.连接新账号:conn Leo/Leo; 6.显示当前客户:show user; 7.查看表结构:desc s_e

数据库之sql语句汇总20180616

/*******************************************************************************************/ 一.SQL简介 SQL:结构化查询语言 SQL 是一门 ANSI 的标准计算机语言,用来访问和操作数据库系统. SQL 语句用于取回和更新数据库中的数据.SQL 可与数据库程序协同工作,比如 MS Access.DB2.Informix.MS SQL Server.Oracle.Sybase 以及其他数据库系统

Oracle数据库的sql语句性能优化

在应用系统开发初期,由于开发数据库数据比较少,对于查询sql语句,复杂试图的编写等体会不出sql语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要问题之一.系统优化中一个很重要的方面就是sql语句的优化.对于海量数据,劣质sql语句和优质sql语句之间的速度差别可以达到上百倍,可见对于一个系统不是简单地能实现其功能就行,而是要写出高质量的sql语句,提高系统的可用性. Oracle的sql调优第一个复杂的主题,甚至需要长