Spring 对数据库的操作在 jdbc 上面做了深层次的封装,使用 Spring 的注入功能,把 DataSource 注册到 JdbcTemplate 中。
基本使用
在 pom.xml 中引入相关依赖
- 数据库驱动
- 数据库连接池
- spring-jdbc
- spring-tx:事务和异常控制
```xml
mysql mysql-connector-java 8.0.22
<a name="5E9Ps"></a>#### 数据库配置文件在 src/main/resources 下创建数据库连接配置文件:db.properties
jdbc.username=root jdbc.password=1911472163Pzs_ jdbc.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=true jdbc.driverClassName=com.mysql.cj.jdbc.Driver
<a name="trjNE"></a>#### spring 配置类创建 Spring 配置类:```java@Configuration@PropertySource(value = {"classpath:db.properties"}) //指定配置文件位置@EnableTransactionManagement //开启事务配置public class DemoConfig {@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;@Value("${jdbc.url}")private String url;@Value("${jdbc.driverClassName}")private String driverClassName;// 配置一个Druid连接池@Beanpublic DataSource dataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setUsername(username);dataSource.setPassword(password);dataSource.setUrl(url);dataSource.setDriverClassName(driverClassName);return dataSource;}// 配置一个JdbcTemplate实例,注入dataSource数据源@Beanpublic JdbcTemplate jdbcTemplate(@Autowired DataSource dataSource) {JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);return jdbcTemplate;}}
测试 jdbcTemplate
JdbcTemplate 提供的方法:
- execute():用于执行任何 SQL 语句,一般用来执行 DDL 语句
- update()/batchUpdate():update 方法用于执行新增、修改、删除等语句;batchUpdate 方法用于执行批处理相关语句
- query()/queryForXXX():用于执行查询相关语句
call():用于执行存储过程、函数相关语句
public class DemoTest {private JdbcTemplate jdbcTemplate;@Beforepublic void before() {ApplicationContext context =new AnnotationConfigApplicationContext(DemoConfig.class);jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate");}@Testpublic void testInsert() {// 插入数据String sql = "insert into t_user (name, age) values (?, ?)";int update = jdbcTemplate.update(sql, "李四", 18);System.out.println(update);}@Testpublic void testUpdate() {// 更新数据String sql = "update t_user set name=?,age=? where id=?";int update = jdbcTemplate.update(sql, new Object[]{"万斯", 19, 1});System.out.println(update);}@Testpublic void testDelete() {// 删除数据String sql = "delete from t_user where id=?";int update = jdbcTemplate.update(sql, 2);System.out.println(update);}@Testpublic void testBatchUpdate() {// 批量插入String sql = "insert into t_user (name, age) values (?, ?)";List<Object[]> batchArgs = new ArrayList<Object[]>() {{add(new Object[]{"世界", 53});add(new Object[]{"Bob", 83});add(new Object[]{"风华", 48});}};// batchUpdate的第二个参数为Object[]类型int[] update = jdbcTemplate.batchUpdate(sql, batchArgs);System.out.println(Arrays.toString(update));}@Testpublic void testSingleSelect() {// 查询数据,读取单个对象String sql = "select id,name,age from t_user where id=?";// BeanPropertyRowMapper要求数据库查询出来的列和实体属性一一对应,如果列名和属性不一致,则需要设置查询别名RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class);// 使用JdbcTemplate对象不能获取关联对象User user = jdbcTemplate.queryForObject(sql, rowMapper, 3);System.out.println(user);}@Testpublic void testMultiSelect() {String sql = "select id,name,age from t_user";RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class);// 查询多个对象List<User> query = jdbcTemplate.query(sql, rowMapper);// 避免空指针Optional.of(query).map(Collection::stream).orElse(Stream.empty()).forEach(System.out::println);}@Testpublic void testOtherSelect() {// 获取某个记录或者count、avg等函数返回的唯一值String sql = "select count(*) from t_user";Integer integer = jdbcTemplate.queryForObject(sql, Integer.class);System.out.println(integer);}}
实际使用
1、构建 UserDao 层:
// UserDaopublic interface UserDao {// 插入数据int insert(User user);// 根据id查询数据User selectById(int id);// 查询数据List<User> select();// 更新数据int update(User user);// 删除数据int delete(int id);}// UserDaoImpl实现类@Repositorypublic class UserDaoImpl implements UserDao {@Autowiredprivate JdbcTemplate jdbcTemplate;private Integer selectLastInsertID() {// 获取最后一个由Auto_Increment插入的值String sql = "select LAST_INSERT_ID()";return jdbcTemplate.queryForObject(sql, Integer.class);}@Overridepublic int insert(User user) {// 插入数据String sql = "insert into t_user (name, age) values (?, ?)";int update = jdbcTemplate.update(sql, user.getName(), user.getAge());// 获取刚刚插入数据的idInteger id = selectLastInsertID();// id回写到useruser.setId(id);return update;}@Overridepublic User selectById(int id) {// 构建查询语句String sql = "select id,name,age from t_user where id=?";// 构建对象映射RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class);// 进行查询return jdbcTemplate.queryForObject(sql, rowMapper, id);}@Overridepublic List<User> select() {// 构建查询语句String sql = "select id,name,age from t_user limit ?,?";// 构建对象映射RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class);// 这里可以作分页处理,这里就不再测试,直接固定数据List<User> query = jdbcTemplate.query(sql, rowMapper, 2, 2);return query;}@Overridepublic int update(User user) {// 构建sql语句String sql = "update t_user set name=?,age=? where id=?";int update = jdbcTemplate.update(sql, user.getName(), user.getAge(), user.getId());return update;}@Overridepublic int delete(int id) {String sql = "delete from t_user where id=?";int delete = jdbcTemplate.update(sql, id);return delete;}}
2、构建 UserService 层:
在Spring中,如果需要进行事务管理,需要有如下几点:
- 在配置类上使用 @EnableTransactionManagement 开启事务配置
- 配置一个事务管理器:TransactionManager
- 在需要使用事务的 service 方法上使用 @Transaction 注解

在配置类中配置 jdbc 的事务管理器:
// 在配置类中配置jdbc的事务管理器@Beanpublic PlatformTransactionManager transactionManager() {return new DataSourceTransactionManager(dataSource());}
创建 UserService:
public interface UserService {Integer insert(User user);User selectById(int id);List<User> select();int update(User user);int delete(int id);}
创建 UserServiceImpl:
@Servicepublic class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;@Override@Transactional(propagation = Propagation.MANDATORY)public Integer insert(User user) {return userDao.insert(user);}@Overridepublic User selectById(int id) {return userDao.selectById(id);}@Overridepublic List<User> select() {return userDao.select();}@Override@Transactionalpublic int update(User user) {return userDao.update(user);}@Override@Transactionalpublic int delete(int id) {return userDao.delete(id);}}
3、测试:
public class UserServiceTest {private UserService userService;@Beforepublic void before() {ApplicationContext context =new AnnotationConfigApplicationContext(DemoConfig.class);userService = context.getBean(UserService.class);}@Testpublic void testInsert() {User user = new User().setName("shen").setAge(44);Integer insert = userService.insert(user);System.out.println(insert);System.out.println(user);}@Testpublic void testDelete() {int delete = userService.delete(8);System.out.println(delete);}@Testpublic void testSelect() {List<User> select = userService.select();Optional.of(select).map(Collection::stream).orElse(Stream.empty()).forEach(System.out::println);}@Testpublic void testUpdate() {int i = userService.update(new User().setId(1).setName("狮虎").setAge(28));System.out.println(i);}}
