springboot使用JdbcTemplate(二)

参考博客 http://tengj.top/2017/04/13/springboot8/

项目地址:https://github.com/snjl/springboot.jdbcTemplete.git

添加依赖

1
2
3
4
5
6
7
8
9
在pom.xml里添加spring-boot-starter-jdbc依赖跟mysql依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

数据源配置

在src/main/resources/application.properties中配置数据源信息:

1
2
3
4
spring.datasource.url = jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driver-class-name = com.mysql.jdbc.Driver

自定义数据源

添加mysql依赖(spring-boot-starter-jdbc 默认使用tomcat-jdbc数据源,如果要使用其他数据源,需要添加额外的依赖,这里使用了阿里巴巴的数据池管理):

1
2
3
4
5
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.19</version>
</dependency>

修改Application.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.dudu;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;

import javax.sql.DataSource;

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

@Autowired
private Environment env;

//destroy-method="close"的作用是当数据库连接不使用的时候,就把该连接重新放到数据池中,方便下次使用调用.
@Bean(destroyMethod = "close")
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));//用户名
dataSource.setPassword(env.getProperty("spring.datasource.password"));//密码
dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
dataSource.setInitialSize(2);//初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
dataSource.setMaxActive(20);//最大连接池数量
dataSource.setMinIdle(0);//最小连接池数量
dataSource.setMaxWait(60000);//获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
dataSource.setValidationQuery("SELECT 1");//用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。
dataSource.setTestOnBorrow(false);//申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
dataSource.setTestWhileIdle(true);//建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
dataSource.setPoolPreparedStatements(false);//是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
return dataSource;
}
}

Spring Boot会智能地选择我们自己配置的这个DataSource实例。

脚本初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

CREATE DATABASE /*!32312 IF NOT EXISTS*/`spring` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `spring`;

DROP TABLE IF EXISTS `learn_resource`;

CREATE TABLE `learn_resource` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`author` varchar(20) DEFAULT NULL COMMENT '作者',
`title` varchar(100) DEFAULT NULL COMMENT '描述',
`url` varchar(100) DEFAULT NULL COMMENT '地址链接',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1029 DEFAULT CHARSET=utf8;

insert into `learn_resource`(`id`,`author`,`title`,`url`) values (999,'官方SpriongBoot例子','官方SpriongBoot例子','https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples');
insert into `learn_resource`(`id`,`author`,`title`,`url`) values (1000,'龙果学院','Spring Boot 教程系列学习','http://www.roncoo.com/article/detail/124661');
insert into `learn_resource`(`id`,`author`,`title`,`url`) values (1001,'嘟嘟MD独立博客','Spring Boot干货系列','http://tengj.top/');
insert into `learn_resource`(`id`,`author`,`title`,`url`) values (1002,'后端编程嘟','Spring Boot视频教程','http://www.toutiao.com/m1559096720023553/');
insert into `learn_resource`(`id`,`author`,`title`,`url`) values (1003,'程序猿DD','Spring Boot系列','http://www.roncoo.com/article/detail/125488');
insert into `learn_resource`(`id`,`author`,`title`,`url`) values (1004,'纯洁的微笑','Sping Boot系列文章','http://www.ityouknow.com/spring-boot');
insert into `learn_resource`(`id`,`author`,`title`,`url`) values (1005,'CSDN——小当博客专栏','Sping Boot学习','http://blog.csdn.net/column/details/spring-boot.html');
insert into `learn_resource`(`id`,`author`,`title`,`url`) values (1006,'梁桂钊的博客','Spring Boot 揭秘与实战','http://blog.csdn.net/column/details/spring-boot.html');
insert into `learn_resource`(`id`,`author`,`title`,`url`) values (1007,'林祥纤博客系列','从零开始学Spring Boot','http://412887952-qq-com.iteye.com/category/356333');
insert into `learn_resource`(`id`,`author`,`title`,`url`) values (1028,'杜琪','关于Spring Boot的博客集合','http://www.jianshu.com/p/7e2e5e7b32ab');

使用JdbcTemplate

Spring的JdbcTemplate是自动配置的,可以直接使用@Autowired来注入到自己的bean中来使用。这里做了一套增伤改查。
pojo类:

1
2
3
4
5
6
7
public class LearnResouce {
private Long id;
private String author;
private String title;
private String url;
// SET和GET方法
}

dao层的接口实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.dudu.dao.impl;

import com.dudu.dao.LearnDao;
import com.dudu.domain.LearnResouce;
import com.dudu.tools.Page;
import com.dudu.tools.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

/**
* Created by tengj on 2017/4/8.
*/
@Repository
public class LearnDaoImpl implements LearnDao{
@Autowired
private JdbcTemplate jdbcTemplate;

@Override
public int add(LearnResouce learnResouce) {
return jdbcTemplate.update("insert into learn_resource(author, title,url) values(?, ?, ?)",learnResouce.getAuthor(),learnResouce.getTitle(),learnResouce.getUrl());
}

@Override
public int update(LearnResouce learnResouce) {
return jdbcTemplate.update("update learn_resource set author=?,title=?,url=? where id = ?",new Object[]{learnResouce.getAuthor(),learnResouce.getTitle(),learnResouce.getUrl(),learnResouce.getId()});
}

@Override
public int deleteByIds(String ids){
return jdbcTemplate.update("delete from learn_resource where id in("+ids+")");
}

@Override
public LearnResouce queryLearnResouceById(Long id) {
List<LearnResouce> list = jdbcTemplate.query("select * from learn_resource where id = ?", new Object[]{id}, new BeanPropertyRowMapper(LearnResouce.class));
if(null != list && list.size()>0){
LearnResouce learnResouce = list.get(0);
return learnResouce;
}else{
return null;
}
}

@Override
public Page queryLearnResouceList(Map<String,Object> params) {
StringBuffer sql =new StringBuffer();
sql.append("select * from learn_resource where 1=1");
if(!StringUtil.isNull((String)params.get("author"))){
sql.append(" and author like '%").append((String)params.get("author")).append("%'");
}
if(!StringUtil.isNull((String)params.get("title"))){
sql.append(" and title like '%").append((String)params.get("title")).append("%'");
}
Page page = new Page(sql.toString(), Integer.parseInt(params.get("page").toString()), Integer.parseInt(params.get("rows").toString()), jdbcTemplate);
return page;
}
}

其中值得注意的几个点:

  • jdbcTemplete直接使用@Autowired注解注入的;
  • deleteByIds这个方法是传入的数据是形如”(1,2,3,5)”这样的数据,是在controller里或者前端组装好的;
  • queryLearnResouceList这个方法返回的是一个Page对象,它需要的参数里有一个page,指的是当前页码,下面是Page.java的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package com.dudu.tools;

import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;
import java.util.Map;
/**
* Created by tengj on 2017/4/11.
*/
public class Page {
//一页显示的记录数
private int numPerPage;
//记录总数
private int totalRows;
//总页数
private int totalPages;
//当前页码
private int currentPage;
//起始行数
private int startIndex;
//结束行数
private int lastIndex;
//结果集存放List
private List<Map<String, Object>> resultList;


/**分页构造函数
* @param sql 包含筛选条件的sql,但不包含分页相关约束,如mysql的limit
* @param currentPage 当前页
* @param numPerPage 每页记录数
* @param jdbcTemplate jdbcTemplate实例
*/
public Page(String sql,int currentPage,int numPerPage,JdbcTemplate jdbcTemplate){
if(jdbcTemplate == null){
throw new IllegalArgumentException("Page.jdbcTemplate is null");
}else if(sql == null || sql.equals("")){
throw new IllegalArgumentException("Page.sql is empty");
}
//设置每页显示记录数
setNumPerPage(numPerPage);
//设置要显示的页数
setCurrentPage(currentPage);
//计算总记录数
StringBuffer totalSQL = new StringBuffer(" SELECT count(*) FROM ( ");
totalSQL.append(sql);
totalSQL.append(" ) totalTable ");
//总记录数
setTotalRows(jdbcTemplate.queryForObject(totalSQL.toString(),Integer.class));
//计算总页数
setTotalPages();
//计算起始行数
setStartIndex();
//计算结束行数
setLastIndex();
System.out.println("lastIndex="+lastIndex);
//使用mysql时直接使用limits
StringBuffer paginationSQL = new StringBuffer();
paginationSQL.append(sql);
paginationSQL.append(" limit " + startIndex + "," + lastIndex);
//装入结果集
setResultList(jdbcTemplate.queryForList(paginationSQL.toString()));
}



//计算总页数
public void setTotalPages() {
if(totalRows % numPerPage == 0){
this.totalPages = totalRows / numPerPage;
}else{
this.totalPages = (totalRows / numPerPage) + 1;
}
}

//计算结束时候的索引
public void setLastIndex() {
System.out.println("totalRows="+totalRows);///////////
System.out.println("numPerPage="+numPerPage);///////////
if( totalRows < numPerPage){
this.lastIndex = totalRows;
}else if((totalRows % numPerPage == 0) || (totalRows % numPerPage != 0 && currentPage < totalPages)){
this.lastIndex = currentPage * numPerPage;
}else if(totalRows % numPerPage != 0 && currentPage == totalPages){//最后一页
this.lastIndex = totalRows ;
}
}

Page的构造函数,将sql和其他条件拼接起来,从而得到每一页的信息。最后返回一个List<Map<String, Object>>对象和一些例如页码数、总数据条数等数据,作为一个Page数据。

Service层

没有特点。

Controller层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package com.dudu.controller;


import com.alibaba.fastjson.JSONObject;
import com.dudu.domain.LearnResouce;
import com.dudu.service.LearnService;
import com.dudu.tools.Page;
import com.dudu.tools.ServletUtil;
import com.dudu.tools.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Created by tengj on 2017/3/13.
*/
@Controller
@RequestMapping("/learn")
public class LearnController {
@Autowired
private LearnService learnService;
private Logger logger = LoggerFactory.getLogger(this.getClass());

@RequestMapping("")
public String learn(){
return "learn-resource";
}

@RequestMapping(value = "/queryLeanList",method = RequestMethod.POST,produces="application/json;charset=UTF-8")
@ResponseBody
public void queryLearnList(HttpServletRequest request ,HttpServletResponse response){
String page = request.getParameter("page"); // 取得当前页数,注意这是jqgrid自身的参数
String rows = request.getParameter("rows"); // 取得每页显示行数,,注意这是jqgrid自身的参数
String author = request.getParameter("author");
String title = request.getParameter("title");
Map<String,Object> params = new HashMap<String,Object>();
params.put("page", page);
params.put("rows", rows);
params.put("author", author);
params.put("title", title);
Page pageObj =learnService.queryLearnResouceList(params);
List<Map<String, Object>> learnList=pageObj.getResultList();
JSONObject jo=new JSONObject();
jo.put("rows", learnList);
jo.put("total", pageObj.getTotalPages());
jo.put("records", pageObj.getTotalRows());
ServletUtil.createSuccessResponse(200, jo, response);
}
/**
* 新添教程
* @param request
* @param response
*/
@RequestMapping(value = "/add",method = RequestMethod.POST)
public void addLearn(HttpServletRequest request , HttpServletResponse response){
JSONObject result=new JSONObject();
String author = request.getParameter("author");
String title = request.getParameter("title");
String url = request.getParameter("url");
if(StringUtil.isNull(author)){
result.put("message","作者不能为空!");
result.put("flag",false);
ServletUtil.createSuccessResponse(200, result, response);
return;
}
if(StringUtil.isNull(title)){
result.put("message","教程名称不能为空!");
result.put("flag",false);
ServletUtil.createSuccessResponse(200, result, response);
return;
}
if(StringUtil.isNull(url)){
result.put("message","地址不能为空!");
result.put("flag",false);
ServletUtil.createSuccessResponse(200, result, response);
return;
}
LearnResouce learnResouce = new LearnResouce();
learnResouce.setAuthor(author);
learnResouce.setTitle(title);
learnResouce.setUrl(url);
int index=learnService.add(learnResouce);
System.out.println("结果="+index);
if(index>0){
result.put("message","教程信息添加成功!");
result.put("flag",true);
}else{
result.put("message","教程信息添加失败!");
result.put("flag",false);
}
ServletUtil.createSuccessResponse(200, result, response);
}
/**
* 修改教程
* @param request
* @param response
*/
@RequestMapping(value = "/update",method = RequestMethod.POST)
public void updateLearn(HttpServletRequest request , HttpServletResponse response){
JSONObject result=new JSONObject();
String id = request.getParameter("id");
LearnResouce learnResouce=learnService.queryLearnResouceById(Long.valueOf(id));
String author = request.getParameter("author");
String title = request.getParameter("title");
String url = request.getParameter("url");
if(StringUtil.isNull(author)){
result.put("message","作者不能为空!");
result.put("flag",false);
ServletUtil.createSuccessResponse(200, result, response);
return;
}
if(StringUtil.isNull(title)){
result.put("message","教程名称不能为空!");
result.put("flag",false);
ServletUtil.createSuccessResponse(200, result, response);
return;
}
if(StringUtil.isNull(url)){
result.put("message","地址不能为空!");
result.put("flag",false);
ServletUtil.createSuccessResponse(200, result, response);
return;
}
learnResouce.setAuthor(author);
learnResouce.setTitle(title);
learnResouce.setUrl(url);
int index=learnService.update(learnResouce);
System.out.println("修改结果="+index);
if(index>0){
result.put("message","教程信息修改成功!");
result.put("flag",true);
}else{
result.put("message","教程信息修改失败!");
result.put("flag",false);
}
ServletUtil.createSuccessResponse(200, result, response);
}
/**
* 删除教程
* @param request
* @param response
*/
@RequestMapping(value="/delete",method = RequestMethod.POST)
@ResponseBody
public void deleteUser(HttpServletRequest request ,HttpServletResponse response){
String ids = request.getParameter("ids");
System.out.println("ids==="+ids);
JSONObject result = new JSONObject();
//删除操作
int index = learnService.deleteByIds(ids);
if(index>0){
result.put("message","教程信息删除成功!");
result.put("flag",true);
}else{
result.put("message","教程信息删除失败!");
result.put("flag",false);
}
ServletUtil.createSuccessResponse(200, result, response);
}
}

这里使用了ServletUtil,在此仅举出一例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
	public static String createSuccessResponse(Integer httpCode, Object result, SerializerFeature serializerFeature, SerializeFilter filter, HttpServletResponse response){
PrintWriter printWriter = null;
String jsonString = "";
try {
response.setCharacterEncoding(RESPONSE_CHARACTERENCODING);
response.setContentType(RESPONSE_CONTENTTYPE);
response.setStatus(httpCode);
printWriter = response.getWriter();
if(null != result){
if(null!=filter){
jsonString = JSONObject.toJSONString(result,filter,serializerFeature);
}else{
// jsonString = JSONObject.toJSONString(result, serializerFeature);
jsonString = JSONObject.toJSONStringWithDateFormat(result,"yyyy-MM-dd HH:ss:mm",serializerFeature);
}
printWriter.write(jsonString);
}
printWriter.flush();

} catch (Exception e) {
log.error("createResponse failed", e);
} finally {
if(null!=printWriter)printWriter.close();
}
return jsonString;
}

页面展示

iamge

iamge

iamge

-------------本文结束 感谢您的阅读-------------