JDBC与Mybatis
JDBC与Mybatis
1.0 连接数据库并操作
我们使用jdbc来操作Mysql数据库,首先需要在pom中引入mysql驱动并且导入Junit单元测试包
package com.javalearn;
import org.junit.jupiter.api.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCTest {
@Test
public void testUpdate() throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","352532451");
Statement statement=connection.createStatement();
ResultSet resultSet =statement.executeQuery("select * from user");
while (resultSet.next()){
System.out.println(resultSet.getString("username"));
}
statement.close();
connection.close();
}
}
接着是使用Class注册驱动,注册驱动通过加载驱动类来执行内部的静态代码块,如果不注册驱动SPI也会帮我们自
动的注册完成
接着去创建连接对象,如果我们的mysql服务在本地,可以将localhost:3306 省略掉
接着获取执行对象,我们当前创建的是普通的sql执行对象,我们还可以创建预编译sql执行对象
然后执行数据库操作语句,如果想要执行查询操作就使用ececuteQuery 如果想要执行DDL和DML语句,也就是
增删改和定义表,则使用executeUpdate语句
使用executeUpdate 语句返回的是本次操作中受到影响的行号,使用ececuteQuery返回的是一个ResultSet对
象,来存储接受到的结果,查询的结果可能是0行,也可能是多行next方法可以对当前行是否有值进行判断,如果
有就返回true,如果一条也没查到就返回false,无论是true还是false,执行完后都会自动的向下移动一行
获取数据可以通过下标或者列名,如果通过下标起始下标是1,需要根据数据的类型调用对应的get方法
如果需要查询多条数据我们一般放在对象中
我们如果要测试,像这样直接写死sql语句肯定是不行的,就要用到参数化测试:
package com.javalearn;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import org.junit.jupiter.params.provider.CsvSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCTest {
@ParameterizedTest
@CsvSource({"admin, 1234","mysql, 111"})
public void testUpdate(String username,String password) throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","352532451");
Statement statement=connection.createStatement();
ResultSet resultSet =statement.executeQuery("select * from user where username='"+username+"' and password='"+password+"'");
while (resultSet.next()){
System.out.println(resultSet.getString("username"));
System.out.println(resultSet.getString("password"));
}
statement.close();
connection.close();
}
}
但如果我们之前学习过网络安全相关知识的话,就能发现现在这种写法是存在安全风险的,很轻松的就可以进行
sql注入,所以我们要采取预编译的sql语句
下面是修改后的代码:
package com.javalearn;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import java.sql.*;
public class JDBCTest {
@ParameterizedTest
@CsvSource({"admin, 1234","mysql, 111"})
public void testUpdate(String username,String password) throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","352532451");
PreparedStatement preparedStatement=connection.prepareStatement("select * from user where username=? and password =?");
preparedStatement.setString(1,username);
preparedStatement.setString(2,password);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getString("username"));
System.out.println(resultSet.getString("password"));
}
preparedStatement.close();
connection.close();
}
}
当前的这种写法因为通过使用预编译sql,做到了避免sql注入的效果,注意我们通过?替代我们本来要写入变量的
地方,通过下面的setString来赋字符串变量值,这里在内部做了处理,不单是简单拼接,为了适配sql语法在变量
替换时两侧加了引号
使用预编译sql 不仅可以避免sql注入,还可以减少编译次数,优化sql操作的性能
1.1 Mybatis入门
使用jdbc操作数据库还是太麻烦了,所以我们将使用持久层框架mybatis来操作数据库
首先我们创建一个sping项目,将Mybits和mysql驱动都导入到依赖中
然后再resources中配置mybatis设置
spring.application.name=Mybatis
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=111
接下来创建实体类
我们创建entity包来存储实体类
package com.javalearn.mybatis.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id;
private String name;
private String username;
private String password;
private String gender;
private Integer age;
}
然后创建mapper包写mapper接口
package com.javalearn.mybatis.mapper;
import com.javalearn.mybatis.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper //程序启动时会自动生成该接口的代理对象交由ioc管理
public interface UserMapper {
@Select("select * from user")
public List<User> list();
}
将sql语句写到注释里,因为使用的是select所以使用select注解
使用Mapper接口替代Dao
再去测试接口
创建测试类
package com.javalearn.mybatis;
import com.javalearn.mybatis.entity.User;
import com.javalearn.mybatis.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void listTest(){
List<User> users=userMapper.list();
for (User user : users) {
System.out.println(user);
}
}
}
因为这里需要用到依赖注入,所以需要使用到@SpringBootTest来加载spingboot,默认是不在测试文件夹加载
的
但直接运行我们输出是看不到sql语句等信息的,如果想要看到就需要在配置文件加入
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
将输出直接打印到控制台
测试类想要正确运行也需要在测试的启动类在一个包或者自包下
使用Mybatis和之前的jdbc对比,我们不需要自己取获得值创建实体类对象,而是自动去封装,不需要我们自己去
处理
1.2 数据库连接池
和线程池类似,Mybatis使用数据库连接池管理数据库连接对象优势是可以实现资源重用,提升系统响应速度,并
且可以避免数据库连接遗漏
SpringBoot使用的默认数据库连接池是hikari 国内使用较多的是阿里的Druid
想要使用Druid直接导入依赖后在配置文件加
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
即可切换
1.3基于xml执行sql语句
我们之前执行sql语句都是基于注解,还可以基于xml执行sql语句,我们执行的xml文件结构如下:

xml文件需要和我们的mapper接口同包名同文件名,除了后缀不需要相同,需要注意在resources下无法创建包,
所以我们要按/来代替.创建文件夹
xml的内容如下:
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.javalearn.mybatis.mapper.UserMapper">
<select id="list" resultType="com.javalearn.mybatis.entity.User">
select * from user;
</select>
</mapper>
最上面引入的dtd文件对xml文件的内容做约束,namespace 声明了mapper 接口的全类名,id代之接口中的方
法,返回的数据类型也需要使用全类名,因为使用的是select方法,所以使用select标签/
1.4 数据封装
mybatis提供了自动封装功能,会将数据库返回的结果封装成实体类的数据,前提是字段名和属性名一致,如果字
段我们使用的_分割单词,属性使用驼峰,就需要开启转换的配置才能实现自动封装
mybatis.configuration.map-underscore-to-camel-case=true
需要在配置文件上加上这一行才能实现自动封装
除了自动我们也可也选择手动结果映射
使用@Results注解
@Results({
@Result(column="",property=""),
})
将这个放到mapper接口的函数之上即可建立映射关系

浙公网安备 33010602011771号