Spring Boot 入门之持久层篇(三)

原文地址:Spring Boot 入门之持久层篇(三)
博客地址:http://www.extlight.com

一、前言

上一篇《Spring Boot 入门之 Web 篇(二)》介绍了 Spring Boot 的 Web 开发相关的内容,项目的开发离不开数据,因此本篇开始介绍持久层相关的知识。

二、整合 JdbcTemplate

2.1 添加依赖

 
  1. <!-- jdbc -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-jdbc</artifactId>
  5. </dependency>
  6.  
  7. <!-- mysql 驱动包 -->
  8. <dependency>
  9. <groupId>mysql</groupId>
  10. <artifactId>mysql-connector-java</artifactId>
  11. </dependency>

2.2 配置数据库连接

在 application.properties 中添加:

 
  1. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  2. spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
  3. spring.datasource.username=root
  4. spring.datasource.password=tiger

其中,可以不指定 driver-class-name,因为 spring boot 会自动识别 url。

2.3 测试

2.3.1 建表

在 MySQL 中创建名为 springboot 的数据库,在该库中创建 user 表:

 
  1. CREATE TABLE `user` (
  2. `id` INT(11) NOT NULL AUTO_INCREMENT,
  3. `username` VARCHAR(50) NOT NULL,
  4. `password` VARCHAR(64) NOT NULL,
  5. `birthday` DATE NOT NULL,
  6. PRIMARY KEY (`id`)
  7. )
  8. COLLATE='utf8_general_ci'
  9. ENGINE=InnoDB
  10. AUTO_INCREMENT=3
  11. ;

2.3.2 建实体类

 
  1. public class User implements Serializable{
  2.  
  3. private static final long serialVersionUID = -6249397911566315813L;
  4.  
  5. private Integer id;
  6.  
  7. private String username;
  8.  
  9. private String password;
  10.  
  11. private Date birthday;
  12.  
  13. }

setter 和 getter 方法此处省略。

2.3.3 dao 接口

接口和实现类如下:

 
  1. public interface UserDao {
  2.  
  3. public int insert(User user);
  4.  
  5. public int deleteById(Integer id);
  6.  
  7. public int update(User user);
  8.  
  9. public User getById(Integer id);
  10. }
  11.  
  12. @Repository
  13. public class UserDaoImpl implements UserDao {
  14.  
  15. @Autowired
  16. private JdbcTemplate jdbcTemplate;
  17.  
  18. @Override
  19. public int insert(User user) {
  20. String sql = "insert into user(id,username,password,birthday) values(?,?,?,?)";
  21. return this.jdbcTemplate.update(
  22. sql,
  23. user.getId(),
  24. user.getUsername(),
  25. user.getPassword(),
  26. user.getBirthday()
  27. );
  28. }
  29.  
  30. @Override
  31. public int deleteById(Integer id) {
  32. String sql = "delete from user where id = ?";
  33. return this.jdbcTemplate.update(sql,id);
  34. }
  35.  
  36. @Override
  37. public int update(User user) {
  38. String sql = "update user set password = ? where id = ?";
  39. return this.jdbcTemplate.update(
  40. sql,
  41. user.getPassword(),
  42. user.getId()
  43. );
  44. }
  45.  
  46. @Override
  47. public User getById(Integer id) {
  48. String sql = "select * from user where id = ?";
  49. return this.jdbcTemplate.queryForObject(sql, new RowMapper<User>() {
  50.  
  51. @Override
  52. public User mapRow(ResultSet rs, int rowNum) throws SQLException {
  53. User user = new User();
  54. user.setId(rs.getInt("id"));
  55. user.setUsername(rs.getString("username"));
  56. user.setPassword(rs.getString("password"));
  57. user.setBirthday(rs.getDate("birthday"));
  58. return user;
  59. }
  60.  
  61. },id);
  62. }
  63.  
  64. }

2.3.4 测试类:

 
  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest
  3. public class UserDaoTest {
  4.  
  5. @Autowired
  6. private UserDao userDao;
  7.  
  8.  
  9. @Test
  10. public void testInsert() {
  11. User user = new User();
  12. user.setId(1);
  13. user.setUsername("张三");
  14. user.setPassword("zhangsan");
  15. user.setBirthday(new Date());
  16.  
  17. int result = this.userDao.insert(user);
  18. System.out.println(result);
  19. }
  20.  
  21. @Test
  22. public void testGetById() {
  23. User user = this.userDao.getById(1);
  24. System.out.println(user.getUsername());
  25. }
  26.  
  27. @Test
  28. public void testUpdate() {
  29. User user = new User();
  30. user.setId(1);
  31. user.setPassword("zhangsan123");
  32. this.userDao.update(user);
  33. }
  34.  
  35. @Test
  36. public void testDeleteById() {
  37. int result = this.userDao.deleteById(1);
  38. System.out.println(result);
  39. }
  40. }

测试结果省略...

如需打印日志,在日志配置文件中添加如下配置

 
  1. <logger name="org.springframework.jdbc.core.JdbcTemplate" level="debug"/>

三、整合 Spring-data-jpa

3.1 添加依赖

 
  1. <!-- jdbc -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-jdbc</artifactId>
  5. </dependency>
  6.  
  7. <!-- springboot,jpa 整合包-->
  8. <dependency>
  9. <groupId>org.springframework.boot</groupId>
  10. <artifactId>spring-boot-starter-data-jpa</artifactId>
  11. </dependency>
  12.  
  13. <!-- mysql 驱动包 -->
  14. <dependency>
  15. <groupId>mysql</groupId>
  16. <artifactId>mysql-connector-java</artifactId>
  17. </dependency>

3.2 配置数据库连接

在 application.properties 中添加:

 
  1. # 数据库连接配置
  2. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  3. spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
  4. spring.datasource.username=root
  5. spring.datasource.password=tiger
  6.  
  7. # JPA 配置
  8. spring.jpa.hibernate.ddl-auto=update
  9. spring.jpa.show-sql=true

3.3 编码

3.3.1 建表

在 MySQL 中创建名为 springboot 的数据库,在该库中创建 role 表:

 
  1. CREATE TABLE `role` (
  2. `id` INT(11) NOT NULL AUTO_INCREMENT,
  3. `name` VARCHAR(10) NOT NULL,
  4. `descr` VARCHAR(100) NULL DEFAULT NULL,
  5. PRIMARY KEY (`id`)
  6. )
  7. COLLATE='utf8_general_ci'
  8. ENGINE=InnoDB
  9. ;

注意,主键 ID 为 AUTO_INCREMENT 自增。

3.3.2 建实体类

添加相应的注解

 
  1. @Entity
  2. public class Role implements Serializable{
  3.  
  4. private static final long serialVersionUID = 3926276668667517847L;
  5.  
  6. @Id
  7. @GeneratedValue
  8. private Integer id;
  9.  
  10. @Column
  11. private String name;
  12.  
  13. @Column
  14. private String descr;
  15. }

setter 和 getter 方法此处省略。

3.3.3 Repository 接口

 
  1. public interface RoleRepository extends JpaRepository<Role, Integer>{
  2.  
  3. }

3.3.4 测试类

 
  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest
  3. public class RoleRepositoryTest {
  4.  
  5. @Autowired
  6. private RoleRepository roleRepository;
  7.  
  8. @Test
  9. public void testInsert() {
  10. Role role = new Role();
  11. role.setName("管理员");
  12. role.setDescr("测试");
  13. Role result = this.roleRepository.save(role);
  14. System.out.println(result);
  15. }
  16.  
  17. @Test
  18. public void testFindOne() {
  19. Role role = this.roleRepository.findOne(1);
  20. System.out.println(role);
  21. }
  22.  
  23. @Test
  24. public void testUpdate() {
  25. Role role = new Role();
  26. role.setId(1);
  27. role.setName("管理员");
  28. role.setDescr("控制权限");
  29. Role result = this.roleRepository.save(role);
  30. System.out.println(result);
  31. }
  32.  
  33. @Test
  34. public void testDelete() {
  35. this.roleRepository.delete(1);
  36. }
  37. }

测试结果省略...

四、整合 Mybatis

整合 MyBatis 有两种方式:

1) 使用 mybatis 官方提供的 Spring Boot 整合包实现。

2) 使用 mybatis-spring 整合的方式,也就是传统的方式(推荐,此方式容易控制 MyBatis 的配置)。

4.1 配置依赖

方式一:使用官方整合包

1)添加依赖:

 
  1. <!-- springboot,mybatis 整合包 -->
  2. <dependency>
  3. <groupId>org.mybatis.spring.boot</groupId>
  4. <artifactId>mybatis-spring-boot-starter</artifactId>
  5. <version>1.3.0</version>
  6. </dependency>
  7.  
  8. <!-- mysql 驱动包 -->
  9. <dependency>
  10. <groupId>mysql</groupId>
  11. <artifactId>mysql-connector-java</artifactId>
  12. </dependency>

2)配置数据库连接:

在 application.properties 中添加:

 
  1. # 数据源配置
  2. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  3. spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
  4. spring.datasource.username=root
  5. spring.datasource.password=tiger
  6.  
  7. # mybatis 配置
  8. mybatis.config-location=classpath:mybatis/mybatis-config.xml
  9. mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

方式二:原始 Jar 包 + 手动编程

1)添加依赖:

 
  1. <!-- jdbc -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-jdbc</artifactId>
  5. </dependency>
  6.  
  7. <!-- mybatis -->
  8. <dependency>
  9. <groupId>org.mybatis</groupId>
  10. <artifactId>mybatis</artifactId>
  11. <version>3.4.4</version>
  12. </dependency>
  13.  
  14. <!-- spring,mybatis整合包 -->
  15. <dependency>
  16. <groupId>org.mybatis</groupId>
  17. <artifactId>mybatis-spring</artifactId>
  18. <version>1.3.1</version>
  19. </dependency>
  20.  
  21. <!-- mysql 驱动包 -->
  22. <dependency>
  23. <groupId>mysql</groupId>
  24. <artifactId>mysql-connector-java</artifactId>
  25. </dependency>

2)配置数据库连接:

在 application.properties 中添加:

 
  1. # 数据源配置
  2. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  3. spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
  4. spring.datasource.username=root
  5. spring.datasource.password=tiger

3)创建配置类:

 
  1. @Configuration
  2. public class MyBatisConfiguration {
  3.  
  4. @Bean
  5. @ConditionalOnMissingBean // 当容器里没有指定的 Bean 的情况下创建该对象
  6. public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
  7. SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
  8. // 设置数据源
  9. sqlSessionFactoryBean.setDataSource(dataSource);
  10.  
  11. // 设置mybatis的主配置文件
  12. sqlSessionFactoryBean.setConfigLocation(new ClassPathResource("mybatis/mybatis-config.xml"));
  13.  
  14. // 设置mapper映射文件
  15. PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
  16. Resource[] mapperXml;
  17. try {
  18. mapperXml = resolver.getResources("classpath:mybatis/mapper/*.xml");
  19. sqlSessionFactoryBean.setMapperLocations(mapperXml);
  20. } catch (IOException e) {
  21. e.printStackTrace();
  22. }
  23.  
  24. // 设置别名包
  25. sqlSessionFactoryBean.setTypeAliasesPackage("com.light.springboot.domain");
  26.  
  27. return sqlSessionFactoryBean;
  28. }
  29.  
  30. @Bean
  31. @ConditionalOnBean(SqlSessionFactoryBean.class) // 当 SqlSessionFactoryBean 实例存在时创建对象
  32. public MapperScannerConfigurer mapperScannerConfigurer() {
  33. MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
  34. mapperScannerConfigurer.setBasePackage("com.light.springboot.mapper");
  35. return mapperScannerConfigurer;
  36. }
  37. }

以上便是两种方式的配置的不同之处,不同之处就在于如何配置 mybatis 配置文件和 mapper 映射文件的路径。

在 src/main/resources 下创建 mybatis 文件夹,并在 mybatis 文件夹中创建 "mybatis-config.xml" 配置文件,内容如下:

 
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <settings>
  7. <!-- 获取数据库自增主键值 -->
  8. <setting name="useGeneratedKeys" value="true"/>
  9. <!-- 使用列别名替换列名,默认为 true -->
  10. <setting name="useColumnLabel" value="true"/>
  11. <!-- 开启驼峰命名转换:Table(create_time) => Entity(createTime) -->
  12. <setting name="mapUnderscoreToCamelCase" value="true"/>
  13. </settings>
  14. </configuration>

mybatis 文件夹下再创建一个 "mapper" 文件夹,里边存放 Mpper 接口对应的 mapper 映射文件。

4.2 测试

4.2.1 建表

在 MySQL 中创建名为 springboot 的数据库,在该库中创建 role 表:

 
  1. CREATE TABLE `department` (
  2. `id` INT(11) NOT NULL,
  3. `name` VARCHAR(10) NOT NULL,
  4. `descr` VARCHAR(50) NULL DEFAULT NULL,
  5. PRIMARY KEY (`id`)
  6. )
  7. ENGINE=InnoDB
  8. ;
  9.  

4.2.2 实体类

 
  1. public class Department implements Serializable{
  2.  
  3. private static final long serialVersionUID = 6067283535977178571L;
  4.  
  5. private Integer id;
  6.  
  7. private String name;
  8.  
  9. private String descr;
  10. }

setet 和 getter 方法省略。

4.2.3 Mapper 接口

 
  1. @Mapper
  2. public interface DepartmentMapper {
  3.  
  4. public void insert(Department department);
  5.  
  6. public Department getById(Integer id);
  7.  
  8. public void update(Department department);
  9.  
  10. public void deleteById(Integer id);
  11. }

mybatis/mapper/departmentMapper.xml :

 
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  4. <mapper namespace="com.light.springboot.dao.DepartmentMapper">
  5.  
  6. <insert id="insert" parameterType="com.light.springboot.domain.Department">
  7. insert into department(id,name,descr) values(#{id},#{name},#{descr})
  8. </insert>
  9.  
  10. <select id="getById" parameterType="java.lang.Integer" resultType="com.light.springboot.domain.Department">
  11. select id,name,descr from department where id = #{id}
  12. </select>
  13.  
  14. <update id="update" parameterType="com.light.springboot.domain.Department">
  15. update department set descr = #{descr} where id = #{id}
  16. </update>
  17.  
  18. <delete id="deleteById" parameterType="java.lang.Integer">
  19. delete from department where id = #{id}
  20. </delete>
  21. </mapper>

4.2.4 测试类

 
  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest
  3. public class DepartmentTest {
  4.  
  5. @Autowired
  6. private DepartmentMapper departmentMapper;
  7.  
  8. @Test
  9. public void testInsert() {
  10. Department department = new Department();
  11. department.setId(1);
  12. department.setName("研发部");
  13. department.setDescr("开发产品");
  14. this.departmentMapper.insert(department);
  15. }
  16.  
  17. @Test
  18. public void testGetById() {
  19. Department department = this.departmentMapper.getById(1);
  20. System.out.println(department);
  21. }
  22.  
  23. @Test
  24. public void testUpdate() {
  25. Department department = new Department();
  26. department.setId(1);
  27. department.setDescr("开发高级产品");
  28. this.departmentMapper.update(department);
  29. }
  30.  
  31. @Test
  32. public void testDeleteById() {
  33. this.departmentMapper.deleteById(1);
  34. }
  35. }

测试结果省略...

五、配置 Druid 数据源

同样地,有两种方式配置:

1)Spring boot,Druid 整合包

2)原始 jar 包 + 手动编程

5.1 Spring boot,Druid 整合包方式

5.1.1 添加依赖

 
  1. <!-- springboot,druid 整合包 -->
  2. <dependency>
  3. <groupId>com.alibaba</groupId>
  4. <artifactId>druid-spring-boot-starter</artifactId>
  5. <version>1.1.8</version>
  6. </dependency>

5.1.2 添加配置

在 application.properties 中添加:

 
  1. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  2. spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
  3. spring.datasource.username=root
  4. spring.datasource.password=tiger
  5.  
  6. # 修改数据源
  7. spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
  8. spring.datasource.druid.initial-size=5
  9. spring.datasource.druid.min-idle=5
  10. spring.datasource.druid.max-active=20
  11. spring.datasource.druid.max-wait=60000
  12. spring.datasource.druid.time-between-eviction-runs-millis=60000
  13. spring.datasource.druid.min-evictable-idle-time-millis=300000
  14. spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
  15. spring.datasource.druid.test-while-idle=true
  16. spring.datasource.druid.test-on-borrow=false
  17. spring.datasource.druid.test-on-return=false
  18. spring.datasource.druid.pool-prepared-statements=true
  19. spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
  20. spring.datasource.druid.filters=stat,wall,log4j

5.2 原始 jar 包 + 手动编程方式

5.2.1 添加依赖

 
  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>druid</artifactId>
  4. <version>1.1.8</version>
  5. </dependency>

5.2.2 添加配置

 
  1. spring.datasource.druid.driverClassName=com.mysql.jdbc.Driver
  2. spring.datasource.druid.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
  3. spring.datasource.druid.username=root
  4. spring.datasource.druid.password=tiger
  5.  
  6. spring.datasource.druid.initialSize=5
  7. spring.datasource.druid.minIdle=5
  8. spring.datasource.druid.maxActive=20
  9. spring.datasource.druid.maxWait=60000
  10. spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
  11. spring.datasource.druid.min-evictableIdleTimeMillis=300000
  12. spring.datasource.druid.validationQuery=SELECT 1 FROM DUAL
  13. spring.datasource.druid.testWhileIdle=true
  14. spring.datasource.druid.testOnBorrow=false
  15. spring.datasource.druid.testOnReturn=false
  16. spring.datasource.druid.poolPreparedStatements=true
  17. spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize=20
  18. spring.datasource.druid.filters=stat,wall

注意:配置中都是以 spring.datasource.druid 开头,使用驼峰命名

5.2.3 手动编程

 
  1. @Configuration
  2. public class DruidConfiguration {
  3.  
  4. @ConfigurationProperties(prefix = "spring.datasource.druid")
  5. @Bean(initMethod = "init",destroyMethod = "close")
  6. public DruidDataSource dataSource() {
  7. DruidDataSource ds = new DruidDataSource();
  8. ds.setProxyFilters(Arrays.asList(statFilter()));
  9. return ds;
  10. }
  11.  
  12. @Bean
  13. public Filter statFilter() {
  14. StatFilter filter = new StatFilter();
  15. filter.setSlowSqlMillis(5000);
  16. filter.setLogSlowSql(true);
  17. filter.setMergeSql(true);
  18. return filter;
  19. }
  20. }

通过上文 MyBatis 的测试代码,运行结果如下:

image

项目已经使用了 Druid 数据源了。

六、配置 Druid 监控

默认情况下,Druid 的监控统计功能和页面是开启的。

我们启动项目,访问 http://localhost:8080/druid/index.html,如下图:

image

为了保证访问的安全性,我们可以如下配置:

在 application.properties 中添加:

 
  1. ## druid 监控
  2. spring.datasource.druid.web-stat-filter.enabled=true
  3. spring.datasource.druid.web-stat-filter.url-pattern=/*
  4. spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*
  5.  
  6. ## druid 监控页面
  7. spring.datasource.druid.stat-view-servlet.enabled=true
  8. spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
  9. spring.datasource.druid.stat-view-servlet.login-username=druid
  10. spring.datasource.druid.stat-view-servlet.login-password=druid123

重启项目,再次访问 http://localhost:8080/druid/index.html 地址时需要身份验证:

image

七、源码下载

八、参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值