JDBCTemplate的简单应用

JDBCTemplate概述

在讲JDBCTemplate之前,我先来介绍一下什么是JDBC,JDBC即java database connectivity,指Java数据库连接,是Java语言中用来规范客户端程序如何来访问数据库的应用程序的接口,提供了诸如查询,更新数据库中的数据的方法;
JDBCTemplate则是Spring 对 JDBC的封装,JDBCTemplate能够帮助程序员更加高效便利的进行开发,下面我们来对比一下用JDBC开发和JDBCTemplate开发有哪些区别吧。
本文使用的是JDK 11,数据库使用的是MySql 8.0,使用的是eclipse 进行开发

JDBC操作数据库步骤:
1.加载驱动(一定要和数据库的版本一致,导入对应的驱动包)
Class.forName(“Driver实现类的全路径类名”)[第三方的包]
加载这个类,调用静态代码块,实例化一个驱动,然后注册到DriverManager
2.获得连接
Connection = DriverManager.getConnection(url,user,password);
3.编写sql 语句
4.准备Statement,发送sql,并执行
Statement statement = connection.createStatement();
statement.execute(sql);//select
statement.executeUpdate(sql);//insert update delete
5.如果有结果集,解析结果集
ResultSet resultSet = statement.executeQuery( sql );
//执行给定的SQL语句,该语句返回单个ResultSet对象。
ResultSet resultSet = statement.executeUpdate( sql );
//执行给定的SQL语句,这可能是INSERT , UPDATE ,或DELETE语句
6.关闭资源
在以上步骤中有大量重复的代码,于是我们就有了JDBCTemplate,
JDBCTempalte中执行sql语句的方法大致分为3类:
execute:可以执行所有sql语句,一般用于执行DDL语句
update:用于执行insert,update,delete等DML语句
queryXxx:用于DQL数据查询语句

JDBCTemplate 对象的创建需要连接池,这里我们使用的是 DBCP 连接池
public JdbcTemplate(DataSource dataSource)
接下来我们用一个小的案例来演示一下JDBCTemplate的使用方法:

(1)首先我们先创建一个数据库

CREATE DATABASE jdbctest DEFAULT CHARACTER SET utf8

(2)接着我们创建一个数据表tb_user

CREATE TABLE tb_user ( 
id INT PRIMARY KEY auto_increment, 
username VARCHAR ( 20 ) NOT NULL, 
age INT );

(3)我们向表中添加几组数据

INSERT INTO tb_user VALUES( 100, 'Lily', 20 );
INSERT INTO tb_user VALUES( 101, 'Nancy', 21 );
INSERT INTO tb_user VALUES( 102, 'Mike', 20 );

(4)接着我们到 eclipse 中创建项目,点击next
在这里插入图片描述
在这里插入图片描述
添加jar包,这里添加了jdbc依赖包,lombok依赖包,dbcp依赖包
在这里插入图片描述
(5)创建好项目之后,我们先来完善一下项目结构
在这里插入图片描述
(6)接着把db.properties配置文件放在src目录下
db.properties的内容如下:

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbctest?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username=root
password=123456

#<!-- 初始化连接 -->
dataSource.initialSize=10

#<!-- 最大空闲连接 -->
dataSource.maxIdle=20

#<!-- 最小空闲连接 -->
dataSource.minIdle=5

#最大连接数量
dataSource.maxActive=50

#是否在自动回收超时连接的时候打印连接的超时错误
dataSource.logAbandoned=true

#是否自动回收超时连接
dataSource.removeAbandoned=true

#超时时间(以秒数为单位)
#设置超时时间有一个要注意的地方,超时时间=现在的时间-程序中创建Connection的时间,如果maxActive比较大,比如超过100,那么removeAbandonedTimeout可以设置长一点比如180,
#也就是三分钟无响应的连接进行回收,当然应用的不同设置长度也不同。
dataSource.removeAbandonedTimeout=180

#<!-- 超时等待时间以毫秒为单位 -->
#maxWait代表当Connection用尽了,多久之后进行回收丢失连接
dataSource.maxWait=1000

(7)添加工具类:JDBCUtil和静态工厂类BeanFactory
JDBCUtil:

package com.gem.util;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;

public class JDBCUtil {
	private static DataSource dataSource;
	static {
		Properties properties = new Properties();
		try {
			properties.load(JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties"));
			try {
				dataSource = new BasicDataSourceFactory().createDataSource(properties);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static DataSource getDataSource() {
		return dataSource;
	}

	public static Connection getConnection() {
		try {
			return dataSource.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static void close(ResultSet set, Statement preparedStatement, Connection connection) {
		if (set != null) {
			try {
				set.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (preparedStatement != null) {
			try {
				preparedStatement.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (connection != null) {
			try {
				connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

	}

}

BeanFactory:

package com.gem.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class BeanFactory {
	public static Object getBean(String allClassName) {
		try {
			Class objectClass = Class.forName(allClassName);
			Constructor<Object> constructor = objectClass.getConstructor();//无参构造
			return constructor.newInstance();//实例化对象
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}

(8)添加完工具类之后,我们准备工作就做好了,接下来我们先来写实体类User

package com.gem.entity;

import lombok.*;

@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
	private Integer id;
	private String username;
	private Integer age;

	public User(String username, Integer age) {
		super();
		this.username = username;
		this.age = age;
	}

}

(9)接着写持久层UserDao 和UserDaoImpl
UserDao:

package com.gem.dao;

import java.util.List;

import com.gem.entity.User;

public interface UserDao {
	//查看所有用户
	List<User> selectAllUser();

	//根据id查找用户
	User selectUserById(int id);

	//根据年龄查找用户
	List<User> selectUserByAge(int age);

	//添加用户
	boolean insertUser(User user);

	//删除用户
	boolean deleteUserById(int id);

	//修改用户信息
	boolean updateUserById(User user);

}

UserDaoImpl:
★主要看一下UserDaoImpl中,JDBCTemplate中的实现细节。

package com.gem.dao.impl;

import java.util.List;

import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import com.gem.dao.UserDao;
import com.gem.entity.User;
import com.gem.util.JDBCUtil;

public class UserDaoImpl implements UserDao {
	//创建JDBCTemplate的对象,并获得连接池对象
	JdbcTemplate template = new JdbcTemplate(JDBCUtil.getDataSource());

	@Override
	public List<User> selectAllUser() {//查看所有用户
		//编写sql语句
		String sql = "select * from tb_user";
		//创建一个users集合来存放从数据库中取出的User对象,BeanPropertyRowMapper的作用是将实体类User中的各个属性对应数据库中的各个字段,
		//将数据库中的数据取出(所以实体类中的属性名要和数据库中的字段名相同)
		List<User> users = template.query(sql, new BeanPropertyRowMapper<User>(User.class));
		if (users.size() > 0)
			return users;
		return null;

	}

	@Override
	public User selectUserById(int id) {//根据id查找用户
		//这里的?设置参数
		String sql = "select * from tb_user where id=?";
		//这里后面添加的id参数,用来填入上面的 "?" 中
		List<User> users = template.query(sql, new BeanPropertyRowMapper<User>(User.class), id);
		if (users.size() > 0 && users.get(0) != null)
			return users.get(0);
		return null;
	}

	@Override
	public List<User> selectUserByAge(int age) {//根据年龄查找用户
		//这里的?设置参数
		String sql = "select * from tb_user where age=?";
		//这里后面添加的age参数,用来填入上面的 "?" 中
		List<User> users = template.query(sql, new BeanPropertyRowMapper<User>(User.class), age);
		if (users.size() > 0)
			return users;
		return null;
	}

	@Override
	public boolean insertUser(User user) { //添加用户
		String sql = "insert into tb_user values(null,?,?)";
		//count用来接收上面这句sql语句更新表中数据所影响的行数
		int count = template.update(sql, user.getUsername(), user.getAge());
		return count > 0;
	}

	@Override
	public boolean deleteUserById(int id) { //删除用户
		String sql = "delete from tb_user where id=?";
		int count = template.update(sql, id);
		return count > 0;
	}

	@Override
	public boolean updateUserById(User user) { //修改用户信息
		String sql = "update tb_user set username=?,age=? where id=?";
		int count = template.update(sql, user.getUsername(), user.getAge(), user.getId());
		return count > 0;
	}
}

(10)写完持久层之后,我们写业务层:UserService和UserServiceImpl
UserService:

package com.gem.service;

import java.util.List;

import com.gem.entity.User;

public interface UserService {
	//查看所有用户
	List<User> getAllUser();

	//根据id查找用户
	User getUserById(int id);

	//根据年龄查找用户
	List<User> getUserByAge(int age);

	//添加用户
	boolean addUser(User user);

	//删除用户
	boolean deleteUserById(int id);

	//修改用户信息
	boolean updateUserById(User user);
}

UserServiceImpl:

package com.gem.service.impl;

import java.util.List;

import com.gem.dao.UserDao;
import com.gem.entity.User;
import com.gem.service.UserService;
import com.gem.util.BeanFactory;

public class UserServiceImpl implements UserService {
	UserDao userDao = (UserDao) BeanFactory.getBean("com.gem.dao.impl.UserDaoImpl");

	@Override
	public List<User> getAllUser() {
		return userDao.selectAllUser();
	}

	@Override
	public User getUserById(int id) {
		return userDao.selectUserById(id);
	}

	@Override
	public List<User> getUserByAge(int age) {
		return userDao.selectUserByAge(age);
	}

	@Override
	public boolean addUser(User user) {
		return userDao.insertUser(user);
	}

	@Override
	public boolean deleteUserById(int id) {
		return userDao.deleteUserById(id);
	}

	@Override
	public boolean updateUserById(User user) {
		return userDao.updateUserById(user);
	}

}

(11)最后我们来写一下Client。用来测试JDBCTemplate

package com.gem.client;

import java.util.Scanner;

import com.gem.entity.User;
import com.gem.service.UserService;
import com.gem.util.BeanFactory;

public class Client {
	public static void main(String[] args) {
		UserService userService = (UserService) BeanFactory.getBean("com.gem.service.impl.UserServiceImpl");
		Scanner sc = new Scanner(System.in);

		while (true)
			menu(sc, userService);
	}

	private static void menu(Scanner sc, UserService userService) {
		System.out.println("1.查看所有用户");
		System.out.println("2.根据id查找用户");
		System.out.println("3.根据年龄查找用户");
		System.out.println("4.添加用户");
		System.out.println("5.删除用户");
		System.out.println("6.修改用户信息");
		String choice = sc.nextLine().trim();
		switch (choice) {
		case "1":
			searchAllUser(sc, userService);
			break;
		case "2":
			searchUserById(sc, userService);
			break;
		case "3":
			searchUserByAge(sc, userService);
			break;
		case "4":
			addUser(sc, userService);
			break;
		case "5":
			deleteUserById(sc, userService);
			break;
		case "6":
			updateUserById(sc, userService);
			break;

		default:
			break;
		}
	}

	private static void updateUserById(Scanner sc, UserService userService) {
		System.out.println("请输入要修改的用户的id");
		int id = Integer.parseInt(sc.nextLine().trim());
		System.out.println("请输入新姓名");
		String newUsername = sc.nextLine().trim();
		System.out.println("请输入新年龄");
		int newAge = Integer.parseInt(sc.nextLine().trim());
		if (userService.updateUserById(new User(id, newUsername, newAge)))
			System.out.println("修改成功");
		else
			System.out.println("修改失败");
	}

	private static void deleteUserById(Scanner sc, UserService userService) {
		System.out.println("请输入要删除的id");
		int id = Integer.parseInt(sc.nextLine().trim());
		if (userService.deleteUserById(id))
			System.out.println("删除成功");
		else
			System.out.println("删除失败");
	}

	private static void addUser(Scanner sc, UserService userService) {
		System.out.println("请输入姓名");
		String username = sc.nextLine().trim();
		System.out.println("请输入年龄");
		int age = Integer.parseInt(sc.nextLine().trim());
		if (userService.addUser(new User(username, age)))
			System.out.println("添加成功");
		else
			System.out.println("添加失败");
	}

	private static void searchUserByAge(Scanner sc, UserService userService) {
		System.out.println("请输入要查询的年龄");
		int age = Integer.parseInt(sc.nextLine().trim());
		userService.getUserByAge(age).forEach(System.out::println);
	}

	private static void searchUserById(Scanner sc, UserService userService) {
		System.out.println("请输入要查询的id");
		int id = Integer.parseInt(sc.nextLine().trim());
		System.out.println(userService.getUserById(id));
	}

	private static void searchAllUser(Scanner sc, UserService userService) {
		userService.getAllUser().forEach(System.out::println);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值