发现了Spring2.5里的一个新东西, BeanPropertyRowMapper类

 转载自:http://www.blogjava.net/cmzy/archive/2008/09/11/228271.html

今天看SpringAPI的时候无意中发现了Spring2.5新增了一个RowMapper的实现类org.springframework.jdbc.core.BeanPropertyRowMapper,但是貌似Spring的refrence里面根本就没提及到。Google了一下……貌似也莫得多少文档。

    Spring API Doc的说明如下:

   RowMapper implementation that converts a row into a new instance of the specified mapped target class. The mapped target class must be a top-level class and it must have a default or no-arg constructor.

   Column values are mapped based on matching the column name as obtained from result set metadata to public setters for the corresponding properties. The names are matched either directly or by transforming a name separating the parts with underscores to the same name using "camel" case.

   Mapping is provided for fields in the target class for many common types, e.g.: String, boolean, Boolean, byte, Byte, short, Short, int, Integer, long, Long, float, Float, double, Double, BigDecimal, java.util.Date, etc.

   To facilitate mapping between columns and fields that don't have matching names, try using column aliases in the SQL statement like "select fname as first_name from customer".

   Please note that this class is designed to provide convenience rather than high performance. For best performance consider using a custom RowMapper.


   也就说,它可以把ResultSet和实体类的字段进行实现自动映射。

   一个具体的例子如下:

   假如有这样一个表,SQL-Server2000的建表脚本如下:

代码    查看源代码 打印
  1. /*  
  2. 管理员表  
  3. */  
  4. CREATE TABLE admin(  
  5.    id int identity(1,1) primary key,  
  6.    username varchar(20) not null,  
  7.    password varchar(32) not null,     
  8. )  

   为此,我们编写一个对应的实体类admin,它是一个标准的javaBean,代码如下:

代码    查看源代码 打印
  1. /** 
  2.  *  
  3.  */  
  4. package db.demo;  
  5.   
  6.   
  7. /** 
  8.  * @author zhangyong 
  9.  *  
  10.  * @version 8:11:57 PM 
  11.  *  
  12.  */  
  13. public class Admin {  
  14.         private int id;  
  15.         private String username;  
  16.         private String password;  
  17.   
  18.         public int getId() {  
  19.                 return id;  
  20.         }  
  21.   
  22.         public void setId(int id) {  
  23.                 this.id = id;  
  24.         }  
  25.   
  26.         public String getUsername() {  
  27.                 return username;  
  28.         }  
  29.   
  30.         public void setUsername(String username) {  
  31.                 this.username = username;  
  32.         }  
  33.   
  34.         public String getPassword() {  
  35.                 return password;  
  36.         }  
  37.   
  38.         public void setPassword(String password) {  
  39.                 this.password = password;  
  40.         }  
  41. }  

   以前,在相应的AdminDAO中,我们以前是这么做滴,看起来很麻烦,如果一个表的字段很多的话,就要人命了,我们必须不停的set、get:

代码    查看源代码 打印
  1. /** 
  2.  *  
  3.  */  
  4. package db.demo;  
  5.   
  6. import java.sql.ResultSet;  
  7. import java.sql.SQLException;  
  8. import java.util.List;  
  9.   
  10. import org.springframework.jdbc.core.RowMapper;  
  11. import org.springframework.jdbc.core.support.JdbcDaoSupport;  
  12.   
  13. /** 
  14.  * @author zhangyong 
  15.  *  
  16.  * @version 10:05:37 PM 
  17.  *  
  18.  */  
  19. public class AdminDAO extends JdbcDaoSupport {  
  20.   
  21.         private final String ID = "id";  
  22.         private final String USERNAME = "username";  
  23.         private final String PASSWORD = "password";  
  24.         private final String TABLE_NAME = "admin";  
  25.   
  26.         /** 
  27.          * 查询记录总数<br/> 
  28.          */  
  29.         public List<Admin> queryAll() {  
  30.                 final String sql = "Select * from " + TABLE_NAME;  
  31.                   
  32.                 return getJdbcTemplate().query(sql, new RowMapper(){  
  33.   
  34.                         public Object mapRow(ResultSet rs, int rowNum) throws SQLException {  
  35.                                 Admin admin = new Admin();  
  36.                                 admin.setId(rs.getInt(ID));  
  37.                                 admin.setUsername(rs.getString(USERNAME));  
  38.                                 admin.setPassword(rs.getString(PASSWORD));  
  39.                                 return admin;  
  40.                         }  
  41.                           
  42.                 });  
  43.         }  
  44. }  

   可见,我们必须的手工对ResultSet和Admin进行映射。而现在,我们只是需要这样:

代码    查看源代码 打印
  1. /** 
  2.  *  
  3.  */  
  4. package db.demo;  
  5.   
  6. import java.util.List;  
  7.   
  8. import org.springframework.jdbc.core.BeanPropertyRowMapper;  
  9. import org.springframework.jdbc.core.support.JdbcDaoSupport;  
  10.   
  11. /** 
  12.  * @author zhangyong 
  13.  *  
  14.  * @version 10:05:37 PM 
  15.  *  
  16.  */  
  17. public class AdminDAO extends JdbcDaoSupport {  
  18.   
  19.         private final String TABLE_NAME = "admin";  
  20.   
  21.         /** 
  22.          * 查询记录总数<br/> 
  23.          */  
  24.         public List<Admin> queryAll() {  
  25.                 final String sql = "Select * from " + TABLE_NAME;  
  26.                   
  27.                 return getJdbcTemplate().query(sql, new BeanPropertyRowMapper(Admin.class));  
  28.         }  
  29. }  

    呵呵,只是一句话就完全搞定了……Sprin会为我们自动映射……显然这样比以前方便多了。我们还可以把它用在其它任何使用RowMapper的场合……毕竟它继承自RowMapper……

    需要注意的是:BeanPropertyRowMapper是根据字段名和实体类中的标准Setter方法进行映射滴。也就是说,我们需要使表中的字段名和实体类的成员变量名称一致。


提供一个简单的微信小程序和Spring Boot后端实现点赞、评论和发布的代码示例。 1. 微信小程序代码 在微信小程序中,我们需要实现三个核心功能:点赞、评论和发布。这给出一个简单的UI设计和相关的代码实现。 1.1 界面设计 在小程序的界面中,我们需要实现以下几个页面: - 首页:展示所有已发布的文章列表,包括文章标题、作者、发布时间、点赞数和评论数。 - 文章详情页:展示某一篇文章的详细信息,包括文章标题、作者、发布时间、点赞数、评论数和文章内容。 - 发布文章页:用户可以在此页面发布自己的文章。 - 评论页:用户可以在此页面查看某一篇文章的所有评论,并可以发表自己的评论。 - 点赞功能:用户可以在文章详情页中对文章进行点赞或取消点赞操作。 - 评论功能:用户可以在文章详情页和评论页中发表评论。 下面是一个简单的UI设计: ![微信小程序界面设计](https://img-blog.csdnimg.cn/20210629131456380.png) 1.2 代码实现 在微信小程序中,我们需要使用`wx.request()`来向后端发送请求。例如,向后端请求所有文章列表: ``` wx.request({ url: &#39;http://localhost:8080/article/list&#39;, success: function (res) { console.log(res.data); // TODO: 处理返回的文章列表数据 } }) ``` 在微信小程序中,我们还需要使用`wx.navigateTo()`和`wx.redirectTo()`等方法来实现页面跳转。例如,跳转到文章详情页: ``` wx.navigateTo({ url: &#39;/pages/article-detail/article-detail?id=&#39; + articleId }) ``` 其他具体实现细节可以参考下面的完整代码。 2. Spring Boot后端代码 在Spring Boot后端中,我们需要实现以下几个核心功能: - 文章列表查询接口:查询所有已发布的文章列表。 - 文章详情查询接口:查询某一篇文章的详细信息。 - 文章发布接口:发布一篇的文章。 - 评论列表查询接口:查询某一篇文章的所有评论。 - 评论发布接口:发布一条的评论。 - 点赞接口:对某一篇文章进行点赞或取消点赞操作。 下面给出一个简单的Spring Boot后端实现。 2.1 依赖 在`pom.xml`中添加以下依赖: ``` <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency> </dependencies> ``` 2.2 数据库 这使用MySQL来存储文章和评论的信息。在MySQL中创建`article`和`comment`表,具体的DDL语句如下: ``` CREATE TABLE `article` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT &#39;文章ID&#39;, `title` varchar(255) NOT NULL COMMENT &#39;文章标题&#39;, `author` varchar(255) NOT NULL COMMENT &#39;文章作者&#39;, `content` text NOT NULL COMMENT &#39;文章内容&#39;, `create_time` datetime NOT NULL COMMENT &#39;创建时间&#39;, `update_time` datetime NOT NULL COMMENT &#39;更时间&#39;, `praise_count` int(11) NOT NULL DEFAULT &#39;0&#39; COMMENT &#39;点赞数&#39;, `comment_count` int(11) NOT NULL DEFAULT &#39;0&#39; COMMENT &#39;评论数&#39;, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT=&#39;文章表&#39;; CREATE TABLE `comment` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT &#39;评论ID&#39;, `article_id` bigint(20) NOT NULL COMMENT &#39;文章ID&#39;, `content` text NOT NULL COMMENT &#39;评论内容&#39;, `create_time` datetime NOT NULL COMMENT &#39;创建时间&#39;, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT=&#39;评论表&#39;; ``` 2.3 实体 在Java中,我们需要定义相应的实体来映射数据库中的表结构。具体实现如下: 文章实体`Article.java`: ``` public class Article { private Long id; private String title; private String author; private String content; private Date createTime; private Date updateTime; private Integer praiseCount; private Integer commentCount; // getter 和 setter 方法省略 } ``` 评论实体`Comment.java`: ``` public class Comment { private Long id; private Long articleId; private String content; private Date createTime; // getter 和 setter 方法省略 } ``` 2.4 DAO层 在DAO层中,我们需要定义相应的接口和实现来操作数据库。具体实现如下: 文章DAO接口`ArticleDao.java`: ``` public interface ArticleDao { List<Article> list(); Article getById(Long id); int save(Article article); int updatePraiseCount(Long id, Integer delta); int updateCommentCount(Long id, Integer delta); } ``` 文章DAO实现`ArticleDaoImpl.java`: ``` @Repository public class ArticleDaoImpl implements ArticleDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public List<Article> list() { String sql = "SELECT * FROM article ORDER BY create_time DESC"; return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Article.class)); } @Override public Article getById(Long id) { String sql = "SELECT * FROM article WHERE id = ?"; return jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<>(Article.class)); } @Override public int save(Article article) { String sql = "INSERT INTO article(title, author, content, create_time, update_time) VALUES(?, ?, ?, ?, ?)"; return jdbcTemplate.update(sql, article.getTitle(), article.getAuthor(), article.getContent(), article.getCreateTime(), article.getUpdateTime()); } @Override public int updatePraiseCount(Long id, Integer delta) { String sql = "UPDATE article SET praise_count = praise_count + ? WHERE id = ?"; return jdbcTemplate.update(sql, delta, id); } @Override public int updateCommentCount(Long id, Integer delta) { String sql = "UPDATE article SET comment_count = comment_count + ? WHERE id = ?"; return jdbcTemplate.update(sql, delta, id); } } ``` 评论DAO接口`CommentDao.java`: ``` public interface CommentDao { List<Comment> listByArticleId(Long articleId); int save(Comment comment); } ``` 评论DAO实现`CommentDaoImpl.java`: ``` @Repository public class CommentDaoImpl implements CommentDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public List<Comment> listByArticleId(Long articleId) { String sql = "SELECT * FROM comment WHERE article_id = ? ORDER BY create_time ASC"; return jdbcTemplate.query(sql, new Object[]{articleId}, new BeanPropertyRowMapper<>(Comment.class)); } @Override public int save(Comment comment) { String sql = "INSERT INTO comment(article_id, content, create_time) VALUES(?, ?, ?)"; return jdbcTemplate.update(sql, comment.getArticleId(), comment.getContent(), comment.getCreateTime()); } } ``` 2.5 Service层 在Service层中,我们需要定义相应的接口和实现来处理业务逻辑。具体实现如下: 文章Service接口`ArticleService.java`: ``` public interface ArticleService { List<Article> list(); Article getById(Long id); int save(Article article); int updatePraiseCount(Long id, Boolean add); int updateCommentCount(Long id, Boolean add); } ``` 文章Service实现`ArticleServiceImpl.java`: ``` @Service public class ArticleServiceImpl implements ArticleService { @Autowired private ArticleDao articleDao; @Override public List<Article> list() { return articleDao.list(); } @Override public Article getById(Long id) { return articleDao.getById(id); } @Override public int save(Article article) { Date now = new Date(); article.setCreateTime(now); article.setUpdateTime(now); return articleDao.save(article); } @Override public int updatePraiseCount(Long id, Boolean add) { Integer delta = add ? 1 : -1; return articleDao.updatePraiseCount(id, delta); } @Override public int updateCommentCount(Long id, Boolean add) { Integer delta = add ? 1 : -1; return articleDao.updateCommentCount(id, delta); } } ``` 评论Service接口`CommentService.java`: ``` public interface CommentService { List<Comment> listByArticleId(Long articleId); int save(Comment comment); } ``` 评论Service实现`CommentServiceImpl.java`: ``` @Service public class CommentServiceImpl implements CommentService { @Autowired private CommentDao commentDao; @Override public List<Comment> listByArticleId(Long articleId) { return commentDao.listByArticleId(articleId); } @Override public int save(Comment comment) { Date now = new Date(); comment.setCreateTime(now); return commentDao.save(comment); } } ``` 2.6 Controller层 在Controller层中,我们需要定义相应的接口来处理HTTP请求。具体实现如下: 文章Controller`ArticleController.java`: ``` @RestController @RequestMapping("/article") public class ArticleController { @Autowired private ArticleService articleService; @Autowired private CommentService commentService; @GetMapping("/list") public List<Article> list() { return articleService.list(); } @GetMapping("/detail") public Article detail(Long id) { return articleService.getById(id); } @PostMapping("/publish") public int publish(@RequestBody Article article) { return articleService.save(article); } @PostMapping("/praise") public int praise(Long id, Boolean add) { return articleService.updatePraiseCount(id, add); } @GetMapping("/comment/list") public List<Comment> listComments(Long articleId) { return commentService.listByArticleId(articleId); } @PostMapping("/comment/publish") public int publishComment(@RequestBody Comment comment) { int result = commentService.save(comment); if (result > 0) { articleService.updateCommentCount(comment.getArticleId(), true); } return result; } } ``` 2.7 配置文件 在Spring Boot中,我们需要在`application.properties`或`application.yml`中配置相关参数。例如,配置MySQL连接信息: ``` spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ``` 其他具体实现细节可以参考下面的完整代码。 3. 完整代码 完整的微信小程序和Spring Boot后端的代码可以在我的GitHub仓库中查看: - 微信小程序:https://github.com/zhongmingmao/wechat-mini-program-example - Spring Boot后端:https://github.com/zhongmingmao/spring-boot-example
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值