1. 時(shí)隔 6 年,曾經(jīng)的祝福區(qū)公眾號(hào)開(kāi)始想寫(xiě)代碼了

        共 13987字,需瀏覽 28分鐘

         ·

        2023-08-09 01:48

        最近我在思考對(duì)我的一個(gè)項(xiàng)目進(jìn)行更新,這個(gè)項(xiàng)目已經(jīng)有6年的歷史了。我打算采用JSR-269(可插拔注解處理API)重新設(shè)計(jì)一種使用代碼描述SQL的方式。這種方式類(lèi)似于C#中的Linq,可以實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的操作。


        在后續(xù)的更新中,會(huì)嘗試分享一下反射、MyBatis、APT 以及 ASM 的一些小知識(shí)


        以下是 6 年前的功能

           ad88                                                          88  
          d8"                             ,d                             88  
          88                              88                             88  
        MM88MMM  ,adPPYYba,  ,adPPYba,  MM88MMM  ,adPPYba,   ,adPPYb,d8  88  
          88     "
        "     `Y8  I8[    ""    88     I8[    ""  a8"    `Y88  88  
          88     ,adPPPPP88   `"Y8ba,     88      `"Y8ba,   8b       88  88  
          88     88,    ,88  aa    ]8I    88,    aa    ]8I  "8a    ,d88  88  
          88     `"
        8bbdP"Y8  `"YbbdP"'    "Y888  `"YbbdP"'   `"YbbdP'88  88  
                                                                     88      
                                                                     88      

        fastsql

        一個(gè)簡(jiǎn)單的數(shù)據(jù)庫(kù)工具類(lèi),可以簡(jiǎn)化 DB 操作,減少 SQL 語(yǔ)句的書(shū)寫(xiě),同時(shí)提供將 SQL 轉(zhuǎn)換 Bean 和將 Bean 轉(zhuǎn)換 SQL 的方法,

        Apache Maven

        <!-- https://mvnrepository.com/artifact/com.github.zyndev/fastsql -->
        <dependency>
            <groupId>com.github.zyndev</groupId>
            <artifactId>fastsql</artifactId>
        </dependency>

        FastSQL 主要特性如下:

        1. 遵循非侵入式原則,設(shè)計(jì)優(yōu)雅或簡(jiǎn)單,極易上手

        2. 支持安全查詢(xún),防止SQL注入

        3. 支持與主流數(shù)據(jù)庫(kù)連接池框架集成

        4. 支持 @Query 查詢(xún)

        5. 擁有非常優(yōu)雅的Page(分頁(yè))設(shè)計(jì)

        6. 支持單表ORM查詢(xún)

        7. 支持部分jpa注解

        8. 支持動(dòng)態(tài)SQL創(chuàng)建

        9. 支持駝峰標(biāo)識(shí)與下劃線(xiàn)標(biāo)識(shí)轉(zhuǎn)換

        運(yùn)行環(huán)境要求

        jdk1.8+

        入門(mén)例子

        • 準(zhǔn)備一個(gè)實(shí)體

        @Data
        @Entity
        @Table(name = "tb_user")
        public class User implements Serializable {

            private static final long serialVersionUID = 1L;

            @Id
            @Column
            private Integer id;

            @Column
            private String uid;

            @Column(name = "account_name")
            private String accountName;

            @Column(name = "nick_name")
            private String nickName;

            @Column
            private String password;

            @Column
            private String phone;

            @Column(name = "register_time")
            private Date registerTime;

            @Column(name = "update_time")
            private Date updateTime;

        }
        • DAO接口

        /**
         * @version 0.0.5
         * @author 張瑀楠 [email protected]
         */

        @Repository
        public interface UserRepository {

            @Query("select count(*) from tb_user")
            public Integer getCount();

            @Query("delete from tb_user where id = ?1")
            public Boolean deleteById(int id);

            @Query("select count(*) from tb_user where id = ?1")
            public Integer getCountByPassword(@Param("password") String password);

            @Query("select uid from tb_user where password = ?1 ")
            public String getUidByPassword(@Param("password") String password);

            @Query("select * from tb_user where id = :id ")
            public User getUserById(@Param("id") Integer id);

            @Query("select * " +
                    " from tb_user " +
                    " where account_name = :accountName ")
            public List<User> getUserByAccountName(@Param("accountName") String accountName);

            @Query("insert into tb_user(id, account_name, password, uid, nick_name, register_time, update_time) " +
                    "values(:id, :user.accountName, :user.password, :user.uid, :user.nickName, :user.registerTime, :user.updateTime )")
            public int saveUser(@Param("id") Integer id, @Param("user") User user);

            @ReturnGeneratedKey
            @Query("insert into tb_user(account_name, password, uid, nick_name, register_time, update_time) " +
                    "values(:user.accountName, :user.password, :user.uid, :user.nickName, :user.registerTime, :user.updateTime )")
            public int saveUser(@Param("user") User user);

            @Query("select * " +
                    " from tb_user " +
                    " where 1=1 " +
                    " @if(?1 != null ) { and name like concat('%',?1,'%')} ")
            public Map<Integer, User> queryUserByName(String name);

        }
        • 使用DAO接口.

        該項(xiàng)目主要為了和Spring項(xiàng)目整合使用,這里可以直接通過(guò)自動(dòng)注入方式使用,后面會(huì)講到如何整合到Spring MVCSpring Boot項(xiàng)目,暫時(shí)這里使用注入的方式

        @Autowired
        private UserRepository userRepository;

        這里直接調(diào)用指定的方法即可

        關(guān)于 @Query 的使用

        在上面的示例中,使用了類(lèi)似JPAQuery方式,這里講解一下

        參數(shù)通過(guò)兩種方式指定

        1. 位置參數(shù)

        2. 命名參數(shù)

        在上面的Query 語(yǔ)句中,大致可分為以下三類(lèi):

        1. 不需要參數(shù)

        這類(lèi)查詢(xún)不需要參數(shù)

        @Query("select count(*) from tb_user")
        public Integer getCount();
        1. 位置參數(shù)

        這類(lèi)需要初入?yún)?shù),在語(yǔ)句中可以使用 ?1 ?2 等指定

        注意:這里從 1 開(kāi)始計(jì)數(shù),而不是0

        @Query("delete from tb_user where id = ?1")
        public Boolean deleteById(int id);
        1. 命名參數(shù)

        使用 @Param 進(jìn)行處理,在語(yǔ)句中可以使用 :xxx :xxxx 等指定

        例如:

        @Query("select * from tb_user where id = :id ")
        public User getUserById(@Param("id") Integer id);

        位置參數(shù)和命名參數(shù)可以混用

        注意:在沒(méi)有查詢(xún)到數(shù)據(jù)的情況下,如果返回值是集合類(lèi)型,返回具體的值不會(huì)是null,而是一個(gè)空集合. 如果是對(duì)象,則返回 null

        條件表達(dá)式

        根據(jù)業(yè)務(wù)我們經(jīng)常需要?jiǎng)討B(tài)的構(gòu)建sql,例如mybatisif標(biāo)簽,在這里也提供了一種語(yǔ)法 @if( condition) { statement },其中 condition 為一個(gè)布爾語(yǔ)句,當(dāng)
        語(yǔ)句成立時(shí),拼接后面的 statement

        例如:

        @Query("select * " +
                " from tb_user " +
                " where 1=1 " +
                " @if(?1 != null ) { and name like concat('%',?1,'%')} ")
        public List<User> queryUserByName(String name);

        當(dāng) namenull 時(shí),則查詢(xún)語(yǔ)句為 select * from tb_user where 1=1,
        否則為 select * from tb_user where 1=1 and name like concat('%',?1,'%')

        注意

        注意: 查詢(xún)單個(gè)字段,還支持返回如下類(lèi)型:

        • String

        • Bytebyte

        • Shortshort

        • Integerint

        • Longlong

        • Floatfloat

        • Doubledouble

        • Characterchar

        • Booleanboolean

        注解使用

        Annotation 作用
        @Query 標(biāo)識(shí)查詢(xún)語(yǔ)句
        @Param 標(biāo)識(shí)命名參數(shù)
        @ReturnGeneratedKey 返回自增主鍵id

        BaseRepository的內(nèi)置方法

        這里的entity比如有 @Entity 注解

        // 驗(yàn)證id是否存在
        <T> boolean existsById(T entity);

        // 統(tǒng)計(jì)entity的數(shù)量
        <T> long count(T entity);

        // 保存一個(gè)entity, null屬性 不插入
        <T> int save(T entity);

        // 保存多個(gè)entity, null屬性 不插入
        <T> int saveAll(Iterable<T> entities);

        // 保存一個(gè)entity, 并設(shè)置null屬性 是否插入
        <T> int save(T entity, boolean ignoreNull);

        // 保存多個(gè)entity, 并設(shè)置null屬性 是否插入
        <T> int saveAll(Iterable<T> entities, boolean ignoreNull);

        // 刪除一個(gè)對(duì)象
        <T> int deleteById(T entity);

        // 刪除符合條件的相似對(duì)象
        <T> int delete(T entity);

        // 刪除多個(gè)對(duì)象,其中每個(gè)對(duì)象必須有id
        <T> int deleteAll(Iterable<T> entities);

        // 更新一個(gè)對(duì)象,其中對(duì)象必須有id,null 值不更新
        <T> int update(T entity);

        // 更新一個(gè)對(duì)象,其中對(duì)象必須有id,并設(shè)置null是否更新
        <T> int update(T entity, boolean ignoreNull);

        // 更新多個(gè)對(duì)象,其中對(duì)象必須有id,null 值不更新
        <T> int update(Iterable<T> entities);

        // 更新多個(gè)對(duì)象,其中對(duì)象必須有id,并設(shè)置null是否更新
        <T> int update(Iterable<T> entities, boolean ignoreNull);

        <T> findById(T entity);

        // 只查詢(xún)指定的字段
        <T> findById(T entity, String... columns);

        <T> List<T> getEntityList(T entity);

        <T> List<T> getEntityList(T entity, String... columns);

        <T> List<T> getEntityListBySQL(String sql, T entity);

        <T> List<T> getEntityListBySQL(String sql, Object[] args, T entity);

        <T> PageListContent<T> getEntityPageList(T entity, int pageNum, int pageSize);

        <T> PageListContent<T> getEntityPageList(T entity, int pageNum, int pageSize, String orderBy);

        <T> PageListContent<T> getEntityPageList(T entity, int pageNum, int pageSize, String orderBy, String... columns);

        <T> PageListContent<T> getEntityPageListBySql(String sql, T entity, int pageNum, int pageSize);

        <T> PageListContent<T> getEntityPageListBySql(String sql, T entity, int pageNum, int pageSize, String orderBy);

        <T> PageListContent<T> getEntityPageListBySql(String sql, Object[] args, T entity, int pageNum, int pageSize, String orderBy);

        分頁(yè)

        BaseRepository內(nèi)置分頁(yè)方法

        <T> PageListContent<T> getEntityPageList(T entity, int pageNum, int pageSize);

        <T> PageListContent<T> getEntityPageList(T entity, int pageNum, int pageSize, String orderBy);

        <T> PageListContent<T> getEntityPageList(T entity, int pageNum, int pageSize, String orderBy, String... columns);

        <T> PageListContent<T> getEntityPageListBySql(String sql, T entity, int pageNum, int pageSize);

        <T> PageListContent<T> getEntityPageListBySql(String sql, T entity, int pageNum, int pageSize, String orderBy);

        <T> PageListContent<T> getEntityPageListBySql(String sql, Object[] args, T entity, int pageNum, int pageSize, String orderBy);


        瀏覽 108
        點(diǎn)贊
        1評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        全部評(píng)論
        仙逆2023-08-09 17:20
        10 分
        寫(xiě)的不錯(cuò),很收益
        點(diǎn)贊回復(fù)
        推薦
        點(diǎn)贊
        1評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 国产精品久久久久久久久久久新郎 | 黄视频在线 | 操逼逼视频免费看 | 在线无码成人电影 | 在线播放少妇奶水过盛 |