1. 程式人生 > >輕量級資料庫訪問框架FastSQL

輕量級資料庫訪問框架FastSQL

目錄

1 簡介

FastSQL一個基於spring-jdbc的簡單ORM框架,它支援sql構建、sql執行、命名引數繫結、查詢結果自動對映和通用DAO。結合了Hibernate/JPA快速開發和Mybatis高效執行的優點。

FastSQL可以完全滿足你控制慾,可以用Java程式碼清晰又方便地寫出sql語句並執行。

FastSQL完全可用於生產環境,相比Mybatis,使用簡單,開發效率高。

2 入門

2.1 安裝

如果使用 Maven 來構建專案,則需將下面的 dependency 程式碼置於 pom.xml 檔案中:

<dependency>
    <groupId>
top.fastsql</groupId> <artifactId>fastsql</artifactId> <version>1.3.0</version> </dependency>

如果使用 Gradle 來構建專案,則需將下面的程式碼置於 build.gradle 檔案的 dependencies 程式碼塊中:

compile 'top.fastsql:fastsql:1.3.0'

2.2 構建 SQLFactory

你可以直接從 Java 程式構建一個 SQLFactory ,如果使用SQL的執行功能,至少需要設定 DataSource 。

//新建一個DataSource(這裡使用了spring-jdbc的SimpleDriverDataSource)
//也可以使用支援連線池的各種DataSource,如DruidDataSource等
DataSource dataSource = new SimpleDriverDataSource(<...省略引數...>);

SQLFactory sqlFactory = new SQLFactory();
sqlFactory.setDataSource(dataSource);

2.3 從 SQLFactory 中獲取 SQL

既然有了 SQLFactory ,我們就可以從中獲得 SQL 的例項了。SQL類完全包含了面向資料庫執行 sql 命令所需的所有方法。 你可以通過 SQL 例項來構建並直接執行 SQL 語句。例如:

SQL sql = sqlFactory.sql();
Student student = sql.SELECT("*").FROM("student").WHERE("id=101").queryOne(Student.class);

2.4 作用域(Scope)和生命週期

SQLFactory

SQLFactory 一旦被建立就應該在應用的執行期間一直存在,沒有任何理由對它進行清除或重建。 使用 SQLFactory 的最佳實踐是在應用執行期間不要重複建立多次,多次重建 SQLFactory 被視為一種程式碼“壞味道(bad smell)”。 因此 SQLFactory 的最佳作用域是應用的作用域。有很多方法可以做到,最簡單的就是使用單例模式或者靜態單例模式 (如果在Spring環境中,利用Spring容器的功能,你完全可以把它設定為一個單例bean)。

SQL

SQL 例項是有狀態的 ,不是執行緒安全的,是不能被共享的。即使在同一個執行緒中每執行sql語句一次,都需要重新構建一個 SQL 例項。 絕對不能將 SQL 例項的引用放在一個類的靜態域,甚至一個類的例項變數也不行。

3 SQLFactory 配置

新建SQLFactory

SQLFactory sqlFactory = new SQLFactory();

指定DataSource

//新建任意型別一個DataSource,如SimpleDriverDataSource(Spring內部提供的)
//  或者其他支援連線池的DataSource
DataSource dataSource =  ... ;

//設定資料來源
sqlFactory.setDataSource(dataSource);

設定資料來源型別

sqlFactory.setDataSourceType(DataSourceType.POSTGRESQL);//預設
//支援 DataSourceType.POSTGRESQL、 DataSourceType.MY_SQL、DataSourceType.ORACLE

其他設定

sqlFactory.setQueryTimeout(5000);//設定最大超時時間
sqlFactory.setMaxRows(100);//查詢最大行數

4 使用SQL類構建sql語句

Java程式設計師面對的最痛苦的事情之一就是在Java程式碼中嵌入SQL語句。SQL類可以簡化你構建sql語句的過程。

4.1 基本查詢

SELECT方法可以傳入一個可變引數,以便選擇多列。(FastSQL中建議SQL關鍵字全部採用大寫)

sqlFactory.sql().SELECT("name", "age").FROM("student").WHERE("age>10").build();
//==> SELECT name,age FROM student WHERE age>10
sqlFactory.sql().SELECT("name", "age").FROM("student").WHERE("name='小紅'").build();
//==> SELECT name,age FROM student WHERE name='小紅'

WHERE()關鍵字生成WHERE 1=1語句,動態sql構建如下

SQL sql = sqlFactory.sql().SELECT("name", "age").FROM("student").WHERE();
if (true){
  sql.AND("age > 10");
}
if (false){
  sql.AND("age < 8");
}

//生成sql=>SELECT name,age  FROM student  WHERE 1 = 1  AND age > 10

4.2 使用操作符方法

FastSQL提供了一些操作符方便SQL的構建,比如:

sqlFactory.sql()
    .SELECT("name", "age")
    .FROM("student")
    .WHERE("age").lt("10")
    .AND("name").eq("'小明'")
    .build();
//生成sql=> SELECT name,age FROM student WHERE age < 10 AND name = '小明'

如下:

方法 說明
eq(String) 生成 = ,並追加引數(equal的縮寫)
gt(String) 生成 > ,並追加引數(是greater than的縮寫)
gtEq(String) 生成 >= ,並追加引數(是greater than or equal的縮寫)
lt(String) 生成 < ,並追加引數(是less than的縮寫 )
ltEq(String) 生成 <= ,並追加引數(是less than or equal的縮寫)
nEq(String) 生成 != ,並追加引數(是not equal的縮寫 )
LIKE(String) 生成 LIKE ,並追加引數,
NOT_LIKE(String) 生成 NOT LIKE ,並追加引數
IS_NULL() 生成 IS NULL
IS_NOT_NULL() 生成 IS NOT NULL
eq() 生成 =
gt() 生成 >
gtEq() 生成 >=
lt() 生成 <
ltEq() 生成 <=
nEq() 生成 !=
LIKE() 生成 LIKE
NOT_LIKE() 生成 NOT LIKE

byType(Object)

這些方法僅僅是字串連線:eq("1")生成= 1eq("'1'")會生成= '1'。byType(Object)方法可以根據型別生成你想要的sql字串

sqlFactory.sql()
        .SELECT("name", "age")
        .FROM("student")
        .WHERE("age").lt().byType(10)
        .AND("name").eq().byType("小明")
        .build();
//==>SELECT name,age FROM student WHERE age < 10 AND name = '小明'
方法 說明
byType(Object) 根據型別生成相應字串 ,如 byType(1)生成1 ,byType(“1”)生成’1’
eqByType(Object) 使用 = 連線根據型別生成相應的字串

4.3 使用連線查詢/排序

查詢不及格的成績

sqlFactory.sql().SELECT("s.name","c.subject_name","c.score_value")
        .FROM("score c")
        .LEFT_JOIN_ON("student s", "s.id=c.student_id")
        .WHERE("c.score_value<60")
        .ORDER_BY("c.score_value")
        .build();
/*
生成sql =>
SELECT s.name, c.subject,c.score_value
FROM score c
LEFT OUTER JOIN student s ON (s.id = c.student_id)
WHERE c.score_value < 60
ORDER BY c.score_value
*/

4.4 分組查詢

查詢每個學生總分數

sqlFactory.sql().SELECT("s.name", "sum(c.score_value) total_score")
        .FROM("score c")
        .LEFT_JOIN_ON("student s", "s.id=c.student_id")
        .GROUP_BY("s.name")
        .build()
/*
生成sql==>

SELECT s.name, sum(c.score_value) total_score
FROM score c
LEFT OUTER JOIN student s ON (s.id = c.student_id)
GROUP BY s.name
*/

4.5 IN語句

由於Jdbc規範不支援IN引數繫結,FastSQL提供了幾種IN語句直接拼接的方式:

//1.使用字串
sqlFactory.sql().SELECT("*")
   .FROM("student")
   .WHERE("name").IN("('小明','小紅')")
   .build();

//2.使用集合(List,Set等)
sqlFactory.sql().SELECT("*")
   .FROM("student")
   .WHERE("name").IN(Lists.newArrayList("小明","小紅"))
   .build();

//3.使用陣列
sqlFactory.sql().SELECT("*")
   .FROM("student")
   .WHERE("name").IN(new Object[]{"小明","小紅"})
   .build();

//4.使用可變引數(最簡潔)
sqlFactory.sql().SELECT("*")
   .FROM("student")
   .WHERE("name").IN_var("小明","小紅")
   .build();

//生成sql==> SELECT *  FROM student  WHERE name  IN ('小明','小紅')

4.6 使用KaTeX parse error: Expected group after '_' at position 1: _̲()方法進行子查詢

查詢大於平均分的成績(可以使用 KaTeX parse error: Expected group after '_' at position 1: _̲()方法)

sqlFactory.sql().SELECT("*")
   .FROM("score")
   .WHERE("score_value >")
   .$_$(
         sqlFactory.sql().SELECT("avg(score_value)").FROM("score")
    )
   .build();
//生成sql==>
//SELECT *  FROM score
//WHERE score_value >  ( SELECT avg(score_value)  FROM score  )

帶有IN的子查詢

sqlFactory.sql().SELECT("*")
    .FROM("score")
    .WHERE()
    .AND("score")
    .IN().$_$(
         sqlFactory.sql().SELECT("DISTINCT score_value").FROM("score")
    )
    .build();
//生成sql==> SELECT * FROM score WHERE 1 = 1 AND score IN (SELECT DISTINCT score_value FROM score)

注:複雜sql推薦使用字串直接構建:

String sql="SELECT * FROM score WHERE 1 = 1 AND score IN (SELECT DISTINCT score_value FROM score)";
sqlFactory.sql().str(sql);

4.7 AND和OR結合使用

如果查詢年齡大於10歲,並且名字是小明或小紅

sqlFactory.sql().SELECT("*")
   .FROM("student")
   .WHERE("age>10")
   .AND("(name='小明' OR name='小紅')")//手動新增括號
   .build();
//或者
sqlFactory.sql().SELECT("*")
   .FROM("student")
   .WHERE("age>10")
   .AND().$_$("name='小明' OR name='小紅'")//$_$ 生成左右括號
   .build();

4.8 使用Lambda表示式簡化構建動態sql

  • ifTrue(boolean bool, Consumer<SQL> sqlConsumer):如果第1個引數為true,則執行第二個引數(Lambda表示式)
  • ifNotEmpty(Collection<?> collection, Consumer<SQL> sqlConsumer):如果第1個引數長度大於0,則執行第二個引數(Lambda表示式)
  • ifPresent(Object object, Consumer<SQL> sqlConsumer):如果第1個引數存在(不等於null且不為""),則執行第二個引數(Lambda表示式)
  • ifEquals(Object object1, Object object2, Consumer<SQL> sQLConsumer):如果前兩個引數相等,則執行lambda表示式
sqlFactory.sql()
    .SELECT("student")
    .WHERE("id=:id")
    .ifTrue(true, sql -> thisBuilder.AND("name=:name"))
    .ifNotEmpty(names, sql -> {
        System.out.println("ifNotEmpty?");
        thisBuilder.AND("name").IN(Lists.newArrayList("小明", "小紅"));
    })
    .ifPresent("",sql -> {
        System.out.println("ifPresent?");
        //...處理其他流程語句...
    })
    .build();

輸出:

ifNotEmpty?
SELECT student WHERE id=:id AND name=:name AND name  IN ('小明','小紅')

4.9 分頁功能

使用原生關鍵字進行分頁

sqlFactory.sql().SELECT("*").FROM("student").LIMIT(10).build();
sqlFactory.sql().SELECT("*").FROM("student").LIMIT(5, 10).build(); //mysql中的寫法
sqlFactory.sql().SELECT("*").FROM("student").LIMIT(10).OFFSET(5).build(); //postgresql中的寫法

生成如下SQL

SELECT * FROM student LIMIT 10;
SELECT * FROM student LIMIT 5,10;
SELECT * FROM student LIMIT 10 OFFSET 5;

使用 pageThis(int,int) 分頁方法進行分頁

//
sqlFactory.setDataSourceType(DataSourceType.POSTGRESQL); //使用列舉指定資料來源型別
sqlFactory.sql().SELECT("*").FROM("student").pageThis(1,10).build();

注意:如果不指定 dataSourceType,將會預設使用 postgresql 資料庫型別進行分頁;

使用 countThis() 生成獲取數量語句

//countThis
sqlFactory.sql().SELECT("*").FROM("student").countThis().buildAndPrintSQL();

4.10 構建插入insert/修改update/刪除delete語句

插入

//使用列
sqlFactory.sql().INSERT_INTO("student", "id", "name", "age")
                .VALUES("21", "'Lily'", "12").build();
//=>INSERT INTO student (id,name,age)  VALUES (21,'Lily',12)

//不使用列
sqlFactory.sql().INSERT_INTO("student").VALUES("21", "'Lily'", "12").build();
//=>INSERT INTO student VALUES (21,'Lily',12)

修改

SET(String…items) :SET關鍵字

sqlFactory.sql().UPDATE("student").SET("name = 'Jack'","age = 9").WHERE("name = 'Mike'").build();
//=>  UPDATE student SET name = 'Jack',age = 9 WHERE name = 'Mike'

構建刪除語句

sqlFactory.sql().DELETE_FROM("student").WHERE("id=12").build();
//=>DELETE FROM student WHERE id=12

5 使用SQL類執行sql語句

5.1 建立SqlFactory

//建立任意DataSource物件(這裡使用了spring自帶的資料來源SimpleDriverDataSource)
DataSource dataSource = new SimpleDriverDataSource(
                new Driver(), "jdbc:postgresql://192.168.0.226:5432/picasso_dev2?stringtype=unspecified",
                "developer", "password");

//建立SqlFactory
SqlFactory sqlFactory = new SqlFactory();
sqlFactory.setDataSource(dataSource);
sqlFactory.setDataSourceType(DataSourceType.MY_SQL);

5.2 設定引數的方法

FastSQL支援多種傳入命名引數的方法:

  • parameter(SqlParameterSource) 支援傳入SqlParameterSource型別的引數(為了相容spring-jdbc)。
  • beanParameter(Object)方法可以傳入物件引數。
  • mapParameter(Map<String, Object>)支援傳入Map型別引數。
  • mapItemsParameter(Object...)支援多個key-value形式的引數,比如mapItemsParameter("id", 12345,"name","小明")
  • beanAndMapParameter(Object, Map<String, Object>) 支援兩種不同的引數組合,後一個map會覆蓋前面bean中的相同名字的引數。
  • addMapParameterItem(String, Object)可以為以上幾種傳參方法追加引數。

注意:以上方法除了addMapParameterItem只能呼叫一次,呼叫多次會導致前面的傳參被覆蓋。如需追加引數,請使用addMapParameterItem

FastSQL也支援?佔位符和可變引數:

  • varParameter(Object... vars) 傳入可變引數,可以呼叫多次,用來追加引數。

示例

使用beanParameter方法支援傳入一個引數bean

public class StudentDTO{
    private String name;
    private int age;
    //省略set和get方法
}
StudentDTO dto =new StudentDTO();
dto.setName="小明";
dto.setAge=10;

sqlFactory.sql().SELECT("*")
    .FROM("student")
    .WHERE("name=:name")
    .AND("age>:age")
    .beanParameter(dto)  //設定一個DTO查詢引數
    .queryList(StudVO.class);

使用beanParameter方法並追加引數

Map<String,Object> param = new HashMap<>();
map.put("name","李%");

sqlFactory.sql()
    .SELECT("*")
    .FROM("student")
    .WHERE("name").LIKE(":name")
    .AND("age > :age")
    .beanParameter(param)  //設定一個map引數
    .addParameterMapItem("age",12) //追加
    .queryList(Student.class);

使用varParameter方法–支援?佔位符和可變引數

SQL sql = sqlFactory.sql();
sql.INSERT_INTO("student", "id", "name", "age")
    .VALUES("?", "?", "?")
    .varParameter("123", "小明")
    .varParameter(12)
    .update();

5.3 查詢方法

5.3.1 查詢方法解析

  • T queryOne(Class<T> returnClassType)查詢單行結果封裝為一個物件,引數可以是可以為String/Integer/Long/Short/BigDecimal/BigInteger/Float/Double/Boolean或者任意POJO的class。
  • Map<String, Object> queryMap()查詢單行結果封裝為Map
  • List<T> queryList(Class<T> returnClassType)查詢多行結果封裝為一個物件列表
  • List<Map<String, Object>> queryMapList()查詢多行結果封裝為Map陣列
  • List<Object[]> queryArrayList() 查詢結果封裝為泛型為Object陣列的列表
  • ResultPage<T> queryPage(int page, int perPage, Class<T> returnClassType) 查詢結果頁

5.3.2 示例

StudentVO是查詢檢視類,包含name和age欄位;StudentDTO是查詢引數類,包含name欄位。

//queryList可以查詢列表,可以是基本型別列表或物件列表
List<String> strings = sqlFactory.sql().SELECT("name")
                .FROM("student")
                .queryList(String.class); //這裡執行查詢列表並指定返回型別

List<StudVO> studVOList = sqlFactory.sql().SELECT("name", "age")
                            .FROM(
            
           

相關推薦

輕量級資料庫訪問框架FastSQL

目錄 1 簡介 FastSQL一個基於spring-jdbc的簡單ORM框架,它支援sql構建、sql執行、命名引數繫結、查詢結果自動對映和通用DAO。結合了Hibernate/JPA快速開發和Mybatis高效執行的優點。 FastSQL可以完全滿足你控制慾

java中輕量級資料庫ORM框架:JOOQ

1、使用maven下載 <!-- https://mvnrepository.com/artifact/org.jooq/jooq --> <dependency> <gro

安卓本地輕量級資料庫操作框架 greenDao3.2.2 詳細教程附帶Demo②——增、刪、查、改。

歡迎來到安卓本地輕量級資料庫操作框架 greenDao3.2.2 學習之旅。 本套框架部落格系列部落格目錄: 最近一個月在忙做視訊,沒時間更新我們的greendao教程

Retrofit網絡訪問框架的學習

strong llb success getclass dial 使用 build 集合 aik Retrofit具體使用方法 1 import android.app.AlertDialog; 2 import android.content.DialogInt

Volley手寫屬於自己的萬能網絡訪問框架

info 鏈表實現 fas getname 字符串轉換成對象 gets 等等 stc exe 用戶在調用層(Activity或Service中),發起一個網絡請求,該請求肯定包含url,請求參數(requestParameter),以及我們需要給調用層提供一個請求成功或失敗

RF自定義資料庫訪問模組,連線mysql資料庫

程式碼簡單,不多贅述 import MySQLdb class Mysqlexc(): database_name = 'payment' host = '1.1.1.2' port = '3306' username = 'root' passwor

RF工具自定義linux命令列命令執行程式碼及資料庫訪問

之前寫了幾次資料庫連線和linux命令列執行的程式碼,在此儲存下。 另考慮到python2的中文編碼問題,註釋等都用簡單英文,見諒~  import paramiko class Excsshcmd(): ssh = paramiko.SSHClient()

SQL語句實現跨資料庫訪問

SQL語句實現跨資料庫訪問 第一步: 啟用Ad Hoc Distributed Queries語句:  exec sp_configure 'show advanced options',1  reconfigure  exec sp_configure 'Ad

springboot 使用Jpa 簡化資料庫訪問

1.先看看整個專案結構 建立一個springboot專案 2.修改pom檔案 1)新增外掛,順便把資料庫連線池也加進去 <plugin> <groupId>org.apache.maven.plugins</groupId>

資料庫訪問方式

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

轉:資料庫訪問效能優化

特別說明: 1、  本文只是面對資料庫應用開發的程式設計師,不適合專業DBA,DBA在資料庫效能優化方面需要了解更多的知識; 2、  本文許多示例及概念是基於Oracle資料庫描述,對於其它關係型資料庫也可以參考,但許多觀點不適合於KV資料庫或記憶體資

C# winfrom DBHelper 資料庫訪問

using System; using System.Data.SqlClient; using System.Data; using System.Collections.Generic; using System.Configuration; using System.Linq; using Sys

oracle資料庫訪問

1: 裝上ODBC-oracle驅動之後,配置資料來源的時候,用給的使用者名稱和密碼,彈出錯:unable to connect SQLState=28000[oracle][ODBC][Ora]ORA-01017 使用者名稱/口令無效,登入被拒絕 重新給一個賬戶,密碼,可以登入 2:配置資料來源成功後,

sqlservr.exe cpu使用率過高 (資料庫訪問有阻塞)-轉載

--1、統計佔用cpu最多的查詢,比如前10 SELECT TOP 10 total_worker_time AS TotalTime, total_worker_time/execution_count AS avg_cpu_cost, plan_handle, execution_co

易學筆記-系統分析師考試-第5章 資料庫系統/5.3 資料庫訪問介面

資料庫訪問介面 指的是應用程式與資料庫之間連線的部分 介面分類 專用呼叫 概念:資料庫發展初期,由於資料庫檔案格式不一致,操作方式也不相同,導致資料庫的訪問需要通過專用的API介面,這種方式成為專用資料庫 優點:執行

【TeeChart Pro ActiveX教程】(八):ADO資料庫訪問(上)

下載TeeChart Pro ActiveX最新版本 介紹 將TeeChart控制元件連線到ADO.NET資料庫可以在設計時使用TeeChart編輯器完成,並在執行時使用幾行程式碼完成。 任何Series都可以使用TeeChart Editor連線到ADO.NET表或查詢。每個系列

資料庫訪問介面(ODBC、OLE DB、ADO)

最近在學C#的資料庫程式設計,對於資料庫介面技術這塊的知識一直比較模糊,網上查了不少資料,看了幾天還是朦朦朧朧的,只能做些筆記再研究了。 我們都知道,“資料庫”是指一組相關資訊的集合,最早的計算機應用之一也是開發資料庫系統,即通過計算機來儲存和檢索資料的機制。 在資料庫發展的前幾十年裡,資料以各種不同的方

JavaWeb問題集錦: 解決Mysql資料庫訪問出現“Too many connections”問題

工作中程式碼中訪問資料庫連線的時候,程式碼執行中出現了"Too many connections" 的錯誤: MySQL "Too many connections" com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionE

《B/S模式下ADO.NET資料庫訪問技術的設計及應用》論文筆記(十七)

一、基本資訊 標題:B/S模式下ADO.NET資料庫訪問技術的設計及應用 時間:2014 來源:電子測試 關鍵詞:B/S模式; ADO.NET資料庫訪問技術; 設計; 應用; 二、研究內容 1.ADO.NET資料庫訪問技術的兩種模式: 連線模式下的資料庫訪問技術:

JDBC資料庫訪問(一)——JDBC簡介

目錄 1.JDBC簡介 JDBC API是Java API,可以用來訪問任意表格型別的資料,特別是儲存在關係型資料庫中的資料。 JDBC可以幫助編寫涉及以下三種程式設計活動的java應用 連線到資料來源(eg:資料庫) 給資料庫傳送查詢與