1.什么是三层架构?
在项目开发中,遵循的形式模式分为三种:
1.界面层:用来接收客户端的输入,调用业务逻辑层进行功能处理,返回结果给客户端,(过去的servlet就是界面层的功能)
2.业务逻辑层:用来进行整个项目的业务逻辑处理,向上为界面层提供处理结果,向下问数据层要数据
3.数据访问层:专门进行数据库的增删改查操作。想上为业务逻辑层提供数据
各层之间的调用顺序是固定的,不能跨层访问
**界面层<——>业务逻辑层<——>数据访问层
2.生活中的三层架构
3.常用的框架SSM.
Spring:它是整合其它框架的框架.它的核心是IOC和AOP.它由20多个模块构成.在很多领域都提供了很好的解决方案.是一个大佬级别的存在.
SpringMVC:它是Spring家族的一员.专门用来优化控制器(Servlet)的.提供了极简单数据提交,数据携带,页面跳转等功能.
MyBatis:是持久化层的一个框架.用来进行数据库访问的优化.专注于sql语句.极大的简化了JDBC的访问.
4.什么是框架?
它是一个半成品软件.将所有的公共的,重复的功能解决掉,帮助程序快速高效的进行开发.它是可复用,可扩展的.
5.什么是MyBatis框架?
MyBatis 本是 apache 的一个开源项目iBatis, 2010 年这个项目由 apache software foundation 迁移到了 google code,并且改名为 MyBatis 。2013 年 11 月迁移到 Github,最新版本是 MyBatis 3.5.7 ,其发布时间是 2021 年 4月 7日。
MyBatis完成数据访问层的优化.它专注于sql语句.简化了过去JDBC繁琐的访问机制.
6.添加框架的步骤
1)添加依赖
2)添加配置文件
具体步骤:
1.新建库建表
2.新建maven项目,选quickstart模板
3.修改目录,添加缺失的目录,修改目录属性
4.修改pom.xml文件,添加MyBatis的依赖,添加mysql的依赖
<!--添加MyBatis框架的依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!--添加mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
5.修改pom.xml文件,添加资源文件指定
<!--添加资源文件的指定(不指定,所有非java文件不会copy到target里-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
6.在idea中添加数据库的可视化
**注意:**若MySQL的jar包是8版本以上的
需要修改serverTimezone=Asia/Shanghai
7.添加jdbc.properties属性文件(数据库的配置)
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=root
8.添加SqlMapConfig.xml文件,MyBatis的核心配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--读取属性文件(jdbc.properties)
属性:resource:从resource目录下找到指定名称的文件加载
url:使用绝对路径加载属性文件
-->
<properties resource="jdbc.properties"></properties>
<!--设置日志,输出底层执行的代码-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--注册实体类的别名-->
<typeAliases>
<!--单个实体类注册别名-->
<!--
<typeAlias type="com.xin.entity.Student" alias="student"></typeAlias>
-->
<!--批量注册别名
别名时类名的驼峰命名法(规范)
-->
<package name="com.xin.entity"/>
</typeAliases>
<!--配置数据库的环境变量(数据库连接的配置)-->
<environments default="development">
<!--开发时在公司使用的数据库配置
id:就是提供给environments的default属性使用
-->
<environment id="development">
<!--配置事务管理器
type:指定事务的管理方式
JDBC:事务的控制交给程序员处理
MANAGED:由容器(spring)来管理事务
-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源
type:指定不同的配置方式
JNDI:java命名目录接口,在服务器端进行数据库连接池的管理
POOLED:使用数据库连接池
UNPOOLED:不使用数据库连接池
-->
<dataSource type="POOLED">
<!--private String driver;
private String url;
private String username;
private String password;
-->
<property name="driver" value="${jdbc.driverClassName}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</dataSource>
</environment>
</environments>
<!--注册mapper.xml文件
resource:从resources目录下找到指定名称的文件进行注册
url:使用绝对路径注册
class:动态代理方式下注册
-->
<mappers>
<mapper resource="studentMapper.xml"></mapper>
</mappers>
</configuration>
9.创建实体类Student,用来封装数据
package com.xin.entity;
public class Student {
private Integer id;
private String name;
private String email;
private Integer age;
public Student() {
}
public Student(String name, String email, Integer age) {
this.name = name;
this.email = email;
this.age = age;
}
public Student(Integer id, String name, String email, Integer age) {
this.id = id;
this.name = name;
this.email = email;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
10.添加完成学生表的增删改查的功能的StudentMapper.xml文件
<?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:是整个文件的大标签,用来开始和结束xml文件
属性:
namespace:指定命名空间(相当于包名),用来区分不同的mapper.xml文件中相同的id属性
-->
<mapper namespace="zar">
<!--完成查询全部学生的功能
List<Student> getAll();
parameterType:如果有参数,则通过它来指定参数的类型
resultType:指定查询返回结果集的类型,如果是集合,则返回的必须是泛型的类型
-->
<select id="getAll" resultType="student">
select id,name,email,age
from student
</select>
<!--
按主键id查询学生信息
Student getById(Integer id)
-->
<select id="getById" parameterType="int" resultType="student">
select id,name,email,age
from student
where id=#{id}
</select>
<!--
按学生名称模糊查询
List<Student> getByName(String name)
-->
<select id="getByName" parameterType="string" resultType="student">
select id,name,email,age
from student
where name like '%${name}%'
</select>
<!--
增加学生
int insert(Student stu)
实体属性
private Integer id;
private String name;
private String email;
private Integer age;
-->
<insert id="insert" parameterType="student">
insert into student(name,email,age) values(#{name},#{email},#{age})
</insert>
<!--
按主键删除删除学生
int delete(Integer id)
-->
<delete id="delete" parameterType="int">
delete from student where id=#{id}
</delete>
<!--
更新学生
int update(Student stu)
-->
<update id="update" parameterType="student">
update student set name=#{name},email=#{email},age=#{age}
where id=#{id}
</update>
</mapper>
11.创建测试类,进行功能测试
package com.xin.test;
import com.xin.entity.Student;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class MyTest {
SqlSession sqlSession;
@Before //在所有的@Test方法执行前先执行这段代码
public void openSession() throws IOException {
//使用文件流读取核心配置文件SqlMapConfig.xml
InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
//创建SqlSessionFactory工厂对象
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//取出SqlSession对象
sqlSession=factory.openSession();
}
@After
public void closeSqlSession() {
//关闭SqlSession
sqlSession.close();
}
/**
* 查询数据库中的学生信息
* @throws IOException
*/
@Test
public void testGetAll() throws IOException {
/*//使用文件流读取核心配置文件SqlMapConfig.xml
InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
//创建SqlSessionFactory工厂对象
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//取出SqlSession对象
SqlSession sqlSession=factory.openSession();*/
//完成查询操作
List<Student> list=sqlSession.selectList("zar.getAll");
list.forEach(student -> System.out.println(student));
/*//关闭SqlSession
sqlSession.close();*/
}
/**
* 根据学生id查询学生信息
* @throws IOException
*/
@Test
public void testById() throws IOException {
/*//读取核心配置文件
InputStream in=Resources.getResourceAsStream("SqlMapConfig.xml");
//创建SessionFactory工厂对象
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//取出SqlSession对象
SqlSession sqlSession=factory.openSession();*/
//按主键查学生
Student student=sqlSession.selectOne("zar.getById",1);
System.out.println(student);
/* //关闭SqlSession
sqlSession.close();*/
}
/**
* 模糊查询学生信息
* @throws IOException
*/
@Test
public void testGetByName() throws IOException {
/* //使用流读取核心配置文件
InputStream in=Resources.getResourceAsStream("SqlMapConfig.xml");
//创建SessionFactory工厂对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(in);
//取出SqlSession对象
SqlSession sqlSession=sqlSessionFactory.openSession();*/
//进行模糊查询
List<Student> list=sqlSession.selectList("zar.getByName","李");
list.forEach(student-> System.out.println(student));
/*//关闭SqlSession
sqlSession.close();*/
}
/**
* 增加学生
* @throws IOException
*/
@Test
public void testInsert() throws IOException {
/*InputStream in=Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession=sqlSessionFactory.openSession();*/
int num=sqlSession.insert("zar.insert",new Student("梨花","1111@qq.com",18));
System.out.println(num);
//切记切记切记:在所有的增删改后必须手动提交事务!!!设置手动提交
sqlSession.commit();
/*sqlSession.close();*/
}
/**
* 根据id删除学生信息
*/
@Test
public void testDelete() throws IOException {
/*InputStream in=Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession=sqlSessionFactory.openSession();*/
int num=sqlSession.delete("zar.delete",5);
System.out.println(num);
sqlSession.commit();
sqlSession.close();
}
/**
* 根据id修改学生信息
*/
@Test
public void testUpdate() throws IOException {
/*InputStream in=Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession=sqlSessionFactory.openSession();*/
int num=sqlSession.update("zar.update",new Student(3,"李名","3333@qq.com",17));
System.out.println(num);
sqlSession.commit();
/* sqlSession.close();*/
}
}
7.MyBatis对象分析
1.Resources类
就是解析SqlMapConfig.xml文件,创建出相应的对象
//使用文件流读取核心配置文件SqlMapConfig.xml
InputStream in=Resources.getResourceAsStream("SqlMapConfig.xml");
2.SqlSessionFactory接口
DefaultSqlSessionFactory是实现类
SqlSessionFactory是MyBatis中的一个重要的对象,它是用来创建SqlSession对象的,而SQLSession是用来操作数据库的。
SqlSessionFactory对象可以通过SqlSessionFactoryBuilder来获得,
而SqlSessionFactoryBuilder则可以从XML配置文件或预先定制的Configuration实例构建出SqlSessionFactory的实例。
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的,而 SqlSessionFactory 唯一的作用就是生产 MyBatis 的核心接口对象 SqlSession ,所以它的责任是唯一的。
//创建SqlSessionFactory工厂对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
3.SqlSession 接口
DefaultSqlSession实现类
默认的 openSession()方法没有参数,它会创建有如下特性的 SqlSession:
1.会开启一个事务(也就是不自动提交)。
2.将从由当前环境配置的 DataSource 实例中获取 Connection 对象。事务隔离级别将会使用驱动或数据源的默认设置。
3.预处理语句不会被复用,也不会批量处理更新。
//取出SqlSession对象
sqlSession=factory.openSession();
8.为实体类注册别名
<typeAliases>
<!--单个实体类注册别名-->
<!--
<typeAlias type="com.xin.entity.Student" alias="student"></typeAlias>
-->
<!--批量注册别名
别名时类名的驼峰命名法(规范)
-->
<package name="com.xin.entity"/>
</typeAliases>
9.设置日志输出
<!--设置日志,输出底层执行的代码-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
在控制台输出如下: