精华内容
下载资源
问答
  • 关于代码生成器反复生成代码的设计。...前几天在中增加字段之后,手工写了不少代码 :(((受 charon@xxx 的回复的提示,结合myeclipse生成 pojo的思路,对我的代码生成器进行改进,作以下处理。以dao为例(其它logi...

    关于代码生成器反复生成代码的设计。

    我以前的做法是先生成尽可能详细的代码。

    (生成findby方法基本把每个字段都列在了查询条件里,包括一些基本用不到的)

    然后只需要复制其中的代码片断来完成需要新加的方法。

    前几天在表中增加字段之后,手工写了不少代码 :(((

    受 charon@xxx 的回复的提示,结合myeclipse生成 pojo的思路,

    对我的代码生成器进行改进,作以下处理。

    以dao为例(其它logic等均作类似处理),定义两个接口。和对应两个实现。

    写成四个模板文件。

    比如IpojoBaseDAO.java,pojoBaseDAOImpl.java abstract的,但是实现IpojoBaseDAO里的方法。

    这个是可以反复生成的。

    再定义两个继承类模板。

    IpojoDAO.java 继承自IpojoBaseDAO

    pojoDAOImpl.java 继承自 pojoBaseDAOImpl。实现IpojoDAO。

    这两个文件只需要生成一次,以后自己增加的代码都在这里。

    在第一次生成好代码之后,把这两文件名后缀改为.bak.这样再运行代码生成器的时候就不会再生成了。

    不废话了,看生成的效果。

    接口:

    IBlogPostBaseDAO.java

    本文件可以反复生成。

    public interface IBlogPostBaseDAO{

    void addBlogPost(BlogPost blogPost);

    List findBlogPostby(

    java.lang.String blogNo,

    java.util.Date addtime_begin,

    java.util.Date addtime_end,

    java.lang.String blogUserName,

    java.lang.String blogTitle,

    java.lang.String blogContent,

    java.lang.String blogSummary,

    Pagination page);

    }

    IBlogPostDAO.java

    //本文件只需要生成一次

    public interface IBlogPostDAO extends  IBlogPostBaseDAO{

    void testBlogPost(BlogPost blogPost); //在这里增加手工补充的具体接口方法

    }

    BlogPostHibernateBaseDAO.java

    //本文件可以反复生成。

    public class BlogPostHibernateBaseDAO extends HibernateBaseDAOSupport implements IBlogPostDAO {

    private static final transient Logger log = Logger.getLogger(BlogPostHibernateBaseDAO.class);

    public BlogPostHibernateBaseDAO() {

    }

    public void addBlogPost(BlogPost blogPost){

    this.getHibernateTemplate().save(blogPost);

    }

    //多条件分页查询

    public List findBlogPostby(

    final java.lang.String blogNo,

    final java.util.Date addtime_begin,

    final java.util.Date addtime_end,

    final java.lang.String blogUserName,

    final java.lang.String blogTitle,

    final java.lang.String blogContent,

    final java.lang.String blogSummary,

    final Pagination page){

    return (List)this.getHibernateTemplate().execute(

    new HibernateCallback() {

    public Object doInHibernate(Session session) throws SQLException,

    HibernateException {

    Criteria ca = session.createCriteria(BlogPost.class);

    if (blogNo != null && blogNo.length() > 0) {

    ca.add(Expression.like("blogNo", blogNo, MatchMode.ANYWHERE));

    }

    if (addtime_begin != null) {

    ca.add(Expression.ge("addtime", addtime_begin));

    }

    if (addtime_end != null) {

    ca.add(Expression.le("addtime", addtime_end));

    }

    if (blogUserName != null && blogUserName.length() > 0) {

    ca.add(Expression.like("blogUserName", blogUserName, MatchMode.ANYWHERE));

    }

    if (blogTitle != null && blogTitle.length() > 0) {

    ca.add(Expression.like("blogTitle", blogTitle, MatchMode.ANYWHERE));

    }

    if (blogContent != null && blogContent.length() > 0) {

    ca.add(Expression.like("blogContent", blogContent, MatchMode.ANYWHERE));

    }

    if (blogSummary != null && blogSummary.length() > 0) {

    ca.add(Expression.like("blogSummary", blogSummary, MatchMode.ANYWHERE));

    }

    if (page != null) {

    page.setTotalNum(((Integer) ca.setProjection(Projections.

    rowCount()).uniqueResult()).intValue());

    }

    ca.setProjection(null);

    ca.addOrder(Order.desc("addtime"));//

    if (page != null) {

    ca.setMaxResults(page.getPageSize());

    ca.setFirstResult(page.getStartIndex());

    }

    return ca.list();

    }

    }, true);

    }

    }

    BlogPostHibernateDAO.java

    //本文件只需要生成一次

    public class BlogPostHibernateDAO extends BlogPostHibernateBaseDAO implements IBlogPostDAO{

    private static final transient Logger log = Logger.getLogger(BlogPostHibernateDAO.class);

    public BlogPostHibernateDAO() {

    }

    public void testBlogPost(BlogPost blogPost){

    //手工的代码了

    }

    }

    以上代码,除了斜线后的注释,都是代码生成器生成的,受篇幅限制,作了大量的删减

    展开全文
  • 在ACCESS环境中用rnd函数解决,以下查询展示了如何从中随机抽取10条记录 SELECT top 10 * FROM tbl1 ORDER BY Rnd(id) 另外, Rnd(id) 其中的id只是为了提供一个种子,可以利用其他任何数值来完成 id字段是自动...

    方法一:
    在ACCESS环境中用rnd函数解决,以下查询展示了如何从表中随机抽取10条记录
    SELECT top 10 * FROM tbl1 ORDER BY Rnd(id)
    另外, Rnd(id) 其中的id只是为了提供一个种子,可以利用其他任何数值来完成
    id字段是自动编号字段,也可以用其他字段代替,只要能生成数值就行。
    如果每次RND得到的结果都一样,那是因为没有使用 Randomize 语句来初始化随机数生成器。

    方法二:
    在ASP、VB中无法使用上述方法,可以参考使用adodb.recordset.recordcount 属性以及 adodb.recordset.AbsolutePosition 以及 RND 函数来解决问题。
    Function RndID()
        Dim rs As New ADODB.Recordset
        Dim strsql As String
        strsql = "select * from tbl1"
        rs.CursorLocation = adUseClient
        rs.Open strsql, CurrentProject.Connection, 2, 3
        '在Access中可以使用 CurrentProject.Connection,
        '其他语言中可以用 ADODB.CONNECTION对象。
       
        Dim i As Long
        Dim lngCount As Long
        Dim lngRnd As Long
        lngCount = rs.RecordCount
        '一下取前10条随机记录
        For i = 1 To 10
            lngRnd = Int((lngCount * Rnd) + 1)
            rs.AbsolutePosition = lngRnd
            Debug.Print rs("id")
        Next
    End Function


    方法三:
    用当前 TIME 做种子生成随机数。如果时间重复最终还是重复,没有从根本上解决问题,说白了还是种子的问题。要不重复就要彻底解决种子的问题,如果能取得毫秒级时间就基本能解决了
    或者建议在组织 SQL 语句的时候有意插入一个 VB 函数生成的随机值作为种子也可以
    Dim sql
    Dim RNUM
    Randomize
    RNUM = Rnd
    sql = "select top 1 * from tbl1 order by rnd(" & RNUM & "-id)"

    其中,方法三已经经过验证,可以使用。

    附:
    关于用 SQL 得到 Access 的随机记录集    
    此问题早已有人提出,解决的方法也非原创。写这篇东西,意在共同探讨。毕竟目前还没有非常满意的结论。先说说现在网上大多数转贴是这样说的:

    SQL Server 2000:
    SELECT TOP n * FROM tanblename ORDER BY NEWID()

    Access:
    SELECT TOP n * FROM tanblename ORDER BY rnd([一个自动编号字段])

    SQL 有了 NEWID() 就无须多讲拉,但 Access 中没有,所以寄望于 RND,实际上这条语句在 Access 中的“查询”中是可以运行并得到随机结果的,但在 ASP 中却无法得到预期的随机效果——无论如何刷新得到的结果都是一样的(就算在语句前加上 Randomize 也一样于事无补)。

    当然,也不少其他的解决方法,用数组的,用循环的……不好说不对,但总觉得跑题了。后来有另外的朋友试验出这个方法:表 TestTable,有自动编号字段 TestID,标题字段 TestTitle,随机取得5条纪录,用代码:

    Randomize
    SELECT TOP 5 [TestTitle] FROM [TestTable] ORDER BY Rnd(-(TestID+"&Rnd()&"))

    实际上,我目前需要应用到随机纪录的地方就是用的这条语句,除此我没有其他更好的方法(但用过才知道,其实这条语句偶然会生成重复纪录的)。也许你会有更好的方法……

    转载于:https://www.cnblogs.com/cole2295/archive/2009/07/11/1520997.html

    展开全文
  • 接上一篇关于自动生成费用并添加附件发送的博客,个人认为还需优化的有一处: 当数据量大时,所耗时间相应增加,尤其是读取记录的时间。当模拟10万条业务记录的excel,运行所耗时间就比较长了,从查询生成表格...

    接上一篇关于自动生成费用表并添加附件发送的博客,个人认为还需优化的有一处:

    当数据量大时,所耗时间相应增加,尤其是读取记录的时间。当模拟10万条业务记录的excel,运行所耗时间就比较长了,从查询到生成表格损耗时间为30s左右。自己仍在学习如何优化中,比如使用数据库是否查询效能更快等。

     以下为生成模拟十万条记录的python代码,主要用numpy和pandas库。模拟数据保存到本地的新excel中。

    import pandas as pd
    import numpy as np
    import openpyxl
    import datetime as datetime
    
    '''生成模拟数据,假设每天有1000条业务记录,编号为DZ181201332001-DZ181201332999,共100天,10万条记录'''
    len_of_index=100000
    days=round(len_of_index/1000)
    date1='2018-10-10'
    date_01=datetime.datetime.strptime(date1,"%Y-%m-%d")
    date_temp=date_01
    date_index=[]
    date_list=[]
    for i in range(days):
        date_temp+=datetime.timedelta(days=1)
        date_temp_str=datetime.datetime.strftime(date_temp,'%y%m%d')
        for j in range(1000):
            date_list.append(datetime.datetime.strftime(date_temp,'%Y-%m-%d'))
            date_index_element='DZ'+date_temp_str+'332'+"%03d"%j
            date_index.append(date_index_element)
            i+=1
    
    df=pd.DataFrame(np.arange(100000))
    df['id']=date_index
    df['date_of_pay']=date_list
    df['down_co']=['ABC公司','BCD公司','CDE公司','DEF公司']*25000
    df['down_co_sim']=['ABC','NCD','CDE','DEF']*25000
    df['vin']='xxxxxxxxxxxxxxxx'
    df['total_price']=np.arange(200000,1200000,10)
    df['rate']=0.0004
    df['num_of_cars']=1
    df['bbd_to_up']=0
    df['bbd_to_us']=df['total_price']*0.2
    df['acc_fin']='公司A账户'
    df['brand']=['宝马x5','路虎揽胜','宾利','奔驰GLK']*25000
    df['ad_pay']=df['total_price']*0.8
    df['other_fee']=0
    df['rece_fee']=0
    
    writer=pd.ExcelWriter(r'模拟十万条数据.xlsx')
    df.to_excel(writer,'sheet1')
    writer.save()

     

    展开全文
  • 也会说到一些扩展以及其他高级用法从此篇幅开始,以下代码块中不再详细编写关于DSLContext的创建过程,具体可以看 section-1 中讲解的基础初始化方式dslContext 代表DSLContext实例S1_USER 由jOOQ插件生成...

    通过 DSLContext API 和 Record API,可以完成基础CURD操作。本篇主要通过一些实例代码,讲解最基础的用法。后面的相关篇幅中,也会说到一些扩展以及其他高级用法

    从此篇幅开始,以下代码块中不再详细编写关于DSLContext的创建过程,具体可以看 section-1 中讲解的基础初始化方式dslContext 代表DSLContext实例

    S1_USER 由jOOQ插件生成的表描述常量

    S1_USER.* 由jOOQ插件生成的表内字段常量

    Insert

    jOOQ的数据操作通常有两种方式, 第一种是使用 DSLContext API 以类SQL的语法进行调用,第二种是利用 Record API 进行调用

    类SQL方式

    插入操作,最基础的方式,是以写SQL语句的习惯,调用API进行插入,支持批量插入

    // 类SQL语法 insertInto 方法第一个参数通常是表常量dslContext.insertInto(S1_USER, S1_USER.USERNAME, S1_USER.ADDRESS, S1_USER.EMAIL)

    .values("username1", "demo-address1", "diamondfsd@gmail.com")

    .values("username2", "demo-address2", "diamondfsd@gmail.com")

    .execute();

    // newRecord() 方法标识添加一条记录,通过链式调用,支持批量插入dslContext.insertInto(S1_USER)

    .set(S1_USER.USERNAME, "usernameSet1")

    .set(S1_USER.EMAIL, "diamondfsd@gmail.com")

    .newRecord()

    .set(S1_USER.USERNAME, "usernameSet2")

    .set(S1_USER.EMAIL, "diamondfsd@gmail.com")

    .execute();

    Record API

    除了通过编写类SQL的API方式插入数据之外,还可以通过Record的API进行插入数据 - dslContext.newRecord 方法根据表来创建一个Record对象,可以通过 record.insert() 方法插入数据

    S1UserRecord record = dslContext.newRecord(S1_USER);

    record.setUsername("usernameRecord1");

    record.setEmail("diamondfsd@gmail.com");

    record.setAddress("address hello");

    record.insert();

    批量插入

    dslContext.batchInsert(Collection extends TableRecord>> records)方法,可以进行批量插入操作,由jOOQ生成的S1UserRecord实现了TableRecord接口

    List recordList = IntStream.range(0, 10).mapToObj(i -> {

    S1UserRecord s1UserRecord = new S1UserRecord();

    s1UserRecord.setUsername("usernameBatchInsert" + i);

    s1UserRecord.setEmail("diamondfsd@gmail.com");

    return s1UserRecord;

    }).collect(Collectors.toList());

    dslContext.batchInsert(recordList).execute();

    插入后获取自增主键通过类SQL方式

    通过此方法插入数据,可以通过 returning API读取想要返回的数据,此语法支持返回多个值,通过fetchOne()方法可以取到一个Record对象

    Integer userId = dslContext.insertInto(S1_USER,

    S1_USER.USERNAME, S1_USER.ADDRESS, S1_USER.EMAIL)

    .values("username1", "demo-address1", "diamondfsd@gmail.com")

    .returning(S1_USER.ID)

    .fetchOne().getId();Record API 通过此方法,自增的主键会自动存入record中

    S1UserRecord record = dslContext.newRecord(S1_USER);

    record.setUsername("usernameRecord1");

    record.setEmail("diamondfsd@gmail.com");

    record.setAddress("address hello");

    record.insert();

    // 这里的id是插入后数据库返回的自增ID,会自动存入record中,可以通过get方法获取record.getId();

    主键重复处理

    可以针对主键重复时,做两种操作,一种是忽略插入,一种是进行更新操作主键重复忽略插入

    int affecteRow = dslContext.insertInto(S1_USER,

    S1_USER.ID, S1_USER.USERNAME)

    .values(1, "username-1")

    .onDuplicateKeyIgnore()

    .execute();

    // 这里执行完,返回affecteRow影响行数为0// 生成的SQL: insert ignore into `learn-jooq`.`s1_user` (`id`, `username`) values (1, 'username-1')主键重复进行更新

    dslContext.insertInto(S1_USER)

    .set(S1_USER.ID, 1)

    .set(S1_USER.USERNAME, "duplicateKey-insert")

    .set(S1_USER.ADDRESS, "hello world")

    .onDuplicateKeyUpdate()

    .set(S1_USER.USERNAME, "duplicateKey-update")

    .set(S1_USER.ADDRESS, "update")

    .execute();

    // 生成SQL: insert into `learn-jooq`.`s1_user` (`id`, `username`, `address`) values (1, 'duplicateKey-update', 'hello world') on duplicate key update `learn-jooq`.`s1_user`.`username` = 'duplicateKey-update', `learn-jooq`.`s1_user`.`address` = 'update'

    Update

    update和insert的用法类似,都是有两种方式进行操作

    类SQL方式

    dslContext.update(S1_USER)

    .set(S1_USER.USERNAME, "apiUsername-1")

    .set(S1_USER.ADDRESS, "update-address")

    .where(S1_USER.ID.eq(1))

    .execute()

    Record API

    Record 方式默认通过主键进行作为update语句的where条件

    S1UserRecord record = dslContext.newRecord(S1_USER);

    record.setId(1);

    record.setUsername("usernameUpdate-2");

    record.setAddress("record-address-2");

    record.update();

    // 生成SQL: update `learn-jooq`.`s1_user` set `learn-jooq`.`s1_user`.`id` = 1, `learn-jooq`.`s1_user`.`username` = 'usernameUpdate-2', `learn-jooq`.`s1_user`.`address` = 'record-address-2' where `learn-jooq`.`s1_user`.`id` = 1

    S1UserRecord record2 = dslContext.newRecord(S1_USER);

    record2.setUsername("usernameUpdate-noID");

    record2.update();

    // 生成SQL: update `learn-jooq`.`s1_user` set `learn-jooq`.`s1_user`.`username` = 'usernameUpdate-noID' where `learn-jooq`.`s1_user`.`id` is null

    批量更新

    可以使用 dslContext.batchUpdate 进行批量更新,批量更新还是通过主键条件进行拼接update语句,和之前规则相同

    S1UserRecord record1 = new S1UserRecord();

    record1.setId(1);

    record1.setUsername("batchUsername-1");

    S1UserRecord record2 = new S1UserRecord();

    record2.setId(2);

    record2.setUsername("batchUsername-2");

    List userRecordList = new ArrayList<>();

    userRecordList.add(record1);

    userRecordList.add(record2);

    dslContext.batchUpdate(userRecordList).execute();

    Select

    查询操作基本都是通过类SQL的语法进行操作

    单表查询

    基本查询方法,默认查询指定表的所有字段,返回一个结果集的包装,通过Result.into方法,可以将结果集转换为任意指定类型集合,当然也可以通过 Record.getValue 方法取得任意字段值,值类型依赖于字段类型

    // select `learn-jooq`.`s1_user`.`id`, `learn-jooq`.`s1_user`.`username`, `learn-jooq`.`s1_user`.`email`, `learn-jooq`.`s1_user`.`address`, `learn-jooq`.`s1_user`.`create_time`, `learn-jooq`.`s1_user`.`update_time` from `learn-jooq`.`s1_user`Result fetchResult = dslContext.select().from(S1_USER).fetch();

    List result = fetch.into(S1UserRecord.class);

    // select `learn-jooq`.`s1_user`.`id`, `learn-jooq`.`s1_user`.`username`, `learn-jooq`.`s1_user`.`email`, `learn-jooq`.`s1_user`.`address`, `learn-jooq`.`s1_user`.`create_time`, `learn-jooq`.`s1_user`.`update_time` from `learn-jooq`.`s1_user` where `learn-jooq`.`s1_user`.`id` in (1, 2)Result fetchAll = dslContext.select().from(S1_USER)

    .where(S1_USER.ID.in(1, 2)).fetch();

    fetchAll.forEach(record -> {

    Integer id = record.getValue(S1_USER.ID);

    String username = record.getValue(S1_USER.USERNAME);

    String address = record.getValue(S1_USER.ADDRESS);

    Timestamp createTime = record.getValue(S1_USER.CREATE_TIME);

    Timestamp updateTime = record.getValue(S1_USER.UPDATE_TIME);

    });

    关联查询

    多表关联查询也很简单,和写SQL的方法类似,关联查询出来的结果集,可以自定义一个POJO来储存数据

    新建一个POJO,用于储存查询结果

    public class UserMessagePojo {

    private String username;

    private String messageTitle;

    private String messageContent;

    //... getter/setter}

    之前说过通过into方法可以将结果或结果集转换为任意类型,jOOQ会通过反射的方式,将对应的字段值填充至指定的POJO中。通过关联查询的结果集,可以使用此方法将查询结果转换至指定类型的集合。

    Result> record3Result =

    dslContext.select(S1_USER.USERNAME,

    S2_USER_MESSAGE.MESSAGE_TITLE,

    S2_USER_MESSAGE.MESSAGE_CONTENT)

    .from(S2_USER_MESSAGE)

    .leftJoin(S1_USER).on(S1_USER.ID.eq(S2_USER_MESSAGE.USER_ID))

    .fetch();

    List userMessagePojoList = record3Result.into(UserMessagePojo.class);

    Delete

    类SQL方式

    通过此方式可以灵活的构建条件进行删除操作

    dslContext.delete(S1_USER).where(S1_USER.USERNAME.eq("demo1")).execute();

    Record API方式

    Record.detele() 方法可以进行删除操作,通过调用此方法是根据对应表的主键作为条件进行删除操作

    S1UserRecord record = dslContext.newRecord(S1_USER);

    record.setId(2);

    int deleteRows = record.delete();

    // deleteRows = 1// SQL: delete from `learn-jooq`.`s1_user` where `learn-jooq`.`s1_user`.`id` = 2

    S1UserRecord record2 = dslContext.newRecord(S1_USER);

    record2.setUsername("demo1");

    int deleteRows2 = record2.delete();

    // deleteRows == 0// SQL: delete from `learn-jooq`.`s1_user` where `learn-jooq`.`s1_user`.`id` is null

    批量删除

    通过此方法可以进行批量删除操作

    S1UserRecord record1 = new S1UserRecord();

    record1.setId(1);

    S1UserRecord record2 = new S1UserRecord();

    record2.setId(2);

    dslContext.batchDelete(record1, record2).execute();

    //List recordList = new ArrayList<>();

    recordList.add(record1);

    recordList.add(record2);

    dslContext.batchDelete(recordList).execute();

    POJO和代码生成器配置

    之前代码中,进行关联查询时,对于结果集的处理比较麻烦,需要自己创建POJO类进行操作。在实际业务中,多表关联查询是很经常的事情,如果每个查询的结果都需要自己创建POJO来储存数据,那也是不小的工作了,而且操作起来还很繁琐,需要确认每个字段的名称以及类型

    对于这样的情况,可以通过jOOQ的代码生成器来解决。代码生成器可以配置在生成代码时,同时生成和表一一对应的POJO,只需要在生成器配置generator块中,加上相关配置即可:

    true

    通过以上配置,代码生成的时候,会同时生成和表一一对应的POJO类。因为jOOQ的代码生成每次都是全量生成的,那么我们在编写相关业务代码的时候,不能去修改jOOQ生成的所有代码,那么在关联查询的时候,我们如果要基于原有的某个POJO添加其他字段,那么我们可以自己创建一个和表名一致的类,然后继承该POJO对象,在添加上我们需要的字段,例如本篇代码实例中的s2_user_message表,在这里我们需要将这张表和s1_user表进行关联查询,为了是查出用户ID对应的用户名

    那么我们之前定义的 UserMessagePojo 变成直接继承POJO类 S2UserMessage,然后添加需要关联查询的字段名:

    public class UserMessagePojo extends S2UserMessage {

    private String username;

    public String getUsername() {

    return username;

    }

    public void setUsername(String username) {

    this.username = username;

    }

    }

    添加POJO的生产配置后,jOOQ最终生成的目录如下图,比之前来说,多了一个pojos包,用于存放所有POJO

    ├─src/main/java/.../codegen ---- // 生成路径

    │ ├─tables --------------------- // 表定义目录

    │ │ ├─pojos -------------------- // 存放和表一一对应的 POJO 类

    │ │ └─records ------------------ // 表Record对象目录

    │ ├─DefaultCatalog ------------- // Catalog对象,包含Schema常量

    │ ├─Indexes -------------------- // 当前数据库所有的所有常量

    │ ├─Keys ----------------------- // 当前数据库所有表主键,唯一索引等常量

    │ ├─LearnJooq ------------------ // 数据库`learn-jooq`常量,包含该库所有表描述常量

    │ └─Tables --------------------- // 所有数据库表常量

    于此同时,我们也发现,pojos目录下的所有POJO类名和 tables 目录下所有表描述对象的类名一致,这样开发时,有个麻烦,就是引用的时候还需要去关注所在包路径,不能直观的看出哪个是表描述类或者是POJO类,而且在同一个类中同时用到POJO和表描述类时,会出现要引用全路径的类(xx.xx.xx.XXXX)的情况,降低了代码的可读性

    那么如何解决这个问题呢,jOOQ在代码生成的时候,是通过 org.jooq.codegen.GeneratorStrategy 接口,来确定所有文件名称的生成规则。在代码生成器配置中,提供了参数可以自己指定该接口的实现类:

    com.diamondfsd.jooq.learn.CustomGeneratorStrategy

    CustomGeneratorStrategy 自定义的生成器继承了原有的 DefaultGeneratorStrategy,重写了 getJavaClassName 这方法。主要是为了区别出 POJO 和 表描述的类名,通过这样的配置生成出来的POJO名称会变为类似 S2UserMessagePojo,表描述类名为 TS2UserMessage,这样能更好的区分POJO和表描述类名,避免在编码过程中产生由于import错误的类,而导致的代码问题。

    public class CustomGeneratorStrategy extends DefaultGeneratorStrategy {

    @Override

    public String getJavaClassName(Definition definition, Mode mode) {

    String result = super.getJavaClassName(definition, mode);

    switch (mode) {

    case POJO:

    result +="Pojo";

    break;

    case DEFAULT:

    if (definition instanceof TableDefinition) {

    result = "T" + result;

    }

    break;

    default:

    break;

    }

    return result;

    }

    }

    这样我们可以将之前的继承类去除后缀

    public class S2UserMessage extends S2UserMessagePojo {

    private String username;

    public String getUsername() {

    return username;

    }

    public void setUsername(String username) {

    this.username = username;

    }

    }

    另外要注意的是,POJO的继承类,不可以放在jOOQ代码生成目标的包内,因为生成代码时,会删除指定目标包内的所有内容,所以由我们自行创建的POJO类,需要放在和代码生成器目标包的同级或者上级包内,才不会被jOOQ的代码生成器删除

    例如jOOQ生成器的目标包名为: com.diamondfsd.jooq.learn.codegen

    我们的继承类可以放在 com.diamondfsd.jooq.learn.xxx,或者其他更顶级的目录下,避免被生成器删除

    内容总结

    所有实例代码都在src/java/test目录内,是写好的测试用例。

    本章节讲解了如何进行基础的CURD操作,以及POJO生成。有很多人疑问这个POJO和Record有什么区别,因为Record也有getter/setter方法,这里给大家讲解一下Record 的储存方式是将字段描述和值储存在两个数组中,下标一一对应。get或set的时候,其实现都是通过字段找到对应的下标,进行数组操作的,这样有个问题是无法将其通过json序列化为一个字符串。而且Record对象通常还包含一些针对字段取值的方式,主要用于操作数据时使用

    POJO 是由成员变量和getter/setter组成的,是一个纯粹用于存取数据的类,可以通过json序列化和反序列化,这样在我们进行web开发的时候,可以很方便的进行数据转换处理

    在实际业务中,通常我们不会直接使用由 jOOQ 生成的 POJO 类,因为 jOOQ 代码生成是全量的。我们在对POJO做一些修改的后,例如添加一些其他表的关联成员,重新生成时,代码又会被抹去。如果要直接改动jOOQ生成的代码,每次重新生成的时候,还需要去备份一遍原来的,而且还需要根据改动去改代码

    解决这个问题方法也很简单,不直接去修改 POJO 类,创建一个继承 POJO 的子类。关联的字段或者其他临时的字段在子类中进行设置成员变量,这样就可以不影响 jOOQ 生成的代码,还能实现我们想要的效果

    展开全文
  • 因为后台所有ID都是按照雪花算法生成的18位数字,需要对接到Android,Ios和H5,此时H5会出现字符超长溢出,所以直接把ID改为varchar类型。 如我的一张ID为varchar(18)类型,此时下面两种查询会有不同的结果,...
  • 因为后台所有ID都是按照雪花算法生成的18位数字,需要对接到Android,Ios和H5,此时H5会出现字符超长溢出,所以直接把ID改为varchar类型。 如我的一张ID为varchar(18)类型,此时下面两种查询会有不同的结果,...
  • // 返回旋转因子查询表(twiddle factor lookup table) private static Complex[] WT_LUT(int N, int flag = 1) { Complex[] WT = new Complex[N]; for (int i = 0; i < N; i++) { ...
  • 关于laravel的最热门问题合集,有技术问题,上 bug200.com如何让查询生成器将其原始SQL查询输出为字符串?https://bug200.com/post/18236294给出以下代码: DB::table('users')->get(); 我想获取上面的数据库查询...
  • 在一中有如下字段 假定表名为manage,字段名为:dan dan字段有如下的值: 双 单 单 单 双 双 单 问题:如何查询dan字段中单连续出先了几次,然后隔了几次的双,再出现单 我用相关子查询模拟的游标~ 生成以下结果...
  • 2、 以下为个人遇到的一种可能:在项目开发中由于有张表是动态的,即有个基础,其他的按年月根据基础生成动态,动态结构和基础保持一致。从动态和基础中同时查询数据,且根据各自的条件进行查询并...
  • 关于Mybatis使用问题

    2020-12-30 17:25:52
    今天用mybatis生成的java类来接收数据库对应的,发现有一部分数据接收不了,查了半天才了解到以下方法: 1.在yml中这里添加以下字段 configuration: map-underscore-to-camel-case: true 2.在mybatis数据库中对应...
  • 当前, xo可以为PostgreSQL,MySQL,Oracle,Microsoft SQL Server和SQLite3数据库生成表,枚举,存储过程和自定义SQL查询的类型。 注意:尽管xo生成的代码具有生产质量,但这不是xo的目标,也不是xo成为“银弹”...
  • 传统输入法(输入法的生成器)改进包

    热门讨论 2009-11-12 21:30:01
    1、关于NTFS分区中Guest用户不能使用问题,用以下命令设置码表权限: cacls "%windir%\system32\我的输入法.mb" /t /e /c /g users:w 2、在Vista中IE7(UAC)下不能使用问题,用以下命令设置一下码表级别: icacls...
  • 视图(View)并不在数据库中实际存在,而是一种虚拟,行和列数据来自定义视图的查询中使用的,并且是在使用视图时动态生成的。即视图就是执行查询语句后所返回的结果集,所以在创建视图的时候,主要就是创建这条...
  • 关于分库分表?

    2017-11-02 22:17:53
    根据业务特性来制定适合的方案,比如我们可以每天生产一个,比如t_20170201,t_20170202,来记录每天的数据,或者每月,每年等生成一个 我们常用的规则以下 1范围(Range)所有的数据分成N个区间范围,然后根据...
  • 这是看了网上几篇关于PHP导出word文档的文章之后,本人改进一下的方法,可以导出带图片的,以下是demo。$row = M('Article')->where(array('id'=>5))->find();//这里我用的是Thinkphp框架,意思查询的是...
  • 关于聚集索引选择

    2010-06-04 09:27:00
    根据一段时间的网站日志生成访问记录tblWebVisitLog,需记录以下信息:访问时间: VisitTime访问者IP: IP访问的URL: URL同一时刻可能有多条访问记录,即VisitTime不是唯一的。数据量:3000万条记录左右常见查询情况...
  • l EF不支持存储过程返回多联合查询的结果集。 l EF仅支持返回返回某个的全部字段,以便转换成对应的实体。无法支持返回部分字段的情况。 l 虽然可以正常导入返回标量值的存储过程,但是却没有为我们自动生成...
  • 最近项目需要实现如题“所见即所得”的功能,之前每次生成Excel都需要重新从数据库查询一遍,降低效率不说,那些嵌套的表头实在是很难用Sql嵌套拼接实现。而且这样做还没有通用性,不同的表格需要写不同的Sql实现,...
  • 我如何在查询时在记录生成一个计算列,显示“刷卡时间”在相应时间范围内的用餐类别?结果类似以下表格卡號 刷卡時間 早餐 消費金額卡號 刷卡時間 中餐 消費金額卡號 刷卡時間 晚餐 消費金額谢谢 !!!
  • 通常可以根据算法计算获得,也可以通过利用预先计算好的CRC表查询计算获得,以下这段是关于CRC-ITU**(生成多项式为:x16+x12+x5+1,简记式为1021)余式的CRC校验的JAVA程序。其它余式CRC算法原理类似,只需替换查询...
  • 增加派生列就是在中增加的列来自于其他数据的数据,列的数据由其他中的数据计算生成,这种操作也是为了减少之间的连接查询,提高查询速度。 重新租则指的是将两个经常使用两个连接查询的数据组合成...
  • SQL中limit简单的用法

    千次阅读 多人点赞 2020-09-02 16:47:55
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、pandas是什么? 二、使用步骤 1.引入库 2.读入数据 总结 前言 关于SQL语句中的 limit用法 提示:以下是本...
  • 我的问题是关于以下用例形成Postgres SQL查询Approach#1我有一个像下面的,我在不同的类型(a,b,c,d)生成相同的uuid,如映射不同的类型 .+----+------+-------------+| id | type | master_guid |+----+------...
  • 使用Jora进行查询的数据转换,关于查询类型的建议 定制JSON数据表示(使用,列表等) 通过链接共享定制(报告) 可以在具有有效JSON的任何页面上使用-URL /内容类型无关紧要 适用于本地文件(请参见下文) ...
  • SQL语法大全

    2014-03-30 11:00:11
    以上几个游标类型将直接影响到Recordset对象所有的属性和方法,以下列表说明他们之间的区别。 ------------------------------------------------------------- Recordset属性 adOpenForwardOnly adOpenKeyset ...
  • 没有发布时间,这些发布是“根据需要”完成的。 在Zenodo上发布档案: 范围 我们使用Jekyll静态网站生成器。 该站点旨在保留PHENIX实验的策划文档,包括有关PHENIX软件及其基础结构的技术文章。 尽管它确实托管...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 167
精华内容 66
关键字:

以下关于生成表查询