一、框架概述
1、软件开发常用的结构
1、三层框架
包括:界面层User Interface layer ,业务逻辑层(Business Logic Layer),数据访问层(Data access layer)
2、三层界面的职责
- 界面层(表示层、视图层)主要功能是接受用户数据,显示请求的处理结果。使用web页面和用户交互,手机app也是表示层,用户在app层操作,业务逻辑在服务器中处理(controller包,servlet、jsp)
- 业务逻辑层,接受表示传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取数据(Service类)
- 数据访问层,与数据库打交道,主要负责对数据库的增删改查,将存储在数据库的数据提交给业务层,同时将业务层的数据保存在数据库
三层的处理请求的交互
用户——界面层——业务逻辑层——数据访问层——DB数据库
三层框架对应的处理框架
界面层——servlet——springmvc
业务逻辑层——service类——spring框架
Mybatis
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
实现步骤:
- 新建student表
- 加入maven的mybatis坐标、mysql坐标
- 创建实体类,Student,属性要与Student数据库表的属性一致
- 创建持久层的dao接口,定义操作数据库的方法
- 创建一个mybatis使用的配置文件
- 这个文件称为sql映射文件,用于书写sql语句,一般一个表一个sql映射文件,此文件为xml文件
- 创建mybatis的主配置文件
- 一个项目就一个主配置文件
- 主配置文件提供了数据库的连接信息,和sql映射文件的位置信息
- 创建使用mybatis类
- 通过Mybatis访问数据库
基本实现代码
maven配置
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
</dependency>
student类
package com.mayfly.domain;
import java.util.Date;
public class Student {
//注意属性名需要和表的字段名一致,否则将无法产生映射关系
//解决方法,使用别名访问数据库,需要在对应的mybatis配置文件中设置
private int id = 0;
private String name = null;
private String sex = null;
private String birth = null;
private String department = null;
private String address = null;
public Student() { super.() }
@Override
public String toString() {
return "student{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", birth=" + birth +
", department='" + department + '\'' +
", address='" + address + '\'' +
'}';}
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 String getSex() { return sex; }
public void setSex(String sex) { this.sex = sex; }
public String getBirth() { return birth; }
public void setBirth(String birth) { this.birth = birth; }
public String getDepartment() { return department; }
public void setDepartment(String department) { this.department = department; }
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
}
StudentDao接口
//接口操作Student表
public interface StudentDao {
//查询student表的所有的数据
public List<Student> selectStudents();
}
StudentDao对应的Mybatis配置文件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">
<!--sql映射文件
1,约束文件:mybatis-3-mapper.dtd"
2,约束当前文件中出现的标签,属性必须符合mybatis规范
3,mapper是当前文件的根标签,
4,namespace命名空间,必须是唯一的值,可以自定义,但是一般最好是dao接口的全限定名称
-->
<!--操作数据库的标签:
<select>,表示执行查询,
<update>更新
<insert>插入
<delect>删除
-->
<mapper namespace="com.mayfly.dao.StudentDao">
<!--id可以自定义,但是一般要求要与dao的方法名一致,如果使用动态代理,则id名必须和接口的方法名一致0-->
<!--查询返回,使用一个类保存数据-->
<select id="selectStudents" resultType="com.mayfly.domain.Student">
select * from student order by id
</select>
</mapper>
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">
<!--mybatis-3-config.dtd是Mybatis的约束文件,做约束认证-->
<configuration>
<settings>
<!--设置mybatis日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--定义别名,解决类属性和表格字段名不一致的方法-->
<typeAliases>
<!--可以指定一个类型的自定义别名
type:自定义类型的全限定名称
aliaes:别名
-->
<typeAlias type="com.mayfly.domain.Student" alias="stu"/>
<typeAlias type="com.mayfly.vo.ViewStudent" alias="vstu"/>
</typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>
<environments default="mydev">
<environment id="mydev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3308/book?serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--指定sql mapper(SQL)映射文件的路径-->
<mappers>
<!--一个mapper标签表示一个mapper配置文件的位置,默认是从编译后的classes往下-->
<mapper resource="com/mayfly/dao/StudentDao.xml"/>
</mappers>
</configuration>
测试类
@Test
public void testFindAll() throws IOException {
//访问Mybatis读取student数据库
//1,定义mybatis主要配置文件的名称,类的根路径开始(target/classes)
String config = "mybatis.xml";
//2,读取这个config表示的文件
InputStream in = Resources.getResourceAsStream(config);
//3,创建SqlSessionhFactoryBuiler对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//4,创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
//5,获取SqlSeeion对象,从SqlSession中获取SqlSession
SqlSession sqlSession = factory.openSession();
//6,指定要执行的sql语句标识, sql映射文件namesapce+“.”+标签的id值
String sqlId = "com.mayfly.dao.StudentDao" + "." + "selectStudents";
//7,遍历出查询结果
List<Student> studentList = sqlSession.selectList(sqlId);
//studentList.forEach(stu -> System.out.println(stu));
for (Student stu : studentList) {
System.out.println("查询的学生=" + stu);
}
//关闭sqlSession的session连接
sqlSession.close();
}
查询方法
插入方法
insert、update、delete默认不是自动提交事务,需要手动设置
代码
//接口操作Student表
public interface StudentDao {
//通过数据(通过类对象)
//参数:students,表示需要插入到数据库的数据
//返回值:int,表示执行insert操作后的返回值,表示插入的行数,插入一行就返回1
public int insertStudent(Student student);}
<!--mapper -->
<insert id="insertStudent">
<!--#{...}内对应的student的属性名,注意不要写错-->
insert into student values(#{id},#{name},#{sex},#{birth},#{department},#{address});
</insert>
测试方法
@Test
public void testInsert() throws IOException {
String config = "mybatis.xml";
InputStream in = Resources.getResourceAsStream(config);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession sqlSession = factory.openSession(true);
String sqlId = "com.mayfly.dao.StudentDao" + "." + "insertStudent";
Student student = new Student();
Calendar calendar = Calendar.getInstance();
calendar.set(1996, 0, 0);
Date date = calendar.getTime();
SimpleDateFormat SimpleDateFormat = new SimpleDateFormat("YYYY");
String birth = SimpleDateFormat.format(date.getTime());
student.setId(7);
student.setName("关羽");
student.setSex("男");
student.setBirth(birth);
student.setDepartment("计算机");
student.setAddress("河南");
int studentList = sqlSession.insert(sqlId, student);
//studentList.forEach(stu -> System.out.println(stu));
//MyBatis默认不会自动提交事务,需要手动设置
sqlSession.commit();
System.out.println(studentList);
sqlSession.close();
}
设置mybatis的输出日志
<!--在mybatis的主配置文件中设置-->
<settings>
<!--设置mybatis日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
主要类的介绍
Resources
Mybatis中的一个类,主要用来读取配置文件
//2,读取这个config表示的文件
InputStream in = Resources.getResourceAsStream(config);
SqlSessionFactory
重量级对象,程序创建一个对象耗时比较长,使用资源比较多,在整个项目中,有一个就已经足够。一般设置为静态对象
SqlSeesionFactory接口
接口实现类:DefaultSqlSessionFactory
SqlSessionFactory作用,获取SqlSession对象。
SqlSession sqlSession =factory.openSession();
openSession()方法使用说明
- openSession() :无参数的, 获取是非自动提交事务的SqlSession对象
2. openSession(boolean): openSession(true) 获取自动提交事务的SqlSession.
openSession(false) 非自动提交事务的SqlSession对象
SqlSession接口
定义了操作数据的方法,例如 selectOne() ,selectList() ,insert(),update(), delete(), commit(), rollback()。
SqlSession接口的实现类:DefaultSqlSession。
使用要求:
SqlSession对象不是线程安全的,需要在方法内部使用, 在执行sql语句之前,使用openSession()获取SqlSession对象。<br /> 在执行完sql语句后,需要关闭它,执行**SqlSession.close().** 这样能保证他的使用是线程安全的。
动态代理
动态代理:使用SqlSession.getMapper(dao接口.class)获取dao这个接口的对象
Mybatis的动态代理:mybatis根据dao方法的调用,执行sql语句的信息,自动根据dao接口,创建出一个dao接口的实现类,并创建这个实现类的对象,
/*
* 实际开发中使用的模式:
* 使用myBatis的动态代理机制,使用sqlSession.getMapper(dao接口)
* getMapper可以获取dao接口对应的实现类对象
* 前提:mapper.xml配置文件的namepace要对应的dao类的全限定名称,id需要对应具体方法名、
* 相当于我们写了StudentDao的实现类。StudentDaoImp
* */
//查询
@Test
public void testFindAll4() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Student> studentList = dao.selectStudents();
for (Student stu : studentList) {
System.out.println("学生信息:" + stu);
}
//查看dao对象类型,结果显示属于jdk的动态代理
//System.out.println("dao="+dao.getClass().getName());
}
传入参数
从java代码中把数据传入mapper文件的sql语句中
- parameterType:写在mapper 文件中的一个属性,表示dao接口中方法的参数的数据类型
例如:StudentDao接口public Student selectStudentById(Integer id)
<!--parameterType设置参数数类型。通过文档查询别名--> <select id="selectStudentsId" parameterType="java.lang.Integer" resultType="com.mayfly.domain.Student"> select * from student where id=#{id}; </select>
@Test public void testSelectStudenId(){ SqlSession sqlSession = MyBatisUtils.getSqlSession(); StudentDao studentDao = sqlSession.getMapper(StudentDao.class); Student student = studentDao.selectStudentsId(1); System.out.println("数据:" + student); }