jdbcTemplate

说白了,他就是Spring提供用于简化数据库访问的类

基本jdbc驱动访问数据库

/* 一个简易好用的数据库连接和访问类 */
package cslg.cn.controller;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;public class MyDB {private static final String database="bookmark";private static final String user="root";private static final String password="";private Connection connection;  private Statement statement;public void openConnection() throws SQLException{try {Class.forName("com.mysql.jdbc.Driver");String url="jdbc:mysql://localhost:3306/"+database;connection=DriverManager.getConnection(url, user, password);statement=connection.createStatement();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void closeConnection(){try {if(statement!=null){statement.close();}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}ResultSet executeQuery(String sql) throws SQLException {ResultSet rs=statement.executeQuery(sql);return rs;}void executeUpdate(String sql) throws SQLException {statement.executeUpdate(sql);}
}

基本思路就是:

  1. 连接数据库时的字符串常量,变量
  2. 加载jdbc类库
  3. 获得一个连接
  4. 获得一个连接的状态
  5. 通过状态使用query或者update访问数据库

基本可用的也就是读写两个方法:

statement.executeQuery(sql)
statement.executeUpdate(sql)

我们还需要对query方法返回的ResultSet类进行处理:

while (res.next()) {BookMark bm = new BookMark(res.getInt(1), res.getString(2), res.getString(3), res.getString(4),res.getInt(5));bms.add(bm);
}

如果时多条数据查询,一般需要一个数据模型类(pojo类),然后建立一个这个模型的List泛型对象,通过ResultSet的next()方法遍历每一条记录,使用getInt,getString等方式取得字段。

Spring JdbcTemplate访问数据库

如果我们使用像hibernate,mybatits这样的orm的话,虽然模型映射为sql语句确实非常方便,但是性能上就有一定阉割,在不需要大量数据查询的小型项目上,我们不用偷懒,写几句简单的sql语句使得查询和写入更加有效率。
但是我们像上面那样每次都通过while语句去取出Result的话,岂不是很麻烦,而且这样的多个while代码块显得代码十分冗余。
JdbcTemplate为我们封装了这些取值操作,减少了写循环的痛苦,性能上却并没有被阉割,和纯粹的sql语句查询相当,因为我们依然要写出完整的sql语句,而不是采用映射的办法,所以这个template非常好用的。

项目结构

由于仅仅是学习测试jdbctemplate,所以不需要web访问,使用Main方法运行,自然建立普通的gradle project即可,并不需要转换
结构也只需要对java resource添加java类即可:

配置

配置xml文件,properties文件

如果是web dynamic项目的话xml文件可以web-inf下新建config.xml或者直接在java Resource目录下新建

config.xml,我使用了4.3版本:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"xmlns:c="http://www.springframework.org/schema/c" xmlns:context="http://www.springframework.org/schema/context"xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:p="http://www.springframework.org/schema/p"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"><context:annotation-config /><context:component-scan base-package="jdbc"></context:component-scan><context:property-placeholder location="classpath:jdbc.properties" /><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close" p:driverClassName="${jdbc.driverClassName}"p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}" /><bean id="jdbc" class="org.springframework.jdbc.core.JdbcTemplate"p:dataSource-ref="dataSource" />
</beans>

以上对各种Bean做了配置,用于提供JdbcTemplate连接数据库

jdbc.properties:

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/j2ee?characterEncoding=utf8
jdbc.username=root
jdbc.password=

如果是gradle项目:

修改gradle.build以获得需要的jar包:

apply plugin: 'java-library'// In this section you declare where to find the dependencies of your project
repositories {// Use jcenter for resolving your dependencies.// You can declare any Maven/Ivy/file repository here.jcenter()
}
ext{springVersion="4.3.1.RELEASE"
}dependencies {compile group: 'org.slf4j', name:'slf4j-api', version:'1.7.21'compile group: 'commons-codec', name: 'commons-codec', version: '1.10'compile group: 'commons-collections', name: 'commons-collections', version: '3.2.2'compile group: 'commons-dbcp', name: 'commons-dbcp', version: '1.4'compile group: 'org.aspectj', name: 'aspectjweaver', version: '1.8.9'compile group: 'aopalliance', name: 'aopalliance', version: '1.0'compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.38'compile("org.springframework:spring-core:$springVersion","org.springframework:spring-beans:$springVersion","org.springframework:spring-aop:$springVersion","org.springframework:spring-tx:$springVersion","org.springframework:spring-jdbc:$springVersion","org.springframework:spring-context:$springVersion","org.springframework:spring-test:$springVersion")// This dependency is exported to consumers, that is to say found on their compile classpath.api 'org.apache.commons:commons-math3:3.6.1'// This dependency is used internally, and not exposed to consumers on their own compile classpath.implementation 'com.google.guava:guava:20.0'// Use JUnit test frameworktestImplementation 'junit:junit:4.12'
}

POJO类

该Project是对数据库文章进行增删改查,所以,我新建了一个Article类,为数据库Article表模型:

package jdbc;public class Article {private int id;private String title;private String content;@Overridepublic String toString() {return "Article [id=" + id + ", title=" + title + ", content=" + content + "]";}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public Article(int id, String title, String content) {super();this.id = id;this.title = title;this.content = content;}public Article(String title, String content) {super();this.title = title;this.content = content;}public Article(){}}

Article的DAO层

在面向接口对象编程中

MVC的开发模式:表示层调用控制层,控制层调用业务层,业务层(Service)调用数据访问层(DAO)
就是这样层层剥离,解耦,使得一个层的修改不会导致其他层的修改,更利于团队分层并行编程
当然如果使用的是动态语言,比如php,是不需要剥离出这么多层这么麻烦的!

其中dao是数据访问层,其实是一个集成了一些专门对某个模型直接访问数据库方法的类,比如增删改查等,便于在业务逻辑层(service层)使用这些方法,操作相应的模型,而hibernate这样的orm则是通过映射来封装了相应的模型访问数据库方法,做成了DAO层,不必自己去写

ArticleDAO:

package jdbc;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;@Repository
public class ArticleDAO {@Autowiredprivate JdbcTemplate jdbcTemplate;// 查public Article find(int id) {final String sql = "select * from article where id=?";Article ac = jdbcTemplate.queryForObject(sql, new Object[] { id },new BeanPropertyRowMapper<Article>(Article.class));return ac;}// 改public boolean update(Article a) {final String sql = "update article set title=?,content=? where id=?";int rc = jdbcTemplate.update(sql, new Object[] { a.getTitle(), a.getContent(), a.getId() });return 1 == rc;}// 删public boolean delete(int id) {final String sql = "delete from article where id=?";int rc = jdbcTemplate.update(sql, new Object[] { id });return 1 == rc;}// 增public int add(Article a) {KeyHolder holder = new GeneratedKeyHolder();final String sql = "insert into article(title,content) values(?,?)";jdbcTemplate.update(new PreparedStatementCreator() {@Overridepublic PreparedStatement createPreparedStatement(Connection con) throws SQLException {PreparedStatement ps = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);ps.setString(1, a.getTitle());ps.setString(2, a.getContent());return ps;}}, holder);return holder.getKey().intValue();}//根据开始和限定条数查询多条public List<Article> list(int begin, int limit) {final String sql = "select * from article limit ?,?";return jdbcTemplate.query(sql, new Object[] { begin, limit },new BeanPropertyRowMapper<Article>(Article.class));}}

注意DAO层提供对数据的访问方法库,这里包括了常用的CRUD操作,其中查方法有两种,一种是单条根据主键查询(id),另一种是指定条数开始和数目的多条查询(limit),这里需要用到一个数据库对Bean的映射。

由于jdbcTemplate中的queryForObject方法,第三个参数只能是匹配简单的Interger,String,Boolean等基本类型,不可以传入复杂的数据类型,这里直接传入Article.class是会报异常:
Exception in thread "main" org.springframework.jdbc.IncorrectResultSetColumnCountException: Incorrect column count: expected 1, actual 3

如果是Junit环境下测试是不会获得此List对象(不匹配,不报异常)

所以使用BeanPropertyRowMapper(T.class),此方法的作用是让数据库读出的数据行的字段和java类下的属性一一对应(赋值)。queryForObject的最终效果是要让查询获得row自动匹配到相应的java对象!
(这已经很接近orm技术了!)

注:自动绑定,需要列名称和Java实体类名字一致,如:属性名 “userName” 可以匹配数据库中的列字段 "USERNAME" 或 “user_name”。

关于query和queryForObject的区别:
eclipse自动补全中有说明:

query:传入sql语句,对应的占位对象数组(就是sql中?),RowMapper映射对象。

最终返回的也是RowMapper映射的对象的List列表!

注意是列表!一般用于多条查询的

queryForObject:传入sql,对应的占位对象数组(sql中的?),基本对象的.class属性,或者RowMapper

如果是基本对象Integer,Boolean等则返回相应的与第三个传入参数一样的对象(.class前面的类名)

如果是RowMapper则返回映射后的对象,即第三个参数.class前面的类名!

注:这儿是单个对象,一般用于单条查询

MAIN方法

由于我们是相对简单的应用,不再需要Service层做业务处理,可以直接使用此DAO层进行数据访问,写在Main方法中即可:

main:

package jdbc;
import java.util.Scanner;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MainTest {@SuppressWarnings("resource")public static void main(String[] args) {//加载xml配置文件ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:config.xml");//取得Bean类并且映射为DAO类ArticleDAO aDAO = ctx.getBean(ArticleDAO.class);int id = 0;Scanner s = new Scanner(System.in);while (true) {System.out.println("输入查询id:");id = s.nextInt();try {Article a = aDAO.find(id); // 传入id查询System.out.println(a);} catch (Exception e) {//抛出查不到的异常,不要让查询错误使得程序结束System.out.println("查询不到结果!");// 传入id找不到就报错}System.out.println();}}
}

测试结果:

尝试其他的DAO方法(list查询):

转载于:https://www.cnblogs.com/devilyouwei/p/6844769.html

JAVA WEB之Spring4.x JdbcTemplate相关推荐

  1. 【Java Web开发学习】Spring4条件化的bean

    [Java Web开发学习]Spring4条件化的bean 转载:https://www.cnblogs.com/yangchongxing/p/9071960.html Spring4引入了@Con ...

  2. JAVA WEB整合开发王者归来 -- 读书笔记 by CZF 完整版

    JAVA WEB整合开发王者归来 -- 读书笔记  目录 第1章 概述. 1 第2章 搭建web开发环境. 1 第3章 Servlet技术. 1 第4章 深入JSP技术. 7 第5章 会话跟踪. 12 ...

  3. Java Web开发之一:用好的技术设计来犒赏自己

    (转帖请注明http://taobaotesting.com/blogs/2359) 2012年下半年,我负责的测试平台部分业务开始采用java进行开发,10月份的时候我也加入了具体的设计开发工作中, ...

  4. 基于Java web的客户关系(crm)管理系统

    题目是基于java web的CRM客户关系管理系统的设计和实现 1.这个系统开发的环境: 开发工具:MyEclipse2010版 数据库:MySql+HeidiSql JDK:MyEclipse201 ...

  5. Java Web 08_tomcatServlet

    Java Web 08_tomcat&Servlet web相关概念回顾 web服务器软件: Servlet: server applet IDEA与tomcat的相关配置 Servlet: ...

  6. java web漏洞_如何安全检测Java Web应用网站漏洞

    展开全部 如何安全检测Java Web应用网站漏洞.txt32因为爱心,流浪的人们才e68a843231313335323631343130323136353331333337383932能重返家园: ...

  7. java 框架漏洞网站_在分层架构下寻找java web漏洞

    web开发应用程序(网站),是目前应用最广泛的程序.但是开发者的水平参差不齐,导致了各种各样web漏洞的出现.本文站在分层架构的角度,分析一下如何在java web程序中找到可能出现的种种漏洞. 本文 ...

  8. Java Web技术总结

    这篇总结主要是基于我之前两个系列的文章而来.主要是把重要的知识点用自己的话说了一遍,可能会有一些错误,还望见谅和指点.谢谢 更多详细内容可以查看我的专栏文章: #JavaWeb技术世界 https:/ ...

  9. 在k8s中使用gradle构建java web项目镜像Dockerfile

    在k8s中使用gradle构建java web项目镜像Dockerfile FROM gradle:6-jdk8 AS build COPY --chown=gradle:gradle . /home ...

最新文章

  1. nacos 怎么配置 里的配置ip_Nacos部署--配置中心
  2. SAP MM Movement Type 503的使用
  3. 【Discuz】云平台服务:出了点小错,由于站点ID/通信KEY等关键信息丢失导致Discuz!云平台服务出现异常
  4. JAVA传递子类参数,在Java中,是否可以通过传递超类方法中使用的参数的子类来覆盖方法?...
  5. python自学流程-python 学习之 基础篇三 流程控制
  6. 百度大脑险胜最强大脑背后:200万人2亿照片做训练
  7. oracle loder nextval,ORA-07445: 出现异常错误: 核心转储
  8. 【剑指offer】字符串的排列
  9. 传送门(最短路树+可并堆)
  10. 前端学习(3336):ant design中button按钮类型
  11. Windows Phone 7 使用Canvas Grid StackPanel进行布局管理
  12. Linux中让普通用户拥有超级用户的权限
  13. Sklearn——保存模型参数(picklejoblib)
  14. 深入理解ButterKnife源码并掌握原理(三)
  15. [原创]Linux下网络性能测试Netperf工具介绍及安装
  16. Iocomp.Ultra Pack V5.SP3 for .Net Crack
  17. Auto CAD 批量转PDF、批量打印使用方法
  18. html转邮件html格式转换,如何把电子邮件格式改成HTML格式
  19. 微生物生态数据分析——冗余分析
  20. BugkuCTF 秋名山老司机wp

热门文章

  1. 如何避免把软件装到C盘
  2. 【Tools】Bandicam安装和卸载
  3. 【Tiny4412】最小网络文件系统制作
  4. 【STM32】 keil新建工程模板
  5. 一个4体低位交叉的存储器_GD25Q16CSIG|NRAM存储器的原理及优势是什么?
  6. 分页携带请求参数_一个值得深思的小问题 请求中的参数值为空要不要携带该参数?...
  7. Qt 如何消除边框 及 实现透明底色
  8. python面向对象(3)
  9. layui登录页面写入数据_layui 页面保存数据
  10. [NOTE] 关于DNSLog平台的使用