SpringBoot 与数据访问 一、JDBC
1 2 3 4 5 6 7 8 9 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jdbc</artifactId > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <scope > runtime</scope > </dependency >
1 2 3 4 5 6 7 8 9 spring : datasource : username : root password : 1234 url : jdbc:mysql://192.168.64.129:3307/jdbc?characterEncoding=UTF-8&serverTimezone=UTC driver-class-name : com.mysql.cj.jdbc.Driver
效果 :
1. 默认使用 com.zaxxer.hikari.HikariDataSource 作为数据源(springBoot 的版本为:2.3.3 );
1 2 3 4 5 6 7 8 9 @Configuration @Conditional(PooledDataSourceCondition.class) @ConditionalOnMissingBean({ DataSource.class, XADataSource.class }) @Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class, DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class }) protected static class PooledDataSourceConfiguration { }
springboot 1.5.10 版本 默认是使用 org.apache.tomcat.jdbc.pool.DataSource 作为数据源;
配置源的相关配置都在 DataSourceProperties 里面;
自动配置原理:
org.springframework.boot.autoconfigure.jdbc ;
参考 DataSurceConfiguration,根据配置创建数据源,默认使用 Tomcat 连接池;可以使用 spring.datasource.type 指定自定义的数据源类型‘ 2)SpringBoot 默认可以支持:
1 org.apache.tomcat.jdbc.pool.DataSource、HikariDataSource、BasicDataSource
自定义数据源类型 1 2 3 4 5 6 7 8 9 10 11 12 @ConditionalOnMissingBean(DataSource.class) @ConditionalOnProperty(name = "spring.datasource.type") static class Generic { @Bean public DataSource dataSource (DataSourceProperties properties) { return properties.initializeDataSourceBuilder().build(); } }
4) DataSourceInitialzer : ApplicationListener :
作用 :
① runSchemaScripts(); 运行建表语句;
② runDataScripts():运行插入的 sql 语句;
默认只需要将文件命名为:
1 2 3 4 5 6 schema-*.sql、data-*.sql 默认规则: schema.sql , schema-all.sql 可是使用 schema: - classpath:department.sql 指定位置
==注意:SpringBoot 2.x 及以需要配置==
具体的参考我这篇博客详细介绍了
1 2 spring.datasource.initialization-mode =always
否则不会自动创建 sql 语句
5)操作数据库:自动配置 jdbcTemplate 操作数据库
二、整合 Driuid 数据源 pom.xml 导入依赖
1 2 3 4 5 <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.1.21</version > </dependency >
① 添加基本配置 不使用默认的配置,使用自己的配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 initialSize : 5 minIdle : 5 maxActive : 20 maxWait : 60000 timeBetweenEvictionRunsMillis : 60000 minEvictableIdleTimeMillis : 300000 validationQuery : SELECT 1 FROM DUAL testWhileIdle : true testOnBorrow : false testOnReturn : false poolPreparedStatements : true filters : stat,wall,log4j maxPoolPreparedStatementPerConnectionSize : 20 useGlobalDataSourceStat : true connectionProperties : druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
【DruidConfig.java】
1 2 3 4 5 6 7 8 9 @Configuration public class DruidConfig { @ConfigurationProperties(prefix = "spring.datasource") @Bean public DataSource druid () { return new DruidDataSource (); } }
使用在测试类中启动 DegBug 启动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @SpringBootTest class SpringBoot06DateJdbcApplicationTests { @Autowired DataSource dataSource; @Test void contextLoads () throws SQLException { System.out.println(dataSource.getClass()); System.out.println("*********************" ); Connection conn = dataSource.getConnection(); System.out.println(conn); conn.close(); } }
启动 :
Debug 启动出现异常,原因分析:应该在运行中缺少 log4j 的依赖,导致无法启动。
解决方法 :
1 2 3 4 5 6 // 在pom.xml 文件中导入log4j的依赖 <dependency > <groupId > log4j</groupId > <artifactId > log4j</artifactId > <version > 1.2.17</version > </dependency >
启动配置生效
② 整合 Druid 数据源 【DruidConfig.java】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 @Bean public ServletRegistrationBean staViewServlet () { ServletRegistrationBean bean = new ServletRegistrationBean (new StatViewServlet (), "/druid/*" ); Map<String, String> initParams = new HashMap <>(); initParams.put("loginUsername" ,"admin" ); initParams.put("loginPassword" ,"12345" ); initParams.put("allow" ,"" ); initParams.put("deny" ,"192.168.64.129" ); bean.setInitParameters(initParams); return bean; } @Bean public FilterRegistrationBean webStratFilert () { FilterRegistrationBean bean = new FilterRegistrationBean (); bean.setFilter(new WebStatFilter ()); Map<String, String> initParams = new HashMap <>(); initParams.put("exclusions" ,"*.js, *.css, /druid/*" ); bean.setInitParameters(initParams); bean.setUrlPatterns(Arrays.asList("/*" )); return bean; }
【HelloController.java】
1 2 3 4 5 6 7 8 9 10 11 12 13 @Controller public class HelloController { @Autowired JdbcTemplate jdbcTemplate; @ResponseBody @GetMapping(value = "/query") public Map<String, Object> map () { List<Map<String, Object>> list = jdbcTemplate.queryForList("select * FROM department" ); return list.get(0 ); } }
测试 :
三、 整合 Mybatis 1 2 3 4 5 <dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > <version > 2.1.3</version > </dependency >
准备步骤 :
配置数据源相关属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 spring: datasource: username: root password: 6090 driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.64.129:3307/mybatis type: com.alibaba.druid.pool.DruidDataSource initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true filters: stat,wall,log4j maxPoolPreparedStatementPerConnectionSize: 20 useGlobalDataSourceStat: true connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500 initialization-mode: always
给数据库建表
在 yml 配置文件中添加
1 2 3 schema : - classpath:sql/department.sql - classpath:sql/employee.sql
创建 javabean 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class Employee { private Integer id; private String lastName; private Integer gender; private String email; private Integer dId; } public class Department { private Integer id; private String departmenName; }
① 注解版 【DepartmentMapper.java】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Mapper public interface DepartmentMapper { @Select("select * from department where id = #{id}") @Delete("delete from department where id=#{id}") public int deleteDeptById (Integer id) ; @Insert("insert department(department_name) values(#{departmentName})") public int insertDept (Department department) ; @Update("update departments set department_name=#{departmentName} where id=#{id}") public int updateDept (Department department) ; }
【DeptController.java】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @RestController public class DeptController { @Autowired DepartmentMapper departmentMapper; @GetMapping(value = "/dept/{id}") public Department getdepartment (@PathVariable("id") Integer id) { return departmentMapper.getDeptById(id); } @GetMapping(value = "/dept") public Department insertDept (Department department) { departmentMapper.insertDept(department); return department; } }
测试:
出现异常,获取值不完整,原因分析 departmentName 这个属性名跟数据库的字段不一致,可以自定义增加驼峰命名 来解决这个问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Configuration public class MybatisConfig { @Bean public ConfigurationCustomizer configurationCustomizer () { return new ConfigurationCustomizer () { @Override public void customize (org.apache.ibatis.session.Configuration configuration) { configuration.setMapUnderscoreToCamelCase(true ); } }; } }
补充 :使用 MapperScan 批量扫描所有的 Mapper 接口
1 2 3 4 5 6 7 8 @MapperScan(value = "com.oy.springboot06.Mapper") @SpringBootApplication public class SpringBoot06DataMybatisApplication { public static void main (String[] args) { SpringApplication.run(SpringBoot06DataMybatisApplication.class, args); } }
② 配置文件版 1 2 3 mybatis : config-location : classpath:mybatis/mybatis-config.xml 指定全局配置文件的位置 mapper-locations : classpath:mybatis/mapper/*.xml 指定sql映射文件位置
【EmployeeMapper.class】
1 2 3 4 5 6 7 @Mapper public interface EmployeeMapper { public Employee getEmpById (Integer id) ; public void insertEmp (Employee employee) ; }
【DeptController.java】
1 2 3 4 5 6 7 8 9 10 11 12 @RestController public class DeptController { @Autowired EmployeeMapper employeeMapper; @GetMapping("/emp/{id}") public Employee getEmp (@PathVariable("id") Integer id) { return employeeMapper.getEmpById(id); } }
【mybatis-config.xml】配置驼峰命名规则
1 2 3 4 5 <configuration > <settings > <setting name ="mapUnderscoreToCamelCase" value ="true" /> </settings > </configuration >
测试 :
更多使用参照:http://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/
四、整合 SpringData JPA ① SpringData 简介
② 整合 SpringData JPA JPA : ORM(Object Relational Mapping)
编写一个实体类(bean)和数据表进行映射,并且配置好映射关系; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Entity @Table(name = "tbl_user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "last_name", length = 50) private String lastName; @Column private String email; }
编写一个 Dao 接口来操作实体类对应的数据表(Repository) 1 2 3 4 5 6 7 8 public interface UserRepository extends JpaRepository <User, Integer> {}
基本配置 JpaProperties(yml 中) 1 2 3 4 5 6 7 8 9 10 11 12 13 spring: datasource: username: root password: 123456 url: jdbc:mysql://192.168.64.129:3307/jpa driver-class-name: com.mysql.cj.jdbc.Driver initialization-mode: always jpa: hibernate: ddl-auto: update show-sql: true
4.测试
【UserController.java】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 @RestController public class UserController { @Autowired UserRepository userRepository; @GetMapping("/user/{id}") public User getUser (@PathVariable("id") Integer id) { User user = new User (); user.setId(id); Example<User> example = Example.of(user); Optional<User> one = userRepository.findOne(example); return one.get(); } @GetMapping("/user") public User insertUser (User user) { User save = userRepository.save(user); return save; } @GetMapping("/user/all") public List<User> getAll () { List<User> all = userRepository.findAll(); return all; } }