我有一个用户类,有16个属性,比如名字,姓氏,出生日期,用户名,密码等...这些都存储在MySQL数据库中,当我想要检索用户时,我使用ResultSet。我想将每一列映射回用户属性,但我这样做的效率似乎非常低。例如,我正在做:
//ResultSet rs;
while(rs.next()) {
String uid = rs.getString("UserId");
String fname = rs.getString("FirstName");
...
...
...
User u = new User(uid,fname,...);
//ArrayList<User> users
users.add(u);
}
也就是说,我检索所有的列,然后通过将所有的列值插入用户构造函数来创建用户对象。
有人知道更快、更整洁的方法吗?
假设您希望使用核心Java,而不使用任何战略框架。如果您可以保证,实体的字段名将等于数据库中的列,则可以使用反射API(否则,在那里创建注释并定义映射名)
按字段名
/**
Class<T> clazz - a list of object types you want to be fetched
ResultSet resultSet - pointer to your retrieved results
*/
List<Field> fields = Arrays.asList(clazz.getDeclaredFields());
for(Field field: fields) {
field.setAccessible(true);
}
List<T> list = new ArrayList<>();
while(resultSet.next()) {
T dto = clazz.getConstructor().newInstance();
for(Field field: fields) {
String name = field.getName();
try{
String value = resultSet.getString(name);
field.set(dto, field.getType().getConstructor(String.class).newInstance(value));
} catch (Exception e) {
e.printStackTrace();
}
}
list.add(dto);
}
通过注释
@Retention(RetentionPolicy.RUNTIME)
public @interface Col {
String name();
}
DTO:
class SomeClass {
@Col(name = "column_in_db_name")
private String columnInDbName;
public SomeClass() {}
// ..
}
一样,但是
while(resultSet.next()) {
T dto = clazz.getConstructor().newInstance();
for(Field field: fields) {
Col col = field.getAnnotation(Col.class);
if(col!=null) {
String name = col.name();
try{
String value = resultSet.getString(name);
field.set(dto, field.getType().getConstructor(String.class).newInstance(value));
} catch (Exception e) {
e.printStackTrace();
}
}
}
list.add(dto);
}
思想
事实上,迭代所有字段可能看起来无效,所以我会将映射存储在某个地方,而不是每次都迭代。但是,如果我们的T
是一个仅用于传输数据的DTO,并且不会包含大量不必要的字段,那没关系。最后,这比一直使用样板方法要好得多。
希望这能帮助别人。
无需将 resultSet 值存储到 String 中,然后再次设置到 POJO 类中。而是在检索时设置。
或者最好的方法是切换到像hibernate这样的ORM工具,而不是将POJO对象直接映射到数据库的JDBC。
但是现在使用这个:
List<User> users=new ArrayList<User>();
while(rs.next()) {
User user = new User();
user.setUserId(rs.getString("UserId"));
user.setFName(rs.getString("FirstName"));
...
...
...
users.add(user);
}
如果您不想使用任何JPA提供程序,如OpenJPA或Hibernate,您可以尝试使用ApacheDButils。
http://commons . Apache . org/proper/commons-dbutils/examples . html
那么您的代码将如下所示:
QueryRunner run = new QueryRunner(dataSource);
// Use the BeanListHandler implementation to convert all
// ResultSet rows into a List of Person JavaBeans.
ResultSetHandler<List<Person>> h = new BeanListHandler<Person>(Person.class);
// Execute the SQL statement and return the results in a List of
// Person objects generated by the BeanListHandler.
List<Person> persons = run.query("SELECT * FROM Person", h);
我正在开发一个使用现有数据库的应用程序,该数据库只能通过存储过程访问。这些SP中的大多数返回来自多个表的列。 我们有一个数据访问层,它从我们的域对象层返回类型的对象。但是,由于SPs返回来自多个表的列,我不确定应该如何构建我的域对象,因为它们中的大多数不会“自然”映射到从SPs返回的数据。 示例:存储过程返回来自“员工”表和“经理”表的列: -员工ID -FirstName -LastName -
问题内容: 我有一个具有16个属性的用户类,例如名,姓,dob,用户名,密码等。这些都存储在MySQL数据库中,当我要检索用户时,我使用ResultSet。我想将每个列映射回用户属性,但是我的操作方式似乎效率很低。例如我在做: 即我检索所有列,然后通过将所有列值插入到User构造函数中来创建用户对象。 有谁知道更快,更整洁的方法吗? 问题答案: 无需将resultSet值存储到String中,也无
null 没有将查询结果映射到域对象的基础结构。QueryDSL的QBean和MappingProject、Spring的BeanPropertyRowMapper和Spring-Data的OneToManyResultSetExtractor似乎级别太低,请参见下文。 没有在MyBatis中免费提供的现成会话/事务级缓存 Mybatis中没有免费提供的现成SQL语句和结果日志 因为我只问一个问题
我开始使用JOOQ和dvd租赁商店数据库aka sakila。基本上,我想找一个演员和他的角色(我创建的表)。到目前为止,我想到了这个: 我希望能够将演员及其角色提取到一个对象中:DTO。我找到了这篇文章https://arnaudroger.github.io/blog/2017/03/02/jooq-one-to-many-without-dto.html但我发现使用sfm的解决方案过于冗长,
我是Mapstruct的新手。我有一个Word对象,它包含一个字符串值和一组它自己,我想把它映射到WordDTO,它包含一个值和一组字符串值。我不知道怎么做。正如我在注释中所说,mapstruct不能映射两个对象是有道理的,但如果它有帮助,我将错误放在下面: 我为映射实现了这个接口: 谢谢你的帮助。
在对这个话题进行了大量的测试和研究之后,我无法完全解决我的问题。我正在springboot应用程序中使用modelmapper进行实体/DTO映射。我正在尝试配置modelmapper,将一个集合映射到一个简单的DTO对象。我已经创建了一个自定义转换器,它正在按预期工作: 我现在的问题是将此转换器应用于所有“集合”= 如果我直接在模型映射器中添加转换器,它就是不工作。 你对此有什么提示或解决办法吗