JDBC&Mybatis

发布于 22 天前 2 次阅读 1615 字 预计阅读时间: 7 分钟 JAVA


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

规范

  1. XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)
    如src/main/resources/site/suiyue/mapper/UserMapper.xml和src/main/java/site/suiyue/mapper/UserMapper.java
  2. XML映射文件的namespace属性为Mapper接口全限定名一致
  3. 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进制的数据。