一.概述
在开发中,通常会涉及到对数据库的数据进行操作,Spring Boot在简化项目开发以及实现自动化配置的基础上,对关系型数据库和非关系型数据库的访问操作都提供了非常好的整合支持。接下来,我们将对Spring Boot的数据访问进行介绍,并对常用的数据操作框架进行整合讲解。
Spring Boot默认采用整合SpringData的方式统一处理数据访问层。Spring Data是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得数据库的访问变得方便快捷,除了支持传统的关系数据库同时也支持非关系数据库,以及map-reduce框架和云计算数据服务。
在Springboot 项目中我们可以通过引入不同的依赖启动器,想我们的项目中添加不同的数据库访问功能。
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
接下来我们首先学习在项目中集成Mybatis。
二.数据库准备
a.创建数据库 lerandb
CREATE DATABASE learndb;
b.创建表 t_user , t_dept
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户Id',
`name` varchar(25) DEFAULT NULL COMMENT '姓名',
`age` int DEFAULT NULL COMMENT '年龄',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `t_dept`;
CREATE TABLE `t_dept` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Id',
`name` varchar(25) DEFAULT NULL COMMENT '部门名称',
`code` int DEFAULT NULL COMMENT '部门代码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
c.插入数据
INSERT t_user VALUES (1 ,'小明',20);
INSERT t_user VALUES (2 ,'小红',18);
INSERT t_dept VALUES (1 ,'业务部',10);
INSERT t_dept VALUES (2 ,'行政部',20);
三.pom 添加 Mybatis 依赖
!-- Spring Boot Mybatis 依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot}</version>
</dependency>
四.更阿里Druid换数据连接池
SpringBoot 1.X 默认使用tomcat.jdbc链接池,SpringBoot 2.X默认使用hikari ,我们在这更换成阿里的Druid。
Druid连接池是阿里巴巴开源的数据库连接池项目。Druid连接池为监控而生,内置强大的监控功能,监控特性不影响性能。功能强大,能防SQL注入,内置Loging能诊断Hack应用行为。
Druid官方对不同数据连接池对比:
使用druid 只需引入druid的starter就可以,添加之后无需额外配置,springboot会自动识别druid
<!--阿里druid数据连接池 https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.22</version>
</dependency>
整个工程的 pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.lyu</groupId>
<artifactId>myboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>myboot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 阿里druid数据连接池 https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.22</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
五.在 application.yml 应用配置文件,增加数据库连接
# 数据库链接
spring:
datasource:
#添加mysql数据库驱动
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/learndb
username: learnuser
password: 123456
六.注解方式实现
1.添加相应的 User实体类
User.java:
package com.lyu.myboot.core.entity;
/**
* @ProjectName: [enterprise_training_6_17_2]
* @Package: [com.lyu.myboot.entity]
* @ClassName: [User]
* @Description: 用户实体类
* @Author: [EastHJ]
* @CreateDate: [2020-04-10 11:06]
* @UpdateUser: [EastHJ]
* @UpdateDate: [2020-04-10 11:06]
* @UpdateRemark: [说明本次修改内容]
* @Version: [v1.0]
*/
public class User {
private Integer id;
private String name;
private Integer age;
.... 省略getter 和setter方法 ......
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
2.编写UserMapper 接口类
UserMapper.java
package com.lyu.myboot.core.mapper;
import com.lyu.myboot.core.entity.User;
import org.apache.ibatis.annotations.*;
/**
* @ProjectName: [enterprise_training_6_17_2]
* @Package: [com.lyu.myboot.core.mapper]
* @ClassName: [UserMapper]
* @Description: 用户表访问接口
* @Author: [EastHJ]
* @CreateDate: [2020-04-10 11:14]
* @UpdateUser: [EastHJ]
* @UpdateDate: [2020-04-10 11:14]
* @UpdateRemark: [说明本次修改内容]
* @Version: [v1.0]
*/
@Mapper
public interface UserMapper {
/**
* 插入数据
*/
@Insert(" insert into t_user(id,name) values(#{id},#{name}) ")
public int inserUser(User user);
/**
* 根据用户id删除数据
*/
@Delete(" delete from t_user where id = #{id} ")
public int deleteUserById(Integer id);
/**
* 根据用户id更新数据
*/
@Update(" update t_user set name = #{name} where id=#{id} ")
public int updateUser(User user);
/**
* 根据用户id查询数据
*/
@Select(" select * from t_user where id = #{id} ")
public User selectUserById(Integer id);
/**
* 用户列表查询
*/
@Select(" select * from t_user ")
public List<User> selectUser();
}
3.编写测试类
package com.lyu.myboot.core.mapper;
import com.lyu.myboot.BaseTest;
import com.lyu.myboot.core.entity.User;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class UserMapperTest extends BaseTest {
@Autowired
private UserMapper userMapper;
private User user;
@BeforeEach
void setUp() {
user = new User();
user.setId(3);
user.setName("小敏");
}
@Test
void inserUser() {
System.out.println(user);
System.out.println(userMapper.inserUser(user));
}
@Test
void deleteUserById() {
System.out.println(" 测试userMapper.deleteUserById 方法");
System.out.println(userMapper.deleteUserById(user.getId()));
}
@Test
void updateUser() {
System.out.println("测试userMapper.updateUser 方法");
user.setId(1);
System.out.println(userMapper.updateUser(user));
}
@Test
void selectUserById() {
System.out.println("测试userMapper.selectUserById 方法");
System.out.println(userMapper.selectUserById(1));
}
@Test
void selectUser() {
System.out.println("测试userMapper.selectUser 方法");
List<User> list = userMapper.selectUser();
System.out.println(list);
}
}
总的目录结构如下图:
4.测试运行结果
七.XML方式实现
xml配置方式保持映射文件的方式,优化主要体现在不需要实现持久层接口方法,系统会自动根据方法名在映射文件中找对应的sql,具体操作如下:
1.编写实体类 Dept.java
package com.lyu.myboot.core.entity;
/**
* @ProjectName: [myboot]
* @Package: [com.lyu.myboot.core.entity]
* @ClassName: [Dept]
* @Description: 部门实体类
* @Author: [easthj]
* @CreateDate: [2020-04-16 上午10:18]
* @UpdateUser: [easthj]
* @UpdateDate: [2020-04-16 上午10:18]
* @UpdateRemark: [说明本次修改内容]
* @Version: [v1.0]
*/
public class Dept {
private Integer id;
private String name;
private Integer code;
@Override
public String toString() {
return "Dept{" +
"id=" + id +
", name='" + name + '\'' +
", code=" + code +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
2.新建DeptMapper接口,无需具体实现类
package com.lyu.myboot.core.mapper;
import com.lyu.myboot.core.entity.Dept;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @ProjectName: [myboot]
* @Package: [com.lyu.myboot.core.mapper]
* @ClassName: [DeptMapper]
* @Description: 部门Mapper接口
* @Author: [easthj]
* @CreateDate: [2020-04-16 上午10:21]
* @UpdateUser: [easthj]
* @UpdateDate: [2020-04-16 上午10:21]
* @UpdateRemark: [说明本次修改内容]
* @Version: [v1.0]
*/
@Mapper
public interface DeptMapper {
/**
* 插入Dept数据
* @param dept
* @return
*/
public int insertDept(Dept dept);
/**
* 根据部门ID删除数据
* @param id
* @return
*/
public int deleteDeptById(Integer id);
/**
* 根据部门ID更新数据
* @param dept
* @return
*/
public int updateDeptById(Dept dept);
/**
* 根据部门ID查询部门数据
* @param id
* @return
*/
public Dept selectDeptById(Integer id);
/**
* 获取部门信息列表
* @return
*/
public List<Dept> selectAll();
}
3.修改application.yml配置文件制定文件映射关系
mybatis:
#指定mapper接口包路径
type-aliases-package: com.lyu.myboot.core.mapper
#指定mapper配置文件路径
mapper-locations: classpath:mapper/*.xml
4.添加DeptMapper的映射文件
在src/main/resources目录下新建一个mapper目录,在mapper目录下新建DeptMapper.xml文件。通过mapper标签中的namespace属性指定对应的mapper映射,这里指向DeptMapper。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lyu.myboot.core.mapper.DeptMapper">
<!--添加部门信息-->
<insert id="insertDept" parameterType="com.lyu.myboot.core.entity.Dept" >
INSERT INTO t_dept (id, name,code) VALUES (#{id}, #{name}, #{code})
</insert>
<!--根据Id删除部门信息-->
<delete id="deleteDeptById" parameterType="java.lang.Integer" >
DELETE FROM t_dept WHERE id =#{id}
</delete>
<!--根据Id更新部门信息-->
<update id="updateDeptById" parameterType="com.lyu.myboot.core.entity.Dept" >
UPDATE t_dept SET name=#{name},code=#{code} WHERE id = #{id}
</update>
<!--根据Id查询部门信息-->
<select id="selectDeptById" parameterType="java.lang.Integer" resultType="com.lyu.myboot.core.entity.Dept">
SELECT * FROM t_dept WHERE id = #{id}
</select>
<!--获取部门列表-->
<select id="selectAll" resultType="com.lyu.myboot.core.entity.Dept">
select * from t_dept
</select>
</mapper>
5.编写测试类
package com.lyu.myboot.core.mapper;
import com.lyu.myboot.BaseTest;
import com.lyu.myboot.core.entity.Dept;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import static org.junit.jupiter.api.Assertions.*;
/**
* @ProjectName: [myboot]
* @Package: [com.lyu.myboot.core.mapper]
* @ClassName: [DeptMapperTest]
* @Description:
* @Author: [easthj]
* @CreateDate: [2020-04-16 上午11:23]
* @UpdateUser: [easthj]
* @UpdateDate: [2020-04-16 上午11:23]
* @UpdateRemark: [说明本次修改内容]
* @Version: [v1.0]
*/
class DeptMapperTest extends BaseTest {
@Autowired
private DeptMapper deptMapper;
private Dept dept;
@BeforeEach
void setUp() {
dept= new Dept();
dept.setId(4);
dept.setName("销售部");
dept.setCode(40);
}
@Test
void insertDept() {
System.out.println("=========测试=deptMapper.insertDept=方法=====================");
System.out.println(deptMapper.insertDept(dept));
}
@Test
void deleteDeptById() {
System.out.println("=========测试=deptMapper.deleteDeptById=方法=====================");
System.out.println(deptMapper.deleteDeptById(dept.getId()));
}
@Test
void updateDeptById() {
System.out.println("=========测试=deptMapper.updateDeptById=方法=====================");
dept.setId(1);
System.out.println(deptMapper.updateDeptById(dept));
}
@Test
void selectDeptById() {
System.out.println("=========测试=deptMapper.selectDeptById=方法=====================");
System.out.println(deptMapper.selectDeptById(dept.getId()));
}
@Test
void selectAll() {
System.out.println("=========测试=deptMapper.selectAll=方法=====================");
System.out.println(deptMapper.selectAll());
}
}
6.测试运行结果
7.项目最终目录结构:
八.拓展Idea添加mybatis xml生成模板
1.点击File--->Settings --->Edit-->File and Code Templates
2.找到右侧 + 添加模板
点击+ 后会新建一个模板 将name 改为mybatis-mapper, extension 改为 xml 将一下内容粘贴到模板区
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="${NAMESPACE}" >
</mapper>
如下图:
完成后点击 ok保存。
3.使用
选中mapper文件夹右键 new——>找到 mybatis-mapper—>单击
填写 文件名称和namespace ---> OK
UserMapper.xml创建成功 接下来床编写自己的业务逻辑sql
================================================================================================
获取更多内容请关注【编程与读书】公众号