{"id":37020128,"url":"https://github.com/jzheng2017/resultset-mapper","last_synced_at":"2026-01-14T02:15:56.756Z","repository":{"id":38319066,"uuid":"318885840","full_name":"jzheng2017/resultset-mapper","owner":"jzheng2017","description":"ResultSet Mapper allows you to map a ResultSet to a desired java object by passing in its type.","archived":false,"fork":false,"pushed_at":"2024-02-17T12:33:50.000Z","size":147,"stargazers_count":22,"open_issues_count":12,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-01T12:43:12.496Z","etag":null,"topics":["dto","dto-mapper","java","jdbc","library","mapper","mapping","resultset-mapper"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jzheng2017.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-12-05T20:46:21.000Z","updated_at":"2024-12-18T16:30:34.000Z","dependencies_parsed_at":"2023-11-11T20:38:05.046Z","dependency_job_id":null,"html_url":"https://github.com/jzheng2017/resultset-mapper","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/jzheng2017/resultset-mapper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jzheng2017%2Fresultset-mapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jzheng2017%2Fresultset-mapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jzheng2017%2Fresultset-mapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jzheng2017%2Fresultset-mapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jzheng2017","download_url":"https://codeload.github.com/jzheng2017/resultset-mapper/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jzheng2017%2Fresultset-mapper/sbom","scorecard":{"id":545970,"data":{"date":"2025-08-11","repo":{"name":"github.com/jzheng2017/resultset-mapper","commit":"f8a701f8f030c283551a0c0c2b4ec181739ac281"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.7,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/13 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":9,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:28","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:29","Warn: no topLevel permission defined: .github/workflows/codeql.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/jzheng2017/resultset-mapper/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/jzheng2017/resultset-mapper/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:59: update your workflow using https://app.stepsecurity.io/secureworkflow/jzheng2017/resultset-mapper/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:72: update your workflow using https://app.stepsecurity.io/secureworkflow/jzheng2017/resultset-mapper/codeql.yml/main?enable=pin","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 0 commits out of 17 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-20T09:30:41.612Z","repository_id":38319066,"created_at":"2025-08-20T09:30:41.612Z","updated_at":"2025-08-20T09:30:41.612Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408711,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dto","dto-mapper","java","jdbc","library","mapper","mapping","resultset-mapper"],"created_at":"2026-01-14T02:15:55.960Z","updated_at":"2026-01-14T02:15:56.744Z","avatar_url":"https://github.com/jzheng2017.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Maven Central](https://img.shields.io/maven-central/v/nl.jiankai/resultset-mapper.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22nl.jiankai%22%20AND%20a:%22resultset-mapper%22) [![Build Status](https://travis-ci.com/jzheng2017/resultset-mapper.svg?branch=main)](https://travis-ci.com/jzheng2017/resultset-mapper) [![Coverage Status](https://coveralls.io/repos/github/jzheng2017/resultset-mapper/badge.svg?branch=main)](https://coveralls.io/github/jzheng2017/resultset-mapper?branch=main) [![Language grade: Java](https://img.shields.io/lgtm/grade/java/g/jzheng2017/resultset-mapper.svg?logo=lgtm\u0026logoWidth=18)](https://lgtm.com/projects/g/jzheng2017/resultset-mapper/context:java) [![Maintainability](https://api.codeclimate.com/v1/badges/2c2148df6c782aa9fe11/maintainability)](https://codeclimate.com/github/jzheng2017/resultset-mapper/maintainability)\n# ResultSet Mapper\nResultSet Mapper is a small lightweight library that allows you to map a `ResultSet` object to a desired java object by passing in its type.\n\n- [Example usages](#example-usages)\n    * [Model object](#model-object)\n    * [Map `ResultSet` to desired model object](#map--resultset--to-desired-model-object)\n    * [Field naming strategies](#field-naming-strategies)\n        + [IdentityFieldNamingStrategy](#identityfieldnamingstrategy)\n        + [LowerCaseUnderscoreFieldNamingStrategy](#lowercaseunderscorefieldnamingstrategy)\n        + [LowerCaseDashesFieldNamingStrategy](#lowercasedashesfieldnamingstrategy)\n        + [Custom field naming strategy](#custom-field-naming-strategy)\n    * [Attribute converting](#attribute-converting)\n        + [`@Convert` annotation](#--convert--annotation)\n        + [Attribute converter](#attribute-converter)\n        + [Available attribute converters](#available-attribute-converters)\n    * [Ignoring fields](#ignoring-fields)\n        + [Why would I ignore a field?](#why-would-i-ignore-a-field-)\n    * [Logging](#logging)\n        + [Class level `@SuppressWarnings`](#class-level---suppresswarnings-)\n        + [Field level `@SuppressWarnings`](#field-level---suppresswarnings-)\n- [Why use this library?](#why-use-this-library-)\n- [Installation](#installation)\n    * [Maven](#maven)\n    * [Gradle](#gradle)\n- [License](#license)\n- [Java version](#java-version)\n\n## Example usages\n### Model object\nDefine a java object you want to map to. Use the `@Column` annotation to override the `FieldNamingStrategy`\n```java\npublic class User {\n    private int id;\n    @Column(name = \"first_name\")\n    private String firstName;\n    @Column(name = \"last_name\")\n    private String lastName;\n    private String email;\n}\n```\n\n### Map `ResultSet` to desired model object \nTo map a `ResultSet` you need an instance of `ResultSetMapper`. The library provides a factory class `ResultSetMapperFactory` that serves `ResultSetMapper` with different `FieldNamingStrategy`. The `ResultSetMapper` defaults to the `IdentityFieldNamingStrategy`.\n```java\n// ResultSetMapper with IdentityFieldNamingStrategy\nResultSetMapper r = ResultSetMapperFactory.getResultSetMapperIdentity(); \nList\u003cUser\u003e users = r.map(resultSet, User.class);\n```\n\n```java\n// more examples of out of the box factory calls for different field naming strategies\n\n// ResultSetMapper with LowerCaseUnderscoreFieldNamingStrategy\nResultSetMapper r2 = ResultSetMapperFactory.getResultSetMapperLowerCaseUnderscore(); \nList\u003cUser\u003e users = r2.map(resultSet, User.class);\n\n// ResultSetMapper with LowerCaseDashesFieldNamingStrategy\nResultSetMapper r3 = ResultSetMapperFactory.getResultSetMapperLowerCaseDashes(); \nList\u003cUser\u003e users = r3.map(resultSet, User.class);\n```\n### Field naming strategies\nThe library provides out of the box a few field naming strategies. \n\n**Note**: The provided strategies assumes you use `camelCase` for your field names. It does not work if you use other naming styles. If this does not conform to your naming style, you have to implement your own field naming strategy.\n#### IdentityFieldNamingStrategy\nThis strategy leaves the field names unchanged.\n#### LowerCaseUnderscoreFieldNamingStrategy\nThis strategy maps the field names to lowercase with underscores. For instance `firstName` would map to `first_name`.\n#### LowerCaseDashesFieldNamingStrategy\nThis strategy maps the field names to lowercase with dashes. For instance `firstName` would map to `first-name`.\n#### Custom field naming strategy\nIt is possible to make your own field naming strategy. It is done by implementing the `FieldNamingStrategy` interface. It has one function `transform` which transforms the original field name. The concrete `FieldNamingStrategy` implementation can then be injected through the constructor.\n```java\nResultSetMapper r = new ResultSetMapper(new CustomFieldNamingStrategy());\n```\n\n### Attribute converting\nThe library provides the ability to convert one type to another, allowing two incompatible types to work during mapping.\n\n#### `@Convert` annotation\nUsing the `@Convert` annotation you can define on class field level which attribute converter must be used.\n\n**Note**: If there is no `@Convert` annotation is present, the mapper will search for an appropriate attribute converter. If it has found one it will apply *only* if there is a `@Converter` annotation applied on the attribute converter with `autoApply` equaling `true`.\n```java\npublic class User {\n    private int id;\n    @Column(name = \"first_name\")\n    private String firstName;\n    @Column(name = \"last_name\")\n    private String lastName;\n    private String email;\n    @Convert(converter = TimestampToLocalDateTimeConverter.class)\n    private LocalDateTime creationDateTime;\n}\n```\n\n#### Attribute converter\nLet's see how an attribute converter can be defined. As you can see below an attribute converter can be defined by implementing the `AttributeConverter\u003cS, T\u003e` interface.\n```java\n@Converter(autoApply = true)\npublic class TimestampToLocalDateTimeConverter implements AttributeConverter\u003cTimestamp, LocalDateTime\u003e {\n\n    @Override\n    public LocalDateTime convert(Timestamp value) {\n        return value.toLocalDateTime();\n    }\n\n    @Override\n    public Class\u003cTimestamp\u003e source() {\n        return Timestamp.class;\n    }\n\n    @Override\n    public Class\u003cLocalDateTime\u003e target() {\n        return LocalDateTime.class;\n    }\n}\n```\nThis interface has three methods.\n- `convert` - the actual method that does the conversion of type `S` to type `T`.\n- `source` - source class, it should be of type `S`. \n- `target` - target class, it should be of type `T`.\n\nThe `source` and `target` is used internally to determine if the attribute converter is appropriate to be used for a field.\n\nAn attribute converter must always be annotated with the `@Converter` annotation to let the mapper know it is an attribute converter. \nThe annotation can accept one value which is `autoApply`. `autoApply` determines whether to automatically apply the converter when possible. The default value is `false`\n\n\n#### Available attribute converters\nThe library currently provides a few out of the box attribute converters.\n\n- `TimestampToLocalDateTimeConverter` - converts a value of type `java.sql.Timestamp` to `java.time.LocalDateTime`\n- `DateToLocalDateConverter` - converts a value of type `java.sql.Date` to `java.time.LocalDate`\n- `TimeToLocalTimeConverter` - converts a value of type `java.sql.Time` to `java.time.LocalTime`\n\nYou can also define your own attribute converters by implementing the `AttributeConverter\u003cS, T\u003e` interface. \nAfter having defined it you must register this attribute converter. You can register it by calling the `registerAttributeConverter` on the `ResultSetMapper`.\n\n### Ignoring fields\nThe library allows you to annotate class fields with `@Ignore`. This annotation can be used on a field to let the `ResultSetMapper`know that it can skip this field when mapping. This means that the `ResultSetMapper` will not try to retrieve the value from the `ResultSet` for the annotated field.\n\n#### Why would I ignore a field?\nLet me show you an example.\n```java\npublic class User {\n    private int id;\n    @Column(name = \"first_name\")\n    private String firstName;\n    @Column(name = \"last_name\")\n    private String lastName;\n    private String email;\n    @Ignore\n    private List\u003cUserPermission\u003e userPermissions;\n}\n```\nAs you can see above the `User` class has an additional `List\u003cUserPermission\u003e` object. To retrieve that it requires an additional query and can not be mapped when mapping the initial `ResultSet`. By using the `@Ignore` annotation it can let the mapper know that it does not have to be mapped when trying to map the `User` class.\n\n### Logging\nThe library has very extensive logging at every logging level. From `TRACE` to `ERROR`, the logging level is default set on `INFO`. \nThis means only logging messages with log level of `INFO` and above will be logged. \n\nIt is possible to suppress warnings for particular classes. \nFor instance the mapper will throw warning messages when a field can not be found in the `ResultSet`. \nIt would be annoying to be spammed with warning message for every object that is to be mapped. \nThe library provides the `@SuppressWarnings` annotations to \"suppress\" these warning messages.\n\n#### Class level `@SuppressWarnings`\n```java\n@SuppressWarnings\npublic class User {\n    private int id;\n    @Column(name = \"first_name\")\n    private String firstName;\n    @Column(name = \"last_name\")\n    private String lastName;\n    private String email;\n}\n```\nThis will suppress all warnings for every field in the annotated class.\n\n#### Field level `@SuppressWarnings`\n```java\n\npublic class User {\n    private int id;\n    @SuppressWarnings\n    @Column(name = \"first_name\")\n    private String firstName;\n    @SuppressWarnings\n    @Column(name = \"last_name\")\n    private String lastName;\n    private String email;\n}\n```\nIt is also possible to suppress warnings at field level. The warnings will be suppressed for that particular annotated field.\n\n## Why use this library?\nThis library makes it easy to map to a `ResultSet` to your desired java model object. It can be done with only 1 line of code! It saves you a lot of duplicate code when mapping every query.\n```java\nList\u003cUser\u003e users = new ArrayList();\n\nwhile (resultSet.next()){\n    User user = new User();\n    user.setId(resultSet.getInt(\"id\");\n    user.setFirstName(resultSet.getString(\"first_name\"));\n    user.setLastName(resultSet.getString(\"last_name\"));\n    user.setEmail(resultSet.getString(\"email\"));\n    \n    users.add(user);\n}\n```\nvs\n```java\nList\u003cUser\u003e users = r.map(resultSet, User.class);\n```\nWay more cleaner, right? Imagine doing the first example for every different query, that would be a lot of code.. \n\nThe library also takes care of all the exception handling and provides very extensive logging, making it very easy to spot errors when it occurs.\n## Installation\n### Maven\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003enl.jiankai\u003c/groupId\u003e\n  \u003cartifactId\u003eresultset-mapper\u003c/artifactId\u003e\n  \u003cversion\u003e1.6.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n### Gradle\n```gradle\nimplementation 'nl.jiankai:resultset-mapper:1.6.2'\n```\n## License\nSee the [LICENSE](https://github.com/jzheng2017/resultset-mapper/blob/main/LICENSE) file for the license rights and limitations (MIT).\n## Java version\nThe library uses Java 11.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjzheng2017%2Fresultset-mapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjzheng2017%2Fresultset-mapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjzheng2017%2Fresultset-mapper/lists"}