Springboot数据访问

@toc

SpringBoot与数据访问

JDBC

pom文件导入依赖

<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>

yml文件配置数据连接信息

spring:
  datasource:
    username: root
    password: ******
    url: jdbc:mysql://localhost:3306/willblog?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    driver-class-name: com.mysql.jdbc.Driver

连接测试:
在test文件中进行测试,测试代码如下:

public class DemoApplicationTests {
    @Autowired
  DataSource dataSource;
  @Test
  public void contextLoads() throws SQLException {
        System.out.println("--test--"+dataSource.getClass());
  Connection connection=dataSource.getConnection();
  System.out.println("--test--"+connection);
  connection.close();
  }

}

测试截图:
在这里插入图片描述
自动配置原理:
org.springframework.boot.autoconfigure.jdbc:

  1. DataSourceConfiguration,根据配置创建数据源;
  2. 数据库操作:SpringBoot自动配置了JDBCTemplate操作数据库;
@Controller 
public class HelloController {
    @Autowired
  JdbcTemplate jdbcTemplate;
  @ResponseBody
 @GetMapping("/query")
    public Map<String,Object> map(){
        List<Map<String,Object>> list= jdbcTemplate.queryForList("select * from students");
 return list.get(0);
  }

在这里插入图片描述

SpringBoot整合Druid

pom文件引入依赖:

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid</artifactId>
   <version>1.1.8</version> 
 </dependency>
 <!--还需要引入log4j依赖-->
 <dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.17</version>
 </dependency>

配置使用yml配置看起来简洁清晰;
application.yml

spring:
  datasource:
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    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,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    #通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

这是配置文件部分,但是关于druid的配置部分暂时还未起作用。所以需要我们编写配置类并将其加入容器中:
创建DruidConfig.java,内容如下:

@Configuration 
public class DruidConfig {
//将配置文件中关于druid的配置加入容器中,使其起作用;
  @ConfigurationProperties(prefix = "spring.datasource")
  @Bean
  public DataSource druid(){
        return new DruidDataSource();
  }

    //配置Druid的监控
 //1、配置一个管理后台的Servlet  
  @Bean
  public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        Map<String,String> initParams = new HashMap<>();
        initParams.put("loginUsername","admin");
        initParams.put("loginPassword","123456");
        initParams.put("allow","");//默认就是允许所有访问
        initParams.put("deny","192.168.43.19");
        bean.setInitParameters(initParams);
        return bean;
  }

    //2、配置一个web监控的filter
  @Bean
  public FilterRegistrationBean webStatFilter(){
        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;
  }
}

至此Druid就配置完成了,访问路径localhost:8080/druid
输入在该类中设置的用户名密码进行登录;

SpringBoot整合Mybatis并使用Druid数据源

首先配置Druid数据源如上;

  • 数据库建表
    SpringBoot在数据库建表方面也非常人性化,这里SpringBoot在1.5x版本和2.0X版本有点细微的差别;
    • 1.5X版本中将sql文件命名为schema-*.sql并放置在文件类路径下即可,系统在启动主程序时会自动加载该文件并在配置的数据库中创建表:
      在这里插入图片描述
      或者将其放置在其他路径,但要在yml配置文件中配置文件路径,该方法文件名字可随意:
      在这里插入图片描述
      yml配置文件添加配置:
spring:
  datasource:
  ... ...
  schema:
  - classpath:sql/schema-all.sql
  - classpath:sql/employee.sql
  • 2.0X 的SpringBoot中 则需要在上述基础上在配置文件中加一句配置:
spring:
  datasource:
  ... ...
  schema:
  - classpath:sql/schema-all.sql
  - classpath:sql/employee.sql
  initialization-mode: always

配置完成重启服务,就可以看到数据库多了两个表:
在这里插入图片描述

使用注解版的mybatis操作数据库

  • 首先建一个操作数据库的Mapper接口对应的Bean
    以department为例:
/**
 * @author :will
 * @date :2019/8/10 21:35
 * @description:操作数据库的mapper
  */ 
    @Mapper 
public interface DepartmentMapper {
    @Select("select * from department where id=#{id}")
    public Department getDeptById(Integer id);   
    @Delete("delete from department where id=#{id}")
    public int deletDeptById(Integer id);   
    
      //插入数据时数据值直接使用Bean中的对应名称即可
    @Insert("insert into department(departmentName) values(#{departmentName})")
    public int insertDept(Department department);    
    @Update("update department set departmentName=#{departmentName} where id=#{id}")
    public int updateDept(Department department); }

该接口使用注解可对数据库进行各种操作;

  • 创建控制类:
@RestController
 public class DeptController {

    //Service层,自动注入departmentMapper
  @Autowired
  DepartmentMapper departmentMapper;    //此处id为占位符,用@PathVariable("id")可将参数取出
  @GetMapping("/dept/{id}")
    public Department getDepatement(@PathVariable("id") Integer id){
        return departmentMapper.getDeptById(id);
  }
    @GetMapping("/dept")
    public Department insertDept(Department department){
        departmentMapper.insertDept(department);
        return department;
  }
}

接下来直接在浏览器发送请求进行操作数据库:

根据ID查找数据库片描述

添加数据库操作:
添加数据

因为此处添加时直接返回的是代码当中的department对象而不是从数据库中取出的,所以没有id。若想要插入一条数据并可以直接获取到该数据的自增id时,需要在DepartmentMapper 中的insertDept方法上添加上@Options注解,具体如下:

//keyProperty时指定表中主键id,要与表中字段一致
  @Options(useGeneratedKeys = true,keyProperty = "id")
 //插入数据时数据值直接使用Bean中的对应名称即可
  @Insert("insert into department(departmentName) values(#{departmentName})")
 public int insertDept(Department department);

测试如下:
在这里插入图片描述
有时候会出现sql语句明明能查到数据,但在代码中就是获取不到值,这是因为数据库中表的字段名和我们代码中的属性名不一致,也是就是说:在mysql中会自行将我们代码属性中非首字母的大写字母(如:userName)转化成小写字母并加上下划线(转换后:user_name),也就是驼峰命名法;mybatis默认是不解析驼峰命名的;我们需要在yml配置文件或properties文件中加上一句配置,来开启驼峰命名:

mybatis.configuration.mapUnderscoreToCamelCase=true

自定义mybatis的配置规则

数据库使用驼峰命名法department_name,而配置类中用的是departmentName;则默认获取不到数据;需要给容器中添加一个ConfigurationCustomizer;:

@org.springframework.context.annotation.Configuration 
public class MyBatisConfig {
    @Bean
  public ConfigurationCustomizer configurationCustomizer(){
        return new ConfigurationCustomizer() {
            @Override
             public void customize(Configuration configuration) {
                configuration.setMapUnderscoreToCamelCase(true);
            }
        };
  }
}

在这里插入图片描述

在这里插入图片描述

在当我们的Mapper接口非常多的时候,需要在每个类上添加@Mapper注解,这样会有点麻烦;我们可以在主启动类上添加一个扫描Mapper类的注解:

@MapperScan(value = "com.mybatis.mybatis.mapper")
@SpringBootApplication 
public class MybatisApplication {

    public static void main(String[] args) {
        SpringApplication.run(MybatisApplication.class, args);
  }

}

这样程序在启动的时候会自动将路径com.mybatis.mybatis.mapper下的所有文件扫描并为Mapper接口。而不用每个类都加@Mapper注解

配置文件版Mybatis

配置版主要是在配置文件中指定Mybatis的配置文件路径

mybatis:
  config-location: classpath:mybatis/mybatis-config.xml 指定全局配置文件的位置
  mapper-locations: classpath:mybatis/mapper/*.xml  指定sql映射文件的位置

更多学习可参照
http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/

SpringBoot整合JPA操作数据库

JPA是基于ORM(Object Relational Mapping)思想的;

  1. 编写一个实体类(bean)和数据表进行映射,并配置好映射关系;
/**
 * @author :will
 * @date :2019/8/11 20:58
 * @description:使用JPA注解配置映射关系
  */
  @Entity //告诉JPA这是一个实体类 
  @Table(name = "users") //用@Table来指定和哪个表对应; 如果省略,则默认表明就是类名users 
  @JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" })
public class users {
    @Id//标注这是一个主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)//自增主键
    private int uid;
    @Column(name = "username",length = 20)//这是和数据表对应的列名
    private String username;
    @Column(name = "password")//如果省略则默认列名就是属性名
    private String password;
    @Column
    private String gender;
    @Column
    private String role;
    //get和set方法省略
  }
  1. 编写一个Dao接口,来操作对应的数据表(Repository)基本的操作方法已经在JpaRepository类中写好,直接调用就行
//继承JPARepository来完成对数据库的操作 
public interface UserRepository extends JpaRepository<users,Integer> {
}
  1. 基本配置JpaRepository
spring:
  jpa:
    hibernate:
#      更新或者创建数据表结构,在每次启动项目的时候会自动进行检查更新或创建
      ddl-auto: update 
#   控制台显示SQL
    show-sql: true
  1. 编写控制类,在控制类中直接注入自己编写的UserRepository接口,而后直接调用该接口中的方法进行操作数据库:
@RestController
public class UserController {

    @Autowired
    UserRepository userRepository;    @GetMapping("/jpa/{id}")
    public users getUser(@PathVariable("id") Integer id){
        users us=userRepository.getOne(id);
       return us;
  }

    @GetMapping("/jpa")
    public users insertUsers(users us){
        users save= userRepository.save(us);
        return save;
  }
}

JPA中对象一对一、一对多操作

一对多操作

  • 在一对多操作中一的一方需要添加一个Set类型的属性,存放多的一方,并且数据库中表不需要更改,因为前边配置了ddl-auto: update ,这会让数据库自行根据需要添加列:
public class users {
    @Id//标注这是一个主键
  @GeneratedValue(strategy = GenerationType.IDENTITY)//自增主键
  private int uid;
  @Column(name = "username",length = 20)//这是和数据表对应的列名
  private String username;
  @Column(name = "password")//如果省略则默认列名就是属性名
  private String password;
  @Column
  private String gender;
  @Column
  private String role;
 
  
    @OneToMany(targetEntity = Employee.class,cascade = {CascadeType.PERSIST}) //cascade级联新增
    @JoinColumn(name = "use_emp_id",referencedColumnName = "uid")
    private Set<Employee> employees=new HashSet<Employee>(0);
    //TODO Get()
    //TODO Set()
    //TODO ToString()
}
  • 在多的一方不需要添加任何信息;
public class Employee {
    @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
  @Column(name = "lastName",length = 20)
    private String lastName;
  @Column(name = "email")
    private String email;
  @Column(name = "gender")
    private int gender;
  @Column(name = "d_id")
    private int d_id;
    //TODO Get();
    //TODO Set();
    //TODO ToString()
}

这里两个类都省略了get和set以及ToString方法,请自行添加;

  • 测试代码:
    测试使用项目Junit测试:
@RunWith(SpringRunner.class)
@SpringBootTest 
public class SpringdatajpaApplicationTests {
/*OneToMany测试*/
    @Autowired
  UserRepository userRepository;
  //这两个接口生成方法一致,都是只继承JpaRepository即可,无需任何多于代码;唯一区别就是一个修改一下类即可,如下
  //JpaRepository<users,Integer>
  //JpaRepository<Employee,Integer>
  @Autowired
  EmployeeRepository employeeRepository;
  @Test
 @Transactional @Rollback(false)
    public void contextLoads() {
        users us=new users();
        us.setUsername("OneToMany");
        us.setPassword("123456");
        Employee employee=new Employee();
        employee.setLastName("many");
        employee.setGender(2);
        Employee employee1=new Employee();
        employee1.setLastName("many1");
        employee1.setGender(1);
        HashSet<Employee> emplist=new HashSet<Employee>();
        emplist.add(employee);
        emplist.add(employee1);
        us.setEmployees(emplist);
        userRepository.save(us);
        users us1=userRepository.getOne(12);
        System.out.println(us1);
  }
}

一对一的只是把Set 换成Employee类型,@OneToMany换成@OneToOne;自行参悟去吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值