1 简介
SQLite 作为数据库特别小,Android系统中自带,Windows中使用也特别方便。 下面代码是在不使用任何框架的情况下,操作SQLite。
2 工具类
2.1 ResultSetMapper
package com
.wu
.port
.utils
.sqlite
;
import java
.lang
.reflect
.Field
;
import java
.lang
.reflect
.InvocationTargetException
;
import java
.sql
.ResultSet
;
import java
.sql
.ResultSetMetaData
;
import java
.sql
.SQLException
;
import java
.util
.ArrayList
;
import java
.util
.List
;
import javax
.persistence
.Column
;
import javax
.persistence
.Entity
;
import org
.apache
.commons
.beanutils
.BeanUtils
;
public class ResultSetMapper {
@SuppressWarnings("unchecked")
static public<T> List
<T> mapRersultSetToObject(ResultSet rs
, Class
outputClass) {
List
<T> outputList
= null
;
try {
if (rs
!= null
) {
if (outputClass
.isAnnotationPresent(Entity
.class)) {
ResultSetMetaData rsmd
= rs
.getMetaData();
Field
[] fields
= outputClass
.getDeclaredFields();
while (rs
.next()) {
T bean
= (T
) outputClass
.newInstance();
for (int _iterator
= 0; _iterator
< rsmd
.getColumnCount(); _iterator
++) {
String columnName
= rsmd
.getColumnName(_iterator
+ 1);
Object columnValue
= rs
.getObject(_iterator
+ 1);
for (Field field
: fields
) {
if (field
.isAnnotationPresent(Column
.class)) {
Column column
= field
.getAnnotation(Column
.class);
if (column
.name().equalsIgnoreCase(columnName
) && columnValue
!= null
) {
BeanUtils
.setProperty(bean
, field
.getName(), columnValue
);
break;
}
}
}
}
if (outputList
== null
) {
outputList
= new ArrayList<T>();
}
outputList
.add(bean
);
}
} else {
}
} else {
return null
;
}
} catch (IllegalAccessException e
) {
e
.printStackTrace();
} catch (SQLException e
) {
e
.printStackTrace();
} catch (InstantiationException e
) {
e
.printStackTrace();
} catch (InvocationTargetException e
) {
e
.printStackTrace();
}
return outputList
;
}
}
2.2 SqlController
package com
.wu
.port
.utils
.sqlite
;
import lombok
.Getter
;
import java
.sql
.Connection
;
import java
.sql
.PreparedStatement
;
import java
.sql
.ResultSet
;
import java
.sql
.SQLException
;
import java
.util
.List
;
@Getter
public class SqlController {
@Getter
private static SqliteConfig sqliteConfig
;
@Getter
private static SqlController sqlController
= new SqlController();
private SqlController(){
sqliteConfig
= new SqliteConfig();
}
public void excuteSql(String sql
,SqlTemplate sqlTemplate
){
Connection c
= sqliteConfig
.getConnection();
try {
PreparedStatement stmt
= c
.prepareStatement(sql
);
c
.setAutoCommit(false);
sqlTemplate
.setPreparedStatement(stmt
);
stmt
.addBatch();
stmt
.executeBatch();
c
.commit();
stmt
.close();
c
.close();
} catch ( Exception e
) {
e
.printStackTrace();
System
.exit(0);
}
}
public void excuteSqlMany(String sql
,List
<SqlTemplate> sqlTemplates
){
Connection c
= sqliteConfig
.getConnection();
try {
c
.setAutoCommit(false);
PreparedStatement stmt
= c
.prepareStatement(sql
);
for (int i
= 0; i
< sqlTemplates
.size(); i
++) {
SqlTemplate sqlTemplate
= sqlTemplates
.get(i
);
sqlTemplate
.setPreparedStatement(stmt
);
stmt
.addBatch();
stmt
.executeBatch();
}
c
.commit();
stmt
.close();
c
.close();
} catch ( Exception e
) {
e
.printStackTrace();
System
.exit(0);
}
}
public<E> List
<E> excuteSqlAndGetData(String sql
, SqlTemplate sqlTemplate
,Class
<E> clazz
){
Connection c
= sqliteConfig
.getConnection();
PreparedStatement stmt
= null
;
try {
stmt
= c
.prepareStatement(sql
);
sqlTemplate
.setPreparedStatement(stmt
);
ResultSet resultSet
= stmt
.executeQuery();
List
<E> objects
= ResultSetMapper
.mapRersultSetToObject(resultSet
, clazz
);
return objects
;
} catch ( Exception e
) {
e
.printStackTrace();
System
.exit(0);
}finally{
try {
stmt
.close();
c
.close();
} catch (SQLException e
) {
e
.printStackTrace();
}
}
return null
;
}
public interface SqlTemplate{
void setPreparedStatement(PreparedStatement preparedStatement
);
}
public void close(){
sqliteConfig
.close();
}
}
2.3 SqliteConfig
这里需要修改数据库名(修改 databaseName 变量的值)
package com
.wu
.port
.utils
.sqlite
;
import lombok
.Getter
;
import lombok
.extern
.slf4j
.Slf4j
;
import java
.sql
.Connection
;
import java
.sql
.DriverManager
;
import java
.sql
.SQLException
;
@Slf4j
public class SqliteConfig {
private static ThreadLocal
<Connection> threadLocal
= new ThreadLocal<>();
@Getter
private final static String databaseName
= "test.db";
@Getter
private final static String url
= "jdbc:sqlite:" + databaseName
;
static {
try {
Class
.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException e
) {
e
.printStackTrace();
}
}
public SqliteConfig() {
try {
Connection temp
= DriverManager
.getConnection(url
);
threadLocal
.set(temp
);
} catch (Exception e
) {
System
.err
.println(e
.getClass().getName() + ": " + e
.getMessage());
System
.exit(0);
}
}
public Connection
getConnection() {
Connection connection
= threadLocal
.get();
boolean isNeedCreate
= false;
if (connection
== null
) {
isNeedCreate
= true;
}else {
try {
if (connection
.isClosed()) {
isNeedCreate
= true;
}
} catch (SQLException e1
) {
isNeedCreate
= true;
}
}
if (isNeedCreate
) {
Connection temp
= null
;
try {
temp
= DriverManager
.getConnection(url
);
} catch (SQLException e
) {
e
.printStackTrace();
}
threadLocal
.set(temp
);
return temp
;
} else {
return connection
;
}
}
public void close() {
Connection c
= threadLocal
.get();
threadLocal
.remove();
try {
c
.close();
} catch (SQLException e
) {
e
.printStackTrace();
}
}
}
3 工具类的使用
1)sqlController的excuteSql方法没有返回结果,第一个参数是 sql 语句,第二个参数可以填写一个匿名函数,该匿名函数的形参是PreparedStatement类对象,方法体内只放置对应位置的"?“的参数,不做其他操作。 2)sqlController的excuteSqlAndGetData有返回值,返回值是List数组,第一个参数是 sql 语句,第二个参数可以填写一个匿名函数,该匿名函数的形参是PreparedStatement类对象,方法体内只放置对应位置的”?"的参数,不做其他操作。第三个参数是实体类的字节码对象,用于内省操作。
3.1 添加表
private void createTable(){
SqlController sqlController
= SqlController
.getSqlController();
String sql
= "CREATE TABLE IF NOT EXISTS receiveData" +
"(id INT PRIMARY KEY NOT NULL," +
" par_id INT NOT NULL, " +
" par_var INT NOT NULL, " +
" receive_time DATE NOT NULL) ";
sqlController
.excuteSql(sql
, stmt
-> { });
}
3.2 插入数据
private void insert(){
SqlController sqlController
= SqlController
.getSqlController();
sqlController
.excuteSql("INSERT INTO receiveData(id,par_id,par_var,receive_time) VALUES(?,?,?,?);"
, stmt
-> {
try {
stmt
.setInt(1,1 );
stmt
.setInt(2,20 );
stmt
.setInt(3,200 );
stmt
.setDate(4,new Date(new java.util.Date().getTime()));
} catch (SQLException e
) {
e
.printStackTrace();
}
});
}
3.3 查询
查询的实体类对象
package com
.wu
.port
.utils
.protocol
.pojo
;
import com
.wu
.port
.utils
.protocol
.ProtocolData
;
import com
.wu
.port
.utils
.protocol
.utils
.UnsignedCharUtils
;
import lombok
.Data
;
import javax
.persistence
.Column
;
import javax
.persistence
.Entity
;
import java
.util
.Date
;
@Data
@Entity
public class ProtocolDataPojo {
@Column(name
= "id")
private int databaseId
;
private int dAddr
;
private int id
;
@Column(name
= "par_id")
private int parId
;
@Column(name
= "par_var")
private int parVar
;
@Column(name
= "receive_time")
private Date receiveTime
;
public ProtocolDataPojo() {
}
}
查询
private void find(){
SqlController sqlController
= SqlController
.getSqlController();
List
<ProtocolDataPojo> protocolDataPojos
= sqlController
.excuteSqlAndGetData(
"SELECT id,par_id,par_var,receive_time " +
"FROM receiveData order by receive_time DESC"
, stmt
-> {
}, ProtocolDataPojo
.class);
System
.out
.println(protocolDataPojos
);
}