Spring框架经常在项目中处于“粘合剂”的作用,减少项目的硬代码。
Spring除了能整合持久层框架外,自身也提供了对数据库JDBC操作的封装类–JdbcTemplate。
JdbcTemplate是对JDBC很轻的封装,具有较高的执行效率,一般用于系统数据库并发操作压力大的项目中。
系统:Windows10
开发软件:IDEA
JDK:1.8.0_151
数据库:Mysql
框架:Maven、Spring4.1.1.RELEASE
我们需要导入项目所需的jar包,Mysql的驱动,Spring框架,Junit测试包等。
对pom.xml文件的配置:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.sunsharinggroupId>
<artifactId>springJDBCartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<spring.version>4.1.1.RELEASEspring.version>
<slf4j.version>1.7.7slf4j.version>
<log4j.version>1.2.17log4j.version>
properties>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.11version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-supportartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>commons-dbcpgroupId>
<artifactId>commons-dbcpartifactId>
<version>1.4version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.34version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>${log4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>${slf4j.version}version>
dependency>
dependencies>
project>
创建一个实体类User对象:
package com.entity;
public class User {
private int uid;
private String username;
private String psd;
public int getUid() {
return uid;
}
public String getUsername() {
return username;
}
@Override
public String toString() {
return "User{" +
"uid=" + uid +
", username='" + username + '\'' +
", psd='" + psd + '\'' +
'}';
}
public String getPsd() {
return psd;
}
public User(int uid, String username, String psd) {
this.uid = uid;
this.username = username;
this.psd = psd;
}
public User() {
}
public void setUid(int uid) {
this.uid = uid;
}
public void setUsername(String username) {
this.username = username;
}
public void setPsd(String psd) {
this.psd = psd;
}
}
还要创建一个Dao类对象,用于数据库的操作:
package com.dao;
import com.entity.User;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
public class UserDaoImpl {
private DataSource ds;
private JdbcTemplate template;//spring对JDBC封装的操作工具类。原理是模板设计模式
public DataSource getDs() {
return ds;
}
public void setDs(DataSource ds) {
this.ds = ds;
template = new JdbcTemplate(ds);//使用连接池构造一个工具类对象
}
//查找数据库中的所有人
public List<User> findAll() {
String sql = "select * from users";
List<Map<String,Object>> list2 = template.queryForList(sql);
//1个map相当于1条记录。
List<User> list1 = new ArrayList<>();
for(Map<String,Object> map:list2)
{
list1.add(new User((Integer)map.get("uid"),(String) map.get("username"),(String) map.get("psd")));
}
return list1;
}
}
配置applicationContext.xml文件,其中涉及到连接池的配置与dao类对象的bean:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="maxActive" value="50"/>
<property name="minIdle" value="5" />
<property name="maxWait" value="5000" />
bean>
<bean id="dao" class="com.dao.UserDaoImpl">
<property name="ds" ref="dataSource" />
bean>
beans>
最后在测试类中SqlTest.java测试:
import com.dao.UserDaoImpl;
import com.entity.User;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class SqlTest {
@Test
public void Springtest() {
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取dao对象
UserDaoImpl dao = (UserDaoImpl) factory.getBean("dao");
//调用dao方法
List list = dao.findAll();
//查询数据并输出
for (User u:list) {
System.out.println(u);
}
}
}
输出结果:
查询所有的功能可实现,但是在刚刚的dao类中JdbcTemplate的操作略微复杂,看能不能用更简单的语句去实现。(为了阅读方便,以下是刚刚dao类中的findAll方法)
//查找数据库中的所有人
public List<User> findAll() {
String sql = "select * from users";
List<Map<String,Object>> list2 = template.queryForList(sql);
//1个map相当于1条记录。
List<User> list1 = new ArrayList<>();
for(Map<String,Object> map:list2)
{
list1.add(new User((Integer)map.get("uid"),(String) map.get("username"),(String) map.get("psd")));
}
return list1;
}
Spring框架有个缺陷,在使用template.queryforList(sql, class)方法时,后面的class必须为String与Integer类型的class,否则输出的数据库字段超过1列会抛出异常:org.springframework.jdbc.IncorrectResultSetColumnCountException: Incorrect column count: expected 1, actual 3。
于是我创建1个匿名内部类来提取数据,新建一个findall方法:
public List<User> findall() {
String sql = "select * from users";
//创建1个匿名内部类对象,用于提取数据
//如何从结果集提取数据
List<User> list = template.query(sql,
rs -> {
List<User> list1 = new ArrayList<>();
while(rs.next())
list1.add(new User(rs.getInt("uid"),rs.getString("username"),rs.getString("psd")));
return list1;
}
);
return list;
}
注:IDEA提示可用Lambda表达式简写,于是中间匿名内部类我让IDEA自动转换成Lambda表达式了。
最后在测试类中测试:
@Test
public void Springtest() {
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取dao对象
UserDaoImpl dao = (UserDaoImpl) factory.getBean("dao");
//调用dao方法
List list = dao.findall();
//查询数据并输出
for (User u:list) {
System.out.println(u);
}
}
输出结果2:
与之前的输出结果一致,似乎也没优化特别多,就当是拓展吧。
再写一个精确查询的功能,在UserDaoImpl中新增方法:
public User findById(Integer uid) {
String sql = "select * from users where uid = ?";
User u = template.query(sql, new Object[]{uid},
rs -> {
if (rs.next()) //如果找的到
return new User(rs.getInt("uid"), rs.getString("username"), rs.getString("psd"));
else
return null;
}
);
return u;
}
在test测试类中更改为:
@Test
public void Springtest() {
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取dao对象
UserDaoImpl dao = (UserDaoImpl) factory.getBean("dao");
User user = dao.findById(1);
System.out.println(user);
}
public List findByName(String username) {
String sql = "select * from users where username like ?";
List list = template.query(sql, new Object[]{"%" + username + "%"},
rs -> {
List list1 = new ArrayList<>();
while (rs.next())
list1.add(new User(rs.getInt("uid"), rs.getString("username"), rs.getString("psd")));
return list1;
}
);
return list;
}
测试类:
@Test
public void Springtest() {
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取dao对象
UserDaoImpl dao = (UserDaoImpl) factory.getBean("dao");
//调用dao方法
List list = dao.findByName("A");//查找含有A字母的人
//查询数据并输出
for (User u:list) {
System.out.println(u);
}
}
输出结果4:
其实这还不够精确,我要求的是大写字母A,结果小写的a也查出来了,其实只要用右模糊就可以了实现了,介绍到此为止了。