JDBCTemplate的简单应用

    技术2022-07-10  119

    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); } }
    Processed: 0.013, SQL: 9