最后编辑时间:2020年2月8日11:04:11
框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。
表现层:用于展示数据;
业务层:用于业务处理;
持久层:用于和数据库交互;
图示:
Connection;
PreparedStatement;
ResultSet;
Spring中对JDBC的简单封装;
与Spring中对JDBC很像,也是对JDBC的简单封装;
备注:以上都不是框架,JDBC是规范,后面两个只算是工具类;
白话简介:JDBC是用Java操作数据库,但是JDBC太麻烦,MyBatis是对JDBC的进一步封装。
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射;
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集;
MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录;
MyBatis使用了ORM的思想实现了结果集的封装;
作用:
1、用来访问数据库,进行持久化操作;
2、本质上是对JDBC进行封装;
Object Relational Mapping 对象关系映射
白话:把数据库表和实体类的属性对应起来,让我们可以通过操作实体类来实现操作数据库表;
https://mybatis.org/mybatis-3/zh/index.html
POM.XML文件:用于指定所用到云端框架的坐标;
实体类:实体类对应要操作的表;
接口:接口是对数据库进行操作的Java代码(方法);
主配置文件:配置数据库的信息用于访问数据库,指定映射配置文件;
映射配置文件:指定接口中的方法所执行的SQL语句;
根据配置信息或者代码来生成SqlSessionFactory(工厂接口);
依靠工厂来生成SqlSession(会话);
概述:
1、每个MyBatis应用都是以SqlSessionFactory的实例为中心的;
2、SqlSessionFactory的实例SqlSessionFactoryBuilder来获得;
3、SqlSessionFactory是一个工厂接口而不是一个类,它的任务是创建SqlSession;
4、SqlSession是一个会话,类似JDBC的Connection对象;
5、MyBatis提供了两种方式去创建SqlSessionFactory:XML配置的方式(推荐)和代码的方式;
6、Configuration存在于整个MyBatis应用的生命周期中,体积小,性能高,解析一次XML文件保存到Configuration中,可重复读取使用;
7、DefaultSqlSessionFactory是SqlSessionFactory的一个实现类;
使用XML方式构建SqlSessionFactory:
(见SqlMapConfig.xml)
代码方式创建SqlSessionFactory:
大部分情况下不用,需要加入自己特性的时候才用到,例如数据源配置的信息要求是加密的时候我们需要把他们转化过来。
package com.zibo.mybatis_crud.utils;
import com.zibo.mybatis_crud.dao.IUserDao;
import com.zibo.mybatis_crud.domain.User;
import org.apache.ibatis.datasource.pooled.PooledDataSource;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
public class GetSqlSessionFactory {
public static SqlSessionFactory get(){
//1、构建数据库连接池
PooledDataSource dataSource = new PooledDataSource();
dataSource.setDriver("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/zibo?serverTimezone=UTC");
dataSource.setUsername("root");
dataSource.setPassword("zibo15239417242");
//2、构建数据库事务方式
TransactionFactory transactionFactory = new JdbcTransactionFactory();
//3、创建数据库运行环境
Environment environment = new Environment("development",transactionFactory,dataSource);
//4、构建Configuration对象
Configuration configuration = new Configuration(environment);
//5、注册一个MyBatis上下文别名
configuration.getTypeAliasRegistry().registerAlias("user", User.class);
//6、加入一个映射器
configuration.addMapper(IUserDao.class);
//7、使用SqlSessionFactoryBuilder构建SqlSessionFactory
return new SqlSessionFactoryBuilder().build(configuration);
}
}
是一个可以发送SQL去执行并返回结果,也可以获取Mapper的接口;
SqlSession(会话)的两种用途:
1、获取映射器,让映射器通过命名空间和方法名称找到对应的SQL,发送给数据库执行后返回结果;
2、直接通过命名空间信息去执行SQL返回结果;
是MyBatis新设计的组件,是由一个接口和XML文件(或者注解)构成的,需要给出对应的SQL和映射规则,负责发送SQL去执行并返回结果;
作用:
1、定义参数类型;
2、描述缓存;
3、描述SQL语句;
4、定义查询结果和POJO的映射关系;
SQL Mapper(映射器)可以用XML方式和代码方式实现,强烈建议XML方式,代码方式不再演示,XML见(IStudentDao.xml):
pom.xml:
4.0.0
com.zibo.mybatis
mybatis
1.0-SNAPSHOT
jar
org.mybatis
mybatis
3.4.6
mysql
mysql-connector-java
8.0.17
log4j
log4j
1.2.17
junit
junit
4.13-beta-3
test
实体类:
package com.zibo.mybatis;
import java.io.Serializable;
public class Student implements Serializable {
private int id;
private String name;
private int age;
private String sex;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
接口:
package com.zibo.mybatis;
import java.util.List;
public interface IStudentDao {
List findAll();
}
SqlMapConfig.xml
IStudentDao.xml:
①MyBatis把持久层的操作接口和映射文件也叫做Mapper,所以文件XXXDao和XXXMapper是一样的;
②在idea创建目录的时候,它和包是不一样的:
包的创建:com.zibo.XXX是三级目录;
目录的创建:com.zibo.XXX是一级目录;
③MyBatis的映射配置文件的位置必须和dao接口的包结构相同;
④映射配置文件的mapper标签的namespace属性的取值必须是dao接口(Mapper)的全类名;
⑤映射配置文件的操作配置(select),id的属性取值必须是dao接口的方法名;
当遵循了③④⑤点之后,我们在开发中就无需再写dao实现类;
第一步:读取配置文件;
第二步:创建一个SqlSessionFactory工厂;
第三步:使用工厂生产SqlSession对象;
第四步:使用SqlSession对象创建接口的代理对象;
第五步:使用代理对象执行方法;
第六步:释放资源
log4j.properties:
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
package com.zibo.mybatis;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class Test {
public static void main(String[] args) throws IOException {
//第一步:读取配置文件;
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//第二步:创建一个SqlSessionFactory工厂;
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//第三步:使用工厂生产SqlSession对象;
SqlSession session = factory.openSession();
//第四步:使用SqlSession对象创建接口的代理对象;
IStudentDao iStudentDao = session.getMapper(IStudentDao.class);
//第五步:使用代理对象执行方法;
List students = iStudentDao.findAll();
for (Student student : students) {
System.out.println(student);
}
//第六步:释放资源
session.close();
in.close();
}
}
第一步:删除IStudentDao.xml;
第二步:在IStudentDao的方法上使用Select注解,并指定SQL语句;
@Select("select * from student")
第三步:在SqlMapConfig.xml中的mapper配置中使用class属性指定被注解的dao全限定类名;
实际开发中越简便越好,所有不管是XML配置还是注解配置都采用不写dao实现类的方式,但是MyBatis是支持写dao实现类的;
第一步:创建一个dao的接口实现类;
package com.zibo.mybatis;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
public class IStudentDaoImpl implements IStudentDao {
private SqlSessionFactory factory;
public IStudentDaoImpl(SqlSessionFactory factory) {
this.factory = factory;
}
@Override
public List findAll() {
//1、使用工厂生产SqlSession对象
SqlSession session = factory.openSession();
//2、使用session执行查询方法
//3、返回查询结果
return session.selectList("com.zibo.mybatis.IStudentDao.findAll");
}
}
第二步:修改Test测试类:
package com.zibo.mybatis;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class Test {
public static void main(String[] args) throws IOException {
//第一步:读取配置文件;
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//第二步:创建一个SqlSessionFactory工厂;
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//第三步:使用工厂生产SqlSession对象;
IStudentDaoImpl iStudentDao = new IStudentDaoImpl(factory);
// SqlSession session = factory.openSession();
// //第四步:使用SqlSession对象创建接口的代理对象;
// IStudentDao iStudentDao = session.getMapper(IStudentDao.class);
//第五步:使用代理对象执行方法;
List students = iStudentDao.findAll();
for (Student student : students) {
System.out.println(student);
}
//第六步:释放资源
// session.close();
in.close();
}
}
是利用XML或者Java代码的方式构建SqlSessionFactory,通过它可以构建多个SqlSessionFactory。
它的作用是一个构建器,一旦我们构建了SqlSessionFactory就不再需要它了,因此它一般在局部代码中;
SqlSessionFactory作用是创建SqlSession,而SqlSession是一个会话,相当于JDBC的Connection对象,每次应用程序访问数据库,都需要通过SqlSessionFactory创建SqlSession对象,所以SqlSessionFactory应该存在于MyBatis应用的整个生命周期;
如果我们多次创建同一个数据库的SqlSessionFactory,数据库连接(Connection)资源很快就会被耗尽,所以SqlSessionFactory的责任是唯一的,就是创建SqlSession,我们果断采用单例模式,所以每个数据库应该只对应一个SqlSessionFactory;
SqlSession是一个会话,相当于JDBC中的Connection对象,它的生命周期应该是在请求数据库请求事务的过程中。它是一个线程不安全的对象,在涉及多线程的时候我们要特别当心,操作数据库需要注意其隔离级别,数据库锁等高等特性;
此外,每次创建的SqlSession都要及时关闭它,否则对系统性能的影响很大;
它存活于一个应用的请求和操作,可以执行多条SQL语句,保证事务的一致性;
Mapper是一个接口,没有任何实现类,它的作用是发送SQL,然后返回我们需要的结果,或者执行SQL从而修改数据库的数据,因此它应该在一个SqlSession方法之内,是一个方法级别的东西,所以尽量在Sqlsession方法事务中使用它,然后废弃掉。