1.Mybatis概述
mybatis是一个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。mybatis通过 xml 或注解的方式将要执行的各种statement配置起来,并通过java对象和statement 中sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。采用 ORM 思想解决了实体和数据库映射的问题,对 jdbc进行了封装,屏蔽了 jdbc api 底层访问细节,使我们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。
2.回顾JDBC操作
2.1. 加载数据库驱动
ClassForName("com.mysql.cj.jdbc.Driver");
2.2 获取数据库连接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC","root", "root");
2.3 定义preparedStatement对应的sql
String sql = "select * from student where name = ?";
2.4 获取预处理statement
preparedStatement = connection.prepareStatement(sql);
2.5 设置参数,第一个参数为 sql 语句中参数的序号(从 1 开始),第二个参数为设置的参数值
preparedStatement.setString(1, "王二麻子");
2.6 向数据库发出 sql 执行查询,查询出结果集
resultSet = preparedStatement.executeQuery();
2.6.1 补充 execute、executeQuery和executeUpdate之间的区别
execute : 用于执行返回多个结果集、多个更新计数或二者组合的语句。execute方法应该仅在语句能返回多个 ResultSet对象、多个更新计数或ResultSet对象与更新计数的组合时使用。
executeQuery: 用于产生单个结果集的语句,例如 SELECT 语句。
executeUpdate: 用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQL DDL(数据定义语言)语句,例 如 CREATE TABLE 和 DROP TABLE。
2.7 jdbc 中存在的问题:
2.7.1 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
2.7.2 Sql 语句在代码中硬编码,造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java
代码。
2.7.3 使用 preparedStatement 向占有位符号传参数存在硬编码,因为 sql 语句的 where 条件不一定,可能
多也可能少,修改 sql 还要修改代码,系统不易维护。
2.7.4 对结果集解析存在硬编码(查询列名),sql 变化导致解析代码变化,系统不易维护,如果能将数据库记
录封装成 pojo 对象解析比较方便。
3.Mybatis的简单使用
3.1 Maven工程坐标
org.mybatis
mybatis
3.4.5
3.2 创建Student实体类
public class Student implements Serializable
{
private String name;
private Date birthday;
private Integer studenNumber;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Integer getStudenNumber() {
return studenNumber;
}
public void setStudenNumber(Integer studenNumber) {
this.studenNumber = studenNumber;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", birthday=" + birthday +
", studenNumber=" + studenNumber +
", address='" + address + '\'' +
'}';
}
}
3.3 持久层接口
public interface StudentDao
{
/*
* @Author chensy
* @Description //TODO 查询所有的学生
* @Date 23:34 2019/4/20
* @Param []
* @return java.util.List
**/
List findAll();
}
3.4 持久层接口配置文件
创建位置:必须和持久层接口在相同的包中。
名称:必须以持久层接口名称命名文件名,扩展名是.xml
3.5 SqlMapConfig.xml 配置文件
3.6 以上文件对应maven工程的目录:
3.7 测试方法
private InputStream in;
private SqlSessionFactoryBuilder sqlSessionFactoryBuilder;
private SqlSessionFactory sqlSessionFactory;
private SqlSession sqlSession;
private StudentDao studentDao;
@Before
public void init() throws IOException {
//读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//工厂创建类
sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//创建工厂
sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
//创建sqlsession对象
sqlSession = sqlSessionFactory.openSession();
//创建接口代理对象
studentDao = sqlSession.getMapper(StudentDao.class);
}
@After
public void destory() throws IOException {
//提交事务
sqlSession.commit();
sqlSession.close();
in.close();
}
/*
* @Author chensy
* @Description //TODO 测试查询所有
* @Date 23:03 2019/4/8
* @Param []
* @return void
**/
@Test
public void testFindAll() {
List users = studentDao.findAll();
for (Student u : users)
{
System.out.println(u);
}
}
4.使用注解进行开发
4.1 实体类接口
public interface StudentDao{
/**
* 查询所有学生
* @return
*/
@Select("select * from student")
List findAll();
}
4.2 不用写StudentDao.xml配置文件, 直接在SqlMapConfig.xml中配置