JDBC
pom.xml中引入JDBC和MySQL依赖
<dependencies>
<!-- MySQL JDBC driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
</dependencies>
src/main/test/java 目录下编写测试类,定义测试方法
public class JDBCTest {
/**
* 编写JDBC程序, 查询数据
*/
@Test
public void testJdbc() throws Exception {
// 获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web", "root", "1234");
// 创建预编译的PreparedStatement对象
PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM user WHERE username = ? AND password = ?");
// 设置参数
pstmt.setString(1, "daqiao"); // 第一个问号对应的参数
pstmt.setString(2, "123456"); // 第二个问号对应的参数
// 执行查询
ResultSet rs = pstmt.executeQuery();
// 处理结果集
while (rs.next()) {
int id = rs.getInt("id");
String uName = rs.getString("username");
String pwd = rs.getString("password");
String name = rs.getString("name");
int age = rs.getInt("age");
System.out.println("ID: " + id + ", Username: " + uName + ", Password: " + pwd + ", Name: " + name + ", Age: " + age);
}
// 关闭资源
rs.close();
pstmt.close();
conn.close();
}
}
@ParameterizedTest
@CsvSource({"1,123456,25"})//在测试时,需要传递一组参数,可以使用 @CsvSource 注解。
public void testUpdate(int userId, String newPassword, int newAge) throws Exception {
// 建立数据库连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web", "root", "1234");
// SQL 更新语句
String sql = "UPDATE user SET password = ?, age = ? WHERE id = ?";
// 创建预编译的PreparedStatement对象
PreparedStatement pstmt = conn.prepareStatement(sql);
// 设置参数
pstmt.setString(1, newPassword); // 第一个问号对应的参数
pstmt.setInt(2, newAge); // 第二个问号对应的参数
pstmt.setInt(3, userId); // 第三个问号对应的参数
// 执行更新
int rowsUpdated = pstmt.executeUpdate();
// 输出结果
System.out.println(rowsUpdated + " row(s) updated.");
// 关闭资源
pstmt.close();
conn.close();
}
- JDBC程序执行DML语句:int rowsUpdated = pstmt.executeUpdate(); //返回值是影响的记录数
- JDBC程序执行DQL语句:ResultSet resultSet = pstmt.executeQuery(); //返回值是查询结果集
MyBatis
MyBatis是一款优秀的 持久层(dao) 框架,用于简化JDBC的开发
在 application.properties 中配置数据库的连接信息。
实体类的属性名与表中的字段名一一对应。 实体类放在 site.suiyue.pojo 包下。
编写Mybatis程序:
编写Mybatis的持久层接口,定义SQL语句(注解)
mapper创建在引导类所在包下 。在 mapper 包下创建一个接口 UserMapper ,这是一个持久层接口(Mybatis的持久层接口规范一般都叫 XxxMapper)。
import site.suiyue.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface UserMapper {
/**
* 查询全部
*/
@Select("select * from user")
public List<User> findAll();
}
- @Mapper注解:表示是mybatis中的Mapper接口,程序运行时,框架会自动生成接口的实现类对象(代理对象),并给交Spring的IOC容器管理
- @Select注解:代表的就是select查询,用于书写select查询语句
单元测试
在创建出来的SpringBoot工程中,在src下的test目录下,已经自动帮我们创建好了测试类 ,并且在测试类上已经添加了注解 @SpringBootTest,代表该测试类已经与SpringBoot整合。
该测试类在运行时,会自动通过引导类加载Spring的环境(IOC容器)。我们要测试那个bean对象,就可以直接通过@Autowired注解直接将其注入进行,然后就可以测试了。
@SpringBootTest
class SpringbootMybatisQuickstartApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
public void testFindAll(){
List<User> userList = userMapper.findAll();
for (User user : userList) {
System.out.println(user);
}
}
}
注意:测试类所在包,需要与引导类所在包相同。
查看日志
默认情况下,在Mybatis中,SQL语句执行时,我们并看不到SQL语句的执行日志。 在application.properties加入如下配置,即可查看日志:
#mybatis的配置
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
删除
@Delete("delete from user where id = #{id}")
public Integer deleteById(Integer id);
//Integer类型的返回值,表示DML语句执行完毕影响的记录数。
在单元测试类中,增加如下测试方法
@Test
public void testDeleteById(){
userMapper.deleteById(36);
}
| 符号 | 说明 | 场景 | 优缺点 |
| #{…} | 占位符。执行时,会将#{…}替换为?,生成预编译SQL | 参数值传递 | 安全、性能高 (推荐) |
| ${…} | 拼接符。直接将参数拼接在SQL语句中,存在SQL注入问题 | 表名、字段名动态设置时使用 | 不安全、性能低 |
新增
@Insert("insert into user(username,password,name,age) values(#{username},#{password},#{name},#{age})")
public void insert(User user);
在单元测试类中,增加如下测试方法
@Test
public void testInsert(){
User user = new User();
user.setUsername("admin");
user.setPassword("123456");
user.setName("管理员");
user.setAge(30);
userMapper.insert(user);
}
修改
@Update("update user set username = #{username},password = #{password},name = #{name},age = #{age} where id = #{id}")
public void update(User user);
在单元测试类中,增加如下测试方法
@Test
public void testUpdate(){
User user = new User();
user.setId(6);
user.setUsername("admin666");
user.setPassword("123456");
user.setName("管理员");
user.setAge(30);
userMapper.update(user);
}
查询
@Select("select * from user where username = #{username} and password = #{password}")
public User findByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
//@param注解的作用是为接口的方法形参起名字的。(由于用户名唯一的,所以查询返回的结果最多只有一个,可以直接封装到一个对象中)
在单元测试类中,增加如下测试方法
@Test
public void testFindByUsernameAndPassword(){
User user = userMapper.findByUsernameAndPassword("admin666", "123456");
System.out.println(user);
}
XML映射
规范
- XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)
如src/main/resources/site/suiyue/mapper/UserMapper.xml和src/main/java/site/suiyue/mapper/UserMapper.java - XML映射文件的namespace属性为Mapper接口全限定名一致
- XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。
<?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="site.suiyue.mapper.UserMapper">
<select id="findAll" resultType="site.suiyue.pojo.User">
select * from user
</select>
</mapper>
- XML映射文件的namespace属性为Mapper接口全限定名
- resultType属性,指的是查询返回的单条记录所封装的类型。
- <select>标签:就是用于编写select查询语句的。
yaml
#对象/Map集合
user:
name: zhangsan
age: 18
password: 123456
#数组/List/Set集合
hobby:
- java
- game
- sport
#具体到application.yml
spring:
application:
name: springboot-mybatis-quickstart
datasource:
url: jdbc:mysql://localhost:3306/fuck
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: Uujuku32767.
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
在yml格式的配置文件中,如果配置项的值是以 0 开头的,值需要使用 '' 引起来,因为以0开头在yml中表示8进制的数据。
Comments NOTHING