Spring对JDBC封装JdbcTemplate的概述与查询功能

一、JdbcTemplate的概述

Spring框架经常在项目中处于“粘合剂”的作用,减少项目的硬代码。
Spring除了能整合持久层框架外,自身也提供了对数据库JDBC操作的封装类–JdbcTemplate。
JdbcTemplate是对JDBC很轻的封装,具有较高的执行效率,一般用于系统数据库并发操作压力大的项目中。

二、开发环境

系统:Windows10
开发软件:IDEA
JDK:1.8.0_151
数据库:Mysql
框架:Maven、Spring4.1.1.RELEASE

三、项目搭建

项目工程目录:
Spring对JDBC封装JdbcTemplate的概述与查询功能_第1张图片

数据库:
Spring对JDBC封装JdbcTemplate的概述与查询功能_第2张图片

四、编写代码

我们需要导入项目所需的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);
        }
    }
}

输出结果:
Spring对JDBC封装JdbcTemplate的概述与查询功能_第3张图片
查询所有的功能可实现,但是在刚刚的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;
    }

五、优化findAll方法

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:
Spring对JDBC封装JdbcTemplate的概述与查询功能_第4张图片
与之前的输出结果一致,似乎也没优化特别多,就当是拓展吧。

六、精确查询

再写一个精确查询的功能,在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);
    }

输出结果3:
输出结果3
按名字查找的功能findByName:

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:
输出结果4
其实这还不够精确,我要求的是大写字母A,结果小写的a也查出来了,其实只要用右模糊就可以了实现了,介绍到此为止了。

你可能感兴趣的:(实习)