MySQL、Jdbc、Mybatis之间的关系
目录
一、JDBC(底层基础技术)
1、什么是JDBC?
JDBC:Java DataBase Connectivity(java数据库连接),是使用Java语言操作关系型数据库的一套API(规范)
而MyBatis、MyBatisPlus、Hibernate、SpringData JPA等框架是基于JDBC的高级封装,都可以用于操作数据库。
各个关系型数据库厂商会基于这套规范去实现这套接口,提供数据库驱动jar包(具体实现)。
而我们想要操作数据库,需要引入对应的jar包,对数据库进行操作,我们只需要基于JDBC接口去操作数据库,而实际上真正执行的是驱动jar包里的实现类
2、JDBC的入门程序
创建一个普通的maven项目(不用springBoot)→引入mysql的jar包依赖→准备数据库表user→编写JDBC程序,操作数据库
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version></version>
</dependency>
3、JDBC的执行流程
注册驱动→获取连接→获取SQL语句的执行对象→执行SQL语句→释放资源
//注册驱动(告诉要使用哪一套jdbc的实现)
Class.forName("com.mysql.cj.jdbc.Driver");//mysql驱动类的全类名
//获取连接(连接mysql数据库)
String url="jdbc:mysql://localhost:3306/数据库名";
String username="";
String password="";
Connection connection=DriverManager.getConnection(url,username,password);
//获取sql语句执行对象
Statement statement=connection.createStatement();
//执行sql
int rowsAffected=statement.executeUpdate("update user set age=25 where id=1"); //DML语句,操作语句,返回影响的记录数
//释放资源
statement.close();
connection.close();
4、JDBC执行DQL查询语句时会涉及到预编译SQL(PreparedStatement)
什么是预编译?
就是查询语句中没有把参数值写死,而是使用一个问好 ?作为占位符。动态传参
它在获取SQL语句执行对象时,获取的是PreparedStatement对象,而不是普通的Statement对象。PreparedStatement是Statement的一个子接口,它继承了Statement
//注册驱动、获取连接都是一样的
//预编译sql语句
String sql="select id,username,password,name,age from user where username=? and password=?";
//获取sql语句执行对象
PreparedStatement statement=connection.preparedStatement(sql);
//为占位符赋值
statement.setString(1,"daqiao");
//执行操作,ResultSet对象用于封装查询的返回结果
ResultSet rs=statement.executeQuery();
//处理结果集,把数据封装到User对象
while(rs.next()){
User user=new User(
rs.getInt("id"), //rs.getXxx("列名"); Xxx是对应的数据类型
rs.getString("username"),
rs.getInt("age")
);
System.out.println(user); //Lombok的@Data自动生成的toString方法
}
预编译SQL
优势一:可以防止SQL注入,更安全
什么是SQL注入?
SQL注入:通过控制输入来修改已经写好的sql语句,以达到执行代码对服务器进行攻击(在不知道账号名和密码的情况下也能登录成功)
例如:进行登录操作(登录操作的实质是查询数据库中,有没有这个人 )
select count(*) from emp where username='' and password='';
静态sql:是把传入的参数值直接拼接在sql语句中的引号里面,拼接好之后再发送给数据库
动态sql(预编译SQL):用一个?作为占位符,会把带有占位符的sql语句和传入的参数一起传给数据库,一个占位符对应一个参数
优势二:性能更高
SQL语句的在Mysql的执行流程:
SQL语法检查→优化SQL→编译SQL(并加入到缓存,下次再执行SQL语句时,会先看缓存里面有没有,如果没有再从头开始检查→优化→编译→执行)→执行SQL
二、Mybatis
什么是Mybatis?
它是一个持久层框架,用于简化JDBC的开发,底层是对JDBC的封装
入门程序:使用Mybatis查询所有用户数据
1、创建SpringBoot工程,引入Mybatis依赖
2、创建数据库表User、实体类User
3、配置Mybatis(在application.properties中数据库连接信息)
4、编写Mybatis持久层接口


@Mapper
public interface UserMapper {
@Select("select * from user")
public List<User> findAll();
}
加上@Mapper注解就意味着:应用程序在运行时会自动创建UserMapper接口的实现类对象(基于动态代理技术创建出来的代理对象),并且会自动将代理对象(实现类)交给SpringIOC容器管理,成为bean对象
//SpringBoot测试方法
@SpringBootTest
class SpringbootMybatisQuickatartApplicationTests {
@Autowired
private userMapper userMapper;
@Test
public void testFindAll() {
List<User> userList=userMapper.findAll();
userList.forEach(System.out::println);
}
}
加上@SpringBoot单元测试注解,意味着当测试类中的测试方法运行时,会启动springboot项目,就会创建IOC容器,如果想要容器里哪个bean,就直接注入该对象
注意:测试类必须和启动类在同一包下
辅助配置:配置mybatis的日志输出
//在application.properties里面配置
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
三、JDBC VS Mybatis

四、数据库连接池
数据库连接池是一个容器,负责分配、管理数据库连接。
数据库连接池的作用:
- 它允许应用程序重复使用一个现有的数据库连接(资源重用),而不是重新建立一个。(提升系统响应速度,不用每次都创建连接,并释放连接)
- 它会释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏问题。(空闲状态是指客户端占着连接但没有操作数据库,且不归还给连接池)
所有的数据库连接池都会实现DataSource接口
springboot默认使用的数据库连接池:HiKari
使用Druid连接池
1、在pom.xml中引入依赖
<!--Druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.27</version>
</dependency>
2、application.properties配置数据库连接池信息
#配置数据库连接信息
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/web01
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
五、基于Mybatis的增删改查
1、根据 Id 删除用户信息
//userMapper接口
//预编译sql,不把sql语句写死
@Delete("delete from user where id=#{id}")
public void deleteById(int id);
//在测试方法中,返回值是影响的行数
@Test
public void testDeleteById() {
int i=userMapper.deleteById(1); //i是影响的行数
}
Mybatis中 #{….}和${….}的区别:
#{….}是占位符。执行时,会将#{….}替换为 ? 生成预编译SQL。安全、性能高,常用于参数传递
${….}是拼接符。直接把参数拼接在SQL语句中,存在SQL注入问题。不安全,性能低,常用于表名、字段名动态设置时使用。
2、添加一个用户
因为添加的信息比较多,所以通常将信息封装给一个对象,把对象传进去
//注意:#{}里面传递的是对象的属性名
@Insert("insert into user(username,password,name,age) values(#{username},#{password},#{name},#{age})")
public void addUser(User user);
@Test
public void testInsert() {
User user=new User(1,"admin","123456","张三",18);
userMapper.addUser(user);
}
3、根据Id更新用户信息
@Update("update user set username=#{username},password=#{password},name=#{name},age=#{age} where id=#{id}")
public void updateUser(User user);
4、根据用户名和密码查询用户信息
@Select("select * from user where username=#{username} and password=#{password}")
public User findByUsernameAndPassword(@Param("username") String username,@Param("password") String password);
如果方法中传入多个参数,需要用@Param("…..")注解给形参取名字
说明:基于官方骨架创建的SpringBoot项目中,@Param注解可省略
@Test
public void testFindByUsernameAndPassword() {
User user=userMapper.findByUsernameAndPassword("admin","123456");
System.out.println(user);
}
在Mybatis中,既可以通过注解配置SQL语句,也可以通过XML配置文件配置SQL语句
简单的增删改查功能使用注解的方式,如果实现复杂的SQL功能建议使用XML配置文件
XML映射配置
1、XML映射文件的名称与mapper接口名称一致,并且将XML映射文件和Mapper接口放置同一包下(同包同名)
2、XML映射文件的namespace属性为Mapper接口全限定名一致
3、XML映射文件中sql语句的id与Mapper接口中的方法名一致,并且返回值类型一致。resultType对应单条记录的全类名

//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="org.example.mapper.userMapper">
<select id="findAll" resultType="org.example.pojo.User">
select id, username, password, name, age from user
</select>
</mapper>
如果没有把XML文件放在指定的路径下,可以在application.properties里面指定XML映射配置文件的位置
#指定XML映射配置文件的位置
mybatis.mapper-locations=classpath:mapper/*.xml
更多推荐




所有评论(0)