Spring 对数据库的操作在 jdbc 上面做了深层次的封装,使用 Spring 的注入功能,把 DataSource 注册到 JdbcTemplate 中。

基本使用

在 pom.xml 中引入相关依赖

  • 数据库驱动
  • 数据库连接池
  • spring-jdbc
  • spring-tx:事务和异常控制 ```xml mysql mysql-connector-java 8.0.22
com.alibaba druid 1.2.3 org.springframework spring-jdbc 5.2.9.RELEASE

junit junit 4.13.1 test

  1. <a name="5E9Ps"></a>
  2. #### 数据库配置文件
  3. 在 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

  1. <a name="trjNE"></a>
  2. #### spring 配置类
  3. 创建 Spring 配置类:
  4. ```java
  5. @Configuration
  6. @PropertySource(value = {"classpath:db.properties"}) //指定配置文件位置
  7. @EnableTransactionManagement //开启事务配置
  8. public class DemoConfig {
  9. @Value("${jdbc.username}")
  10. private String username;
  11. @Value("${jdbc.password}")
  12. private String password;
  13. @Value("${jdbc.url}")
  14. private String url;
  15. @Value("${jdbc.driverClassName}")
  16. private String driverClassName;
  17. // 配置一个Druid连接池
  18. @Bean
  19. public DataSource dataSource() {
  20. DruidDataSource dataSource = new DruidDataSource();
  21. dataSource.setUsername(username);
  22. dataSource.setPassword(password);
  23. dataSource.setUrl(url);
  24. dataSource.setDriverClassName(driverClassName);
  25. return dataSource;
  26. }
  27. // 配置一个JdbcTemplate实例,注入dataSource数据源
  28. @Bean
  29. public JdbcTemplate jdbcTemplate(@Autowired DataSource dataSource) {
  30. JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
  31. return jdbcTemplate;
  32. }
  33. }

测试 jdbcTemplate

JdbcTemplate 提供的方法:

  • execute():用于执行任何 SQL 语句,一般用来执行 DDL 语句
  • update()/batchUpdate():update 方法用于执行新增、修改、删除等语句;batchUpdate 方法用于执行批处理相关语句
  • query()/queryForXXX():用于执行查询相关语句
  • call():用于执行存储过程、函数相关语句

    1. public class DemoTest {
    2. private JdbcTemplate jdbcTemplate;
    3. @Before
    4. public void before() {
    5. ApplicationContext context =
    6. new AnnotationConfigApplicationContext(DemoConfig.class);
    7. jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate");
    8. }
    9. @Test
    10. public void testInsert() {
    11. // 插入数据
    12. String sql = "insert into t_user (name, age) values (?, ?)";
    13. int update = jdbcTemplate.update(sql, "李四", 18);
    14. System.out.println(update);
    15. }
    16. @Test
    17. public void testUpdate() {
    18. // 更新数据
    19. String sql = "update t_user set name=?,age=? where id=?";
    20. int update = jdbcTemplate.update(sql, new Object[]{"万斯", 19, 1});
    21. System.out.println(update);
    22. }
    23. @Test
    24. public void testDelete() {
    25. // 删除数据
    26. String sql = "delete from t_user where id=?";
    27. int update = jdbcTemplate.update(sql, 2);
    28. System.out.println(update);
    29. }
    30. @Test
    31. public void testBatchUpdate() {
    32. // 批量插入
    33. String sql = "insert into t_user (name, age) values (?, ?)";
    34. List<Object[]> batchArgs = new ArrayList<Object[]>() {
    35. {
    36. add(new Object[]{"世界", 53});
    37. add(new Object[]{"Bob", 83});
    38. add(new Object[]{"风华", 48});
    39. }
    40. };
    41. // batchUpdate的第二个参数为Object[]类型
    42. int[] update = jdbcTemplate.batchUpdate(sql, batchArgs);
    43. System.out.println(Arrays.toString(update));
    44. }
    45. @Test
    46. public void testSingleSelect() {
    47. // 查询数据,读取单个对象
    48. String sql = "select id,name,age from t_user where id=?";
    49. // BeanPropertyRowMapper要求数据库查询出来的列和实体属性一一对应,如果列名和属性不一致,则需要设置查询别名
    50. RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class);
    51. // 使用JdbcTemplate对象不能获取关联对象
    52. User user = jdbcTemplate.queryForObject(sql, rowMapper, 3);
    53. System.out.println(user);
    54. }
    55. @Test
    56. public void testMultiSelect() {
    57. String sql = "select id,name,age from t_user";
    58. RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class);
    59. // 查询多个对象
    60. List<User> query = jdbcTemplate.query(sql, rowMapper);
    61. // 避免空指针
    62. Optional.of(query)
    63. .map(Collection::stream)
    64. .orElse(Stream.empty())
    65. .forEach(System.out::println);
    66. }
    67. @Test
    68. public void testOtherSelect() {
    69. // 获取某个记录或者count、avg等函数返回的唯一值
    70. String sql = "select count(*) from t_user";
    71. Integer integer = jdbcTemplate.queryForObject(sql, Integer.class);
    72. System.out.println(integer);
    73. }
    74. }

实际使用

1、构建 UserDao 层:

  1. // UserDao
  2. public interface UserDao {
  3. // 插入数据
  4. int insert(User user);
  5. // 根据id查询数据
  6. User selectById(int id);
  7. // 查询数据
  8. List<User> select();
  9. // 更新数据
  10. int update(User user);
  11. // 删除数据
  12. int delete(int id);
  13. }
  14. // UserDaoImpl实现类
  15. @Repository
  16. public class UserDaoImpl implements UserDao {
  17. @Autowired
  18. private JdbcTemplate jdbcTemplate;
  19. private Integer selectLastInsertID() {
  20. // 获取最后一个由Auto_Increment插入的值
  21. String sql = "select LAST_INSERT_ID()";
  22. return jdbcTemplate.queryForObject(sql, Integer.class);
  23. }
  24. @Override
  25. public int insert(User user) {
  26. // 插入数据
  27. String sql = "insert into t_user (name, age) values (?, ?)";
  28. int update = jdbcTemplate.update(sql, user.getName(), user.getAge());
  29. // 获取刚刚插入数据的id
  30. Integer id = selectLastInsertID();
  31. // id回写到user
  32. user.setId(id);
  33. return update;
  34. }
  35. @Override
  36. public User selectById(int id) {
  37. // 构建查询语句
  38. String sql = "select id,name,age from t_user where id=?";
  39. // 构建对象映射
  40. RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class);
  41. // 进行查询
  42. return jdbcTemplate.queryForObject(sql, rowMapper, id);
  43. }
  44. @Override
  45. public List<User> select() {
  46. // 构建查询语句
  47. String sql = "select id,name,age from t_user limit ?,?";
  48. // 构建对象映射
  49. RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class);
  50. // 这里可以作分页处理,这里就不再测试,直接固定数据
  51. List<User> query = jdbcTemplate.query(sql, rowMapper, 2, 2);
  52. return query;
  53. }
  54. @Override
  55. public int update(User user) {
  56. // 构建sql语句
  57. String sql = "update t_user set name=?,age=? where id=?";
  58. int update = jdbcTemplate.update(sql, user.getName(), user.getAge(), user.getId());
  59. return update;
  60. }
  61. @Override
  62. public int delete(int id) {
  63. String sql = "delete from t_user where id=?";
  64. int delete = jdbcTemplate.update(sql, id);
  65. return delete;
  66. }
  67. }

2、构建 UserService 层:

在Spring中,如果需要进行事务管理,需要有如下几点:

  • 在配置类上使用 @EnableTransactionManagement 开启事务配置
  • 配置一个事务管理器:TransactionManager
  • 在需要使用事务的 service 方法上使用 @Transaction 注解

image.png
在配置类中配置 jdbc 的事务管理器:

  1. // 在配置类中配置jdbc的事务管理器
  2. @Bean
  3. public PlatformTransactionManager transactionManager() {
  4. return new DataSourceTransactionManager(dataSource());
  5. }

创建 UserService:

  1. public interface UserService {
  2. Integer insert(User user);
  3. User selectById(int id);
  4. List<User> select();
  5. int update(User user);
  6. int delete(int id);
  7. }

创建 UserServiceImpl:

  1. @Service
  2. public class UserServiceImpl implements UserService {
  3. @Autowired
  4. private UserDao userDao;
  5. @Override
  6. @Transactional(propagation = Propagation.MANDATORY)
  7. public Integer insert(User user) {
  8. return userDao.insert(user);
  9. }
  10. @Override
  11. public User selectById(int id) {
  12. return userDao.selectById(id);
  13. }
  14. @Override
  15. public List<User> select() {
  16. return userDao.select();
  17. }
  18. @Override
  19. @Transactional
  20. public int update(User user) {
  21. return userDao.update(user);
  22. }
  23. @Override
  24. @Transactional
  25. public int delete(int id) {
  26. return userDao.delete(id);
  27. }
  28. }

3、测试:

  1. public class UserServiceTest {
  2. private UserService userService;
  3. @Before
  4. public void before() {
  5. ApplicationContext context =
  6. new AnnotationConfigApplicationContext(DemoConfig.class);
  7. userService = context.getBean(UserService.class);
  8. }
  9. @Test
  10. public void testInsert() {
  11. User user = new User().setName("shen").setAge(44);
  12. Integer insert = userService.insert(user);
  13. System.out.println(insert);
  14. System.out.println(user);
  15. }
  16. @Test
  17. public void testDelete() {
  18. int delete = userService.delete(8);
  19. System.out.println(delete);
  20. }
  21. @Test
  22. public void testSelect() {
  23. List<User> select = userService.select();
  24. Optional.of(select)
  25. .map(Collection::stream)
  26. .orElse(Stream.empty())
  27. .forEach(System.out::println);
  28. }
  29. @Test
  30. public void testUpdate() {
  31. int i = userService.update(new User().setId(1).setName("狮虎").setAge(28));
  32. System.out.println(i);
  33. }
  34. }