JAVA WEB之Spring4.x JdbcTemplate
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);}
}
基本思路就是:
- 连接数据库时的字符串常量,变量
- 加载jdbc类库
- 获得一个连接
- 获得一个连接的状态
- 通过状态使用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相关推荐
- 【Java Web开发学习】Spring4条件化的bean
[Java Web开发学习]Spring4条件化的bean 转载:https://www.cnblogs.com/yangchongxing/p/9071960.html Spring4引入了@Con ...
- JAVA WEB整合开发王者归来 -- 读书笔记 by CZF 完整版
JAVA WEB整合开发王者归来 -- 读书笔记 目录 第1章 概述. 1 第2章 搭建web开发环境. 1 第3章 Servlet技术. 1 第4章 深入JSP技术. 7 第5章 会话跟踪. 12 ...
- Java Web开发之一:用好的技术设计来犒赏自己
(转帖请注明http://taobaotesting.com/blogs/2359) 2012年下半年,我负责的测试平台部分业务开始采用java进行开发,10月份的时候我也加入了具体的设计开发工作中, ...
- 基于Java web的客户关系(crm)管理系统
题目是基于java web的CRM客户关系管理系统的设计和实现 1.这个系统开发的环境: 开发工具:MyEclipse2010版 数据库:MySql+HeidiSql JDK:MyEclipse201 ...
- Java Web 08_tomcatServlet
Java Web 08_tomcat&Servlet web相关概念回顾 web服务器软件: Servlet: server applet IDEA与tomcat的相关配置 Servlet: ...
- java web漏洞_如何安全检测Java Web应用网站漏洞
展开全部 如何安全检测Java Web应用网站漏洞.txt32因为爱心,流浪的人们才e68a843231313335323631343130323136353331333337383932能重返家园: ...
- java 框架漏洞网站_在分层架构下寻找java web漏洞
web开发应用程序(网站),是目前应用最广泛的程序.但是开发者的水平参差不齐,导致了各种各样web漏洞的出现.本文站在分层架构的角度,分析一下如何在java web程序中找到可能出现的种种漏洞. 本文 ...
- Java Web技术总结
这篇总结主要是基于我之前两个系列的文章而来.主要是把重要的知识点用自己的话说了一遍,可能会有一些错误,还望见谅和指点.谢谢 更多详细内容可以查看我的专栏文章: #JavaWeb技术世界 https:/ ...
- 在k8s中使用gradle构建java web项目镜像Dockerfile
在k8s中使用gradle构建java web项目镜像Dockerfile FROM gradle:6-jdk8 AS build COPY --chown=gradle:gradle . /home ...
最新文章
- nacos 怎么配置 里的配置ip_Nacos部署--配置中心
- SAP MM Movement Type 503的使用
- 【Discuz】云平台服务:出了点小错,由于站点ID/通信KEY等关键信息丢失导致Discuz!云平台服务出现异常
- JAVA传递子类参数,在Java中,是否可以通过传递超类方法中使用的参数的子类来覆盖方法?...
- python自学流程-python 学习之 基础篇三 流程控制
- 百度大脑险胜最强大脑背后:200万人2亿照片做训练
- oracle loder nextval,ORA-07445: 出现异常错误: 核心转储
- 【剑指offer】字符串的排列
- 传送门(最短路树+可并堆)
- 前端学习(3336):ant design中button按钮类型
- Windows Phone 7 使用Canvas Grid StackPanel进行布局管理
- Linux中让普通用户拥有超级用户的权限
- Sklearn——保存模型参数(picklejoblib)
- 深入理解ButterKnife源码并掌握原理(三)
- [原创]Linux下网络性能测试Netperf工具介绍及安装
- Iocomp.Ultra Pack V5.SP3 for .Net Crack
- Auto CAD 批量转PDF、批量打印使用方法
- html转邮件html格式转换,如何把电子邮件格式改成HTML格式
- 微生物生态数据分析——冗余分析
- BugkuCTF 秋名山老司机wp