zoukankan      html  css  js  c++  java
  • Jooq基本操作

    简单研究下Jooq的基本操作,在使用一段时间后在做补充。

    jooq和Mybatis一样,是dao层的框架,用于操作数据库。

    也有和类似于MybatisGenerator的工程,可以实现导出bean和dao接口,目前了解到的是将导出项目的单独作为一个项目,然后将导出的文件拷贝到实际运用的项目。

    参考git: https://github.com/qiao-zhi/jooq-code-generator

    0. 假设数据库有三张表

    1.user表

    +--------------+--------------+------+-----+---------+----------------+
    | Field        | Type         | Null | Key | Default | Extra          |
    +--------------+--------------+------+-----+---------+----------------+
    | id           | int(11)      | NO   | PRI | NULL    | auto_increment |
    | username     | varchar(20)  | YES  |     | NULL    |                |
    | password     | varchar(40)  | YES  |     | NULL    |                |
    | userfullname | varchar(10)  | YES  |     | NULL    |                |
    | createtime   | date         | YES  |     | NULL    |                |
    | isdeleted    | varchar(2)   | YES  |     | NULL    |                |
    | sex          | varchar(2)   | YES  |     | NULL    |                |
    | address      | varchar(40)  | YES  |     | NULL    |                |
    | roles        | varchar(255) | YES  |     | NULL    |                |
    | userblank    | varchar(255) | YES  |     | NULL    |                |
    +--------------+--------------+------+-----+---------+----------------+

    2.country表

    +-------------+--------------+------+-----+---------+----------------+
    | Field       | Type         | Null | Key | Default | Extra          |
    +-------------+--------------+------+-----+---------+----------------+
    | id          | int(11)      | NO   | PRI | NULL    | auto_increment |
    | countryname | varchar(255) | YES  |     | NULL    |                |
    +-------------+--------------+------+-----+---------+----------------+

    3.usercountry表

    +-----------+---------+------+-----+---------+-------+
    | Field     | Type    | Null | Key | Default | Extra |
    +-----------+---------+------+-----+---------+-------+
    | userid    | int(11) | NO   | PRI | NULL    |       |
    | countryid | int(11) | NO   | PRI | NULL    |       |
    +-----------+---------+------+-----+---------+-------+

    1. 导出数据库表以及dao接口项目

      这个一般是类似于Mybatis的Generator工程一样,单独作为一个工程用于导出数据库相关信息。

    1.pom增加映射

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>cn.qlq</groupId>
        <artifactId>jooq</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <name>jooq</name>
        <!-- FIXME change it to the project's website -->
        <url>http://www.example.com</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
                <scope>test</scope>
            </dependency>
            
            <!--引入 jooq-codegen -->
            <dependency>
                <groupId>org.jooq</groupId>
                <artifactId>jooq-codegen</artifactId>
                <version>3.12.4</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <!-- Use org.jooq for the Open Source Edition
                    org.jooq.pro-java-8 for commercial editions with Java 8 support,
                    org.jooq.trial for the free trial edition
                    Note: Only the Open Source Edition is hosted on Maven Central.
                    Import the others manually from your distribution -->
                    <groupId>org.jooq</groupId>
                    <artifactId>jooq-codegen-maven</artifactId>
                    <version>3.12.4</version>
                    <!-- The jOOQ code generation plugin is also executed in the generate-sources phase, prior to compilation -->
                    <executions>
                        <execution>
                            <phase>generate-sources</phase>
                            <goals>
                                <goal>generate</goal>
                            </goals>
                        </execution>
                    </executions>
                    <!-- This is a minimal working configuration. See the manual's section about the code generator for more details -->
                    <configuration>
                        <!-- 这里使用配置文件 -->
                        <configurationFile>src/main/resources/jooqConfig.xml</configurationFile>
                    </configuration>
                </plugin>
    
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>

    2.classpath,也就是resources下面新建jooqConfig.xml

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <configuration xmlns="http://www.jooq.org/xsd/jooq-codegen-3.12.0.xsd">
        <!-- Configure the database connection here -->
        <jdbc>
            <driver>com.mysql.jdbc.Driver</driver>
            <url>jdbc:mysql://localhost:3306/test1?useUnicode=true&amp;characterEncoding=utf8&amp;autoReconnect=true&amp;autoReconnectForPools=true&amp;failOverReadOnly=false</url>
            <user>root</user>
            <password>123456</password>
        </jdbc>
    
        <generator>
            <!-- The default code generator. You can override this one, to generate your own code style.
                 Supported generators:
                 - org.jooq.codegen.JavaGenerator
                 - org.jooq.codegen.ScalaGenerator
                 Defaults to org.jooq.codegen.JavaGenerator -->
            <name>org.jooq.codegen.JavaGenerator</name>
    
            <database>
                <!-- The database type. The format here is:
                     org.jooq.meta.[database].[database]Database -->
                <name>org.jooq.meta.mysql.MySQLDatabase</name>
    
                <!-- The database schema (or in the absence of schema support, in your RDBMS this
                     can be the owner, user, database name) to be generated -->
                <!-- 数据库名 -->
                <inputSchema>test1</inputSchema>
    
                <!-- All elements that are generated from your schema
                     (A Java regular expression. Use the pipe to separate several expressions)
                     Watch out for case-sensitivity. Depending on your database, this might be important! -->
                <!-- 包含哪些表 -->
                <!--<includes>.*</includes>-->
                <includes>user| usercountry| country</includes>
    
                <!-- All elements that are excluded from your schema
                     (A Java regular expression. Use the pipe to separate several expressions).
                     Excludes match before includes, i.e. excludes have a higher priority -->
                <!-- 排除哪些表,这里支持正则表达式 ,多个条件可以用 | 连接符连接-->
                <!-- 例如:TEST | OTHERS 生成代码时就不会把叫做TEST和OTHERS的表包括进去了-->
                <excludes></excludes>
            </database>
    
            <!-- Optional: The programmatic or configurative generator strategy. -->
            <strategy>
                <matchers>
                    <tables>
                        <table>
                            <tableClass>
                                <transform>UPPER</transform>
                            </tableClass>
                            <pojoClass>
                                <!-- <expression>*+Model</expression> -->
                            </pojoClass>
                        </table>
                    </tables>
                </matchers>
            </strategy>
            <generate>
                <pojos>true</pojos>
                <daos>true</daos>
                <interfaces>true</interfaces>
                <jpaAnnotations>false</jpaAnnotations>
                <springAnnotations>false</springAnnotations>
            </generate>
    
            <target>
                <!-- The destination package of your generated classes (within the destination directory) -->
                <!-- 生成的代码存放的包名 -->
                <packageName>cn.qlq.jooq</packageName>
    
                <!-- The destination directory of your generated classes. Using Maven directory layout here -->
                <!-- 存放的路径 -->
                <directory>src/main/java/</directory>
            </target>
        </generator>
    </configuration>

    可以指定需要导出哪些表,如果是全部表可以用<includes>.*</includes>;也可以用 <includes>user| usercountry| country</includes> 导出指定的三个表,用|做分隔符。

    3.导出表:

    直接运行:

    $ mvn compile

    或者:

    $ mvn jooq-codegen:generate

    再或者用IDEA直接运行:

     4.查看生成的文件

    目录结构如下:

     Test是数据库描述信息;Tables是所有的表的信息;Keys是约束;Indexs是索引信息。

    2.Springboot中使用Jooq

    主要测试简单的增删改查。

    1.pom新增

            <!--引入 Jooq -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jooq</artifactId>
            </dependency>
            <dependency>
                <groupId>org.jooq</groupId>
                <artifactId>jooq-meta</artifactId>
                <version>3.12.4</version>
            </dependency>

    2.上面导出的dao实现类接口层加上注入Spring的注解

    3.测试

    测试类如下:

    package test;
    
    import cn.qlq.MySpringBootApplication;
    import cn.qlq.jooq.tables.COUNTRY;
    import cn.qlq.jooq.tables.USER;
    import cn.qlq.jooq.tables.USERCOUNTRY;
    import cn.qlq.jooq.tables.daos.CountryDao;
    import cn.qlq.jooq.tables.daos.UserDao;
    import cn.qlq.jooq.tables.daos.UsercountryDao;
    import cn.qlq.jooq.tables.pojos.Country;
    import cn.qlq.jooq.tables.pojos.User;
    import cn.qlq.jooq.tables.pojos.Usercountry;
    import cn.qlq.jooq.tables.records.UserRecord;
    import org.jooq.DSLContext;
    import org.jooq.Field;
    import org.jooq.Record4;
    import org.jooq.Result;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.boot.web.servlet.ServletComponentScan;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import javax.annotation.PostConstruct;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = MySpringBootApplication.class)
    @ServletComponentScan("cn.qlq")
    public class Jooqtest {
    
        @Autowired
        @Qualifier("userDao2")
        private UserDao userDao;
    
        @Autowired
        @Qualifier("countryDao2")
        private CountryDao countryDao;
    
        @Autowired
        private UsercountryDao userCountryDao;
    
        @Autowired
        private DSLContext context;
    
        @PostConstruct//表示在userDao构造完成之后执行
        private void createDao() {
            userDao = new UserDao(context.configuration());
            countryDao = new CountryDao(context.configuration());
            userCountryDao = new UsercountryDao(context.configuration());
        }
    
        @Test
        public void testAdd() {
            // 添加用户
            User user = new User();
            user.setId(1);
            user.setUsername("zhangsan");
            user.setUserfullname("张三");
            user.setAddress("测试地址");
            user.setSex("男");
            userDao.insert(user);
    
            // 添加城市,添加两个
            Country country = new Country();
            country.setId(1);
            country.setCountryname("中国北京");
            Country country2 = new Country();
            country2.setId(2);
            country2.setCountryname("中国山西");
            countryDao.insert(country, country2);
    
            // 维护关系
            Usercountry userCountry = new Usercountry();
            userCountry.setUserid(1);
            userCountry.setCountryid(1);
            Usercountry userCountry2 = new Usercountry();
            userCountry2.setUserid(1);
            userCountry2.setCountryid(2);
            userCountryDao.insert(userCountry, userCountry2);
    
            System.out.println("增加成功");
        }
    
        @Test
        public void testSelect() {
            List<User> users = userDao.findAll();
            System.out.println(users);
        }
    
        @Test
        public void testDelete() {
            userDao.deleteById(1);
            System.out.println("删除成功");
        }
    
        // =====S 使用dslContext操作
        private USER TABLE_USER = USER.USER;
        private COUNTRY TABLE_COUNTRY = COUNTRY.COUNTRY;
        private USERCOUNTRY TABLE_USER_COUNTRY = USERCOUNTRY.USERCOUNTRY;
    
        /**
         * DSL 查询单个
         */
        @Test
        public void testSelect2() {
            Result<UserRecord> users = context.selectFrom(TABLE_USER).where("id = 1").and(TABLE_USER.ID.equal(1)).orderBy(1).fetch();
            for (UserRecord userRecord : users) {
                System.out.println(userRecord);
            }
    
            System.out.println("=====");
    
            List<User> results = context.selectFrom(TABLE_USER).where("id = 1").and(TABLE_USER.ID.equal(1)).orderBy(1).fetchInto(User.class);
            System.out.println(results);
        }
    
        /**
         * 联合查询
         */
        @Test
        public void testSelect3() {
            // 简单的联合查询
            Result<Record4<Integer, String, String, String>> fetch = context.select(TABLE_USER.ID, TABLE_USER.USERNAME, TABLE_USER.USERFULLNAME, TABLE_COUNTRY.COUNTRYNAME)
                    .from(TABLE_USER, TABLE_USER_COUNTRY, TABLE_COUNTRY)
                    .where(TABLE_USER.ID.equal(TABLE_USER_COUNTRY.USERID)).and(TABLE_USER_COUNTRY.USERID.equal(TABLE_COUNTRY.ID)).fetch();
            System.out.println(fetch);
    
            System.out.println("====1====");
    
            // 处理结果塞到map中
            List<Map<String, Object>> results = new ArrayList<>();
            fetch.forEach(record -> {
                Map<String, Object> map = new HashMap<>();
                Field<?>[] fields = record.fields();
                for (Field field : fields) {
                    Object value = record.getValue(field);
                    map.put(field.getName(), value);
                }
                results.add(map);
            });
            System.out.println(results);
    
            System.out.println("====2====");
    
            // 查询直接映射到VO中
            List<UserCountryVO> userCountryVOS = context.select(TABLE_USER.ID, TABLE_USER.USERNAME, TABLE_USER.USERFULLNAME, TABLE_COUNTRY.COUNTRYNAME)
                    .from(TABLE_USER, TABLE_USER_COUNTRY, TABLE_COUNTRY)
                    .where(TABLE_USER.ID.equal(TABLE_USER_COUNTRY.USERID)).and(TABLE_USER_COUNTRY.COUNTRYID.equal(TABLE_COUNTRY.ID)).fetchInto(UserCountryVO.class);
            System.out.println(userCountryVOS);
        }
    }

    createDao方法内部的操作是必须的,否则会报一个错。

    (1)testAdd  方法测试

    (2)testSelect 方法测试结果如下:

    [User (1, zhangsan, null, 张三, null, null, 男, 测试地址, null, null)]

    (3)testSelect2 测试结果:

    +----+--------+--------+------------+----------+---------+----+-------+------+---------+
    |  id|username|password|userfullname|createtime|isdeleted|sex |address|roles |userblank|
    +----+--------+--------+------------+----------+---------+----+-------+------+---------+
    |   1|zhangsan|{null}  |张三          |{null}    |{null}   |男   |测试地址   |{null}|{null}   |
    +----+--------+--------+------------+----------+---------+----+-------+------+---------+
    
    =====
    [User (1, zhangsan, null, 张三, null, null, 男, 测试地址, null, null)]

    (4)测试联合查询:

    1》新建VO对象

    package test;
    
    import lombok.Data;
    
    @Data
    public class UserCountryVO {
    
        private Long id;
    
        private String username;
    
        private String userfullname;
    
        private String countryname;
    }

    2》testSelect3  方法测试:  测试多个表的连接查询。Jooq对多表查询的语法还是比较符合SQL写法的,比较方便。

    +----+--------+------------+-----------+
    |  id|username|userfullname|countryname|
    +----+--------+------------+-----------+
    |   1|zhangsan|张三          |中国北京       |
    |   1|zhangsan|张三          |中国北京       |
    +----+--------+------------+-----------+
    
    ====1====
    [{userfullname=张三, countryname=中国北京, id=1, username=zhangsan}, {userfullname=张三, countryname=中国北京, id=1, username=zhangsan}]
    ====2====
    [UserCountryVO(id=1, username=zhangsan, userfullname=张三, countryname=中国北京), UserCountryVO(id=1, username=zhangsan, userfullname=张三, countryname=中国山西)]

      关于其他的用法在之后实际运用一段时间后总结。

  • 相关阅读:
    如何用阿里云ECS搭建网站
    win10下使用pipreqs提示不是内部或外部命令
    python使用openpyxl获取合并单元格的值
    Chrome的一些常用小tips
    Ubantu部署
    分不清ERP、SAP、MES?干货整理看这里
    ApacheCN 数据科学译文集 20210313 更新
    ApacheCN 计算机视觉译文集 20210218 更新
    ApacheCN 计算机视觉译文集 20210212 更新
    ApacheCN 计算机视觉译文集 20210203 更新
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/13974439.html
Copyright © 2011-2022 走看看