1、 框架概述
1.1 软件开发常用结构
1.1.1 三层架构
三层架构包含的三层:
界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)
三层的职责
- 界面层(表示层,视图层):主要功能是接受用户的数据,显示请求的处理结果。使用 web 页面和
用户交互,手机 app 也就是表示层的,用户在 app 中操作,业务逻辑在服务器端处理。 - 业务逻辑层:接收表示传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取数据。
- 数据访问层:与数据库打交道。主要实现对数据的增、删、改、查。将存储在数据库中的数据提交
给业务层,同时将业务层处理的数据保存到数据库。
三层处理请求的交互
为什么使用三层?
- 结构清晰、耦合度低, 各层分工明确
- 可维护性高,可扩展性高
- 有利于标准化
- 开发人员可以只关注整个结构中的其中某一层的功能实现
- 有利于各层逻辑的复用
1.1.1 常用框架
常见的J2EE中开发框架:
MyBatis 框架:
MyBatis 是一个优秀的基于 java 的持久层框架,内部封装了 jdbc,开发者只需要关注 sql 语句本身,而不需要处理加载驱动、创建连接、创建 statement、关闭连接,资源等繁杂的过程。
MyBatis 通过 xml 或注解两种方式将要执行的各种 sql 语句配置起来,并通过 java 对象和 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。
Spring 框架:
Spring 框架为了解决软件开发的复杂性而创建的。Spring 使用的是基本的 JavaBean 来完成以前
非常复杂的企业级开发。Spring 解决了业务对象,功能模块之间的耦合,不仅在 javase,web 中使用,
大部分 Java 应用都可以从 Spring 中受益。
Spring 是一个轻量级控制反转(IoC)和面向切面(AOP)的容器
SpringMVC 框架
Spring MVC 属于 SpringFrameWork 3.0 版本加入的一个模块,为 Spring 框架提供了构建 Web
应用程序的能力。现在可以 Spring 框架提供的 SpringMVC 模块实现 web 应用开发,在 web 项目中
可以无缝使用 Spring 和 Spring MVC 框架
1.2 框架是什么
1.2.1 框架定义
框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种认为,框架是可被应用开发者定制的应用骨架、模板。简单的说,框架其实是半成品软件,就是一组组件,供你使用完成你自己的系统。从另一个角度来说框架一个舞台,你在舞台上做表演。在框架基础上加入你要完成的功能。
框架安全的,可复用的,不断升级的软件。
1.2.2 框架解决的问题
框架要解决的最重要的一个问题是技术整合,在 J2EE 的 框架中,有着各种各样的技术,不同的应用,系统使用不同的技术解决问题。需要从 J2EE 中选择不同的技术,而技术自身的复杂性,有导致更
大的风险。企业在开发软件项目时,主要目的是解决业务问题。 即要求企业负责技术本身,又要求解
决业务问题。这是大多数企业不能完成的。框架把相关的技术融合在一起,企业开发可以集中在业务领域方面。另一个方面可以提供开发的效率
1.3 .1JDBC编程
@Test
public void select(){
Connection conn =null;
PreparedStatement ps =null;
ResultSet rs=null;
List<Student> stuList=null;
try {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库的基本信息,url,uname,password
String url="jdbc:mysql://localhost:3306/mybatis";
//若是本机数据库还可以这样写
String url2="jdbc:mysql:///mybatis";
String user="root";
String password="123456";
//3.创建连接对象
conn = DriverManager.getConnection(url2, user, password);
//4.创建sql语句
String sql="select * from student";
//5.获取PreparedStatement对象
ps = conn.prepareStatement(sql);
//6.执行查询,创建记录集
rs = ps.executeQuery(sql);
//7.遍历查询结果
//7.1保存查询结果
stuList=new ArrayList<>();
//7.2遍历
while (rs.next()){
Student stu=new Student();
stu.setId(rs.getInt("id"));
stu.setName(rs.getString("name"));
stu.setEmail(rs.getString("email"));
stu.setAge(rs.getInt("age"));
stuList.add(stu);
}
//遍历list查看
stuList.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭资源
try {
if(rs!=null){
rs.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if(ps!=null){
ps.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if(conn!=null){
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
1.3 .2 使用jdbc的缺陷
- 代码比较多,开发效率低
- 需要关注Connection,Statement,ResultSet对象创建和销毁
- 对ResultSet查询的结果,需要自己封装为List
- 重复的代码比较多
- 业务代码和数据库的操作混在一起
1.4 mybatis框架概述
MyBatis 框架:
MyBatis 本是 apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁移到了 google code,并且改名为 MyBatis 。
2013 年 11 月迁移到 Github。
iBATIS 一词来源于“internet”和“abatis”的组合,是一个基于 Java 的持久层框架。iBATIS 提供的
持久层框架包括 SQL Maps 和 Data Access Objects(DAOs)
当前,最新版本是 MyBatis 3.5.1 ,其发布时间是 2019 年 4 月 8 日
1.4.1 mybatis解决的主要问题
减轻使用 JDBC 的复杂性,不用编写重复的创建 Connetion , Statement ; 不用编写关闭资源代码。
直接使用 java 对象,表示结果数据。让开发者专注 SQL 的处理。 其他分心的工作由 MyBatis 代劳
mybatis可以完成:
- 注册数据库的驱动,例如 Class.forName(“com.mysql.jdbc.Driver”))
- 创建 JDBC 中必须使用的 Connection , Statement, ResultSet 对象
- 从 xml 中获取 sql,并执行 sql 语句,把 ResultSet 结果转换 java 对象
List<Student> list = new ArrayLsit<>();
ResultSet rs = state.executeQuery(“select * from student”);
while(rs.next){
Student student = new Student();
student.setName(rs.getString(“name”));
student.setAge(rs.getInt(“age”));
list.add(student);
}
- ResultSet.close() , Statement.close() , Conenection.close()
2、 mybatis入门案列
下面是演示,不懂的代码,后面有讲解。
1、创建mysql数据库和表
CREATE TABLE `student` (
`id` int(11) NOT NULL ,
`name` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.插入两条数据
3.创建maven工程,在pom.xml中加入maven坐标
maven的目录结构,如下:
在pom.xml中做如下的配置
<groupId>com.yongbin</groupId>
<artifactId>ch01-hello-mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
在maven工程下面的main下新建com.yongbin.dao
、com.yongbin.domain
两个包。在domain下创建Student类,student类的声明如下:记得提供set、get方法、toString
/**
* 推荐和表名一样,容易记忆
* @author 刘瘦瘦
* @create 2021-07-08-12:13
*/
public class Student {
//定义属性,目前要求属性名和列名一样
private Integer id;
private String name;
private String email;
private Integer age;
public Student() {
}
在com.yongbin.dao
包下,编写dao接口,StudentDao声明如下:
public interface StudentDao {
//查询student表的所有的数据
List<Student> selectStudents();
编写dao接口Mapper映射文件StudentDao.xml
要求
- 在dao包中创建文件StudentDao.xml
- 要StudentDao.xml文件名称和接口StudentDao一样
StudentDao.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">
<!--namespace可以自定义,但是要求使用接口的全限定路径-->
<mapper namespace="com.yongbin.dao.StudentDao">
<!--
select:表示查询操作
id:你要执行的sql语句的唯一标识,mybatis会使用这个id的值来找到要执行的sql语句
可以自定义,但是要求你使用接口中的方法名称。
resultType:表示结果类型的,是sql语句执行后得到ResultSet,遍历这个ResultSet得到java对象的类型
值写的是类型的全限定名称。
-->
<!--第一次配置时resultType写出了:com.yongbin.dao.StudentDao了,检查了好久错误-->
<select id="selectStudents" resultType="com.yongbin.domain.Student">
select id,name,email,age from student order by id
</select>
<!--插入操作
#{id},#{name},#{email},#{age}
相当于占位符的意思,里面一定是Student类中对应的属性,具体后面有详解。
-->
<insert id="insertStudent">
insert into student values(#{id},#{name},#{email},#{age})
</insert>
<!--<table></table>-->
</mapper>
<!--
sql映射文件:写sql语句的,mybatis会执行这些sql
1.指定约束条件
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
mybatis-3-mapper.dtd是约束文件的名称,扩展名是.dts的
2.约束文件作用:限制,检查在当前文件中出现的标签,属性必须符合mybatis的要求。
看我上面写的table就报错了。
3.mapper 是当前文件的根标签,必须的。
namespace:命名空间,唯一值的,可以是自定义的字符串。
要求你使用dao接口的全限定名称。
4.在当前文件中,可以使用特定的标签,表示数据库的特定操作。
<select>:表示执行查询,select语句
<update>:表示更新数据库的操作,就是在<update>标签中,写的是update sql语句
<insert>:表示插入,放的是insert语句
<delete>:表示删除,执行的是delete语句
-->
创建mybatis主配置文件
在maven的项目/src/main下创建resources目录,设置resource目录为resource.root
创建主配置文件,名称为mybatis.xml,该文件是自定义的,内容如下:
<?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>
<!--settings:控制mybatis全局行为-->
<settings>
<!--设置mybatis输出日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--环境配置:数据库的连接信息
default:必须和某个environment的id值一样。
告诉mybatis使用哪个数据库的连接信息。也就是访问哪个数据库
-->
<environments default="mydev">
<environment id="mydev">
<!--
transactionManager:mybatis的事务类型
type:JDBC(表示使用jdbc中的Connection对象的commit,rollback做事务处理)
-->
<transactionManager type="JDBC"/>
<!--
dataSource:表示数据源,连接数据库的
type:表示数据源的类型,POOLED表示使用连接池
-->
<dataSource type="POOLED">
<!--
driver、url、username、password是固定的,不能自定义。
-->
<!--数据库的驱动类名-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--连接数据库的url字符串-->
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<!--访问数据库的用户名-->
<property name="username" value="root"/>
<!--密码-->
<property name="password" value="123456"/>
</dataSource>
</environment>
<environment id="online">
<!--
transactionManager:mybatis的事务类型
type:JDBC(表示使用jdbc中的Connection对象的commit,rollback做事务处理)
-->
<transactionManager type="online"/>
<!--
dataSource:表示数据源,连接数据库的
type:表示数据源的类型,POOLED表示使用连接池
-->
<dataSource type="POOLED">
<!--
driver、url、username、password是固定的,不能自定义。
-->
<!--数据库的驱动类名-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--连接数据库的url字符串-->
<property name="url" value="jdbc:mysql://localhost:3306/onlidb"/>
<!--访问数据库的用户名-->
<property name="username" value="root"/>
<!--密码-->
<property name="password" value="fasdfa"/>
</dataSource>
</environment>
</environments>
<!--sql mapper(sql映射文件)的位置-->
<mappers>
<!--
一个mapper标签指定一个文件的位置。
从类路径开始的路径信息。 target/clasess(类路径):
-->
<mapper resource="com/yongbin/dao/StudentDao.xml"/>
<!--可以配置多个-->
<!--<mapper resource="com/yongbin/dao/StudentDao.xml"/>-->
</mappers>
</configuration>
<!--
mybatis的主配置文件:主要定义了数据库的配置信息,sql映射文件的位置
1.约束条件
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
mybatis-3-config.dtd:约束文件的名称
2.configuration 根标签
-->
在src/test/java/com/yongbin/创建MyBatisTest.java文件
//测试方法,测试功能
@Test
public void testSelectStudents() throws IOException {
//1.定义mybatis主配置文件的名称,从类路径的根开始(target/classes)
//一定检查target--》classes---》yongbin---》dao---》是否存在StudentDao.xml,没有的话加上build标签,否则
//报错:Error parsingSQLMapperConfiguration.Cause:java.io.IOException: Could not find resource dao/StudentDao.xml
String config="mybatis.xml";
//2.读取这个config表示的文件
InputStream in = Resources.getResourceAsStream(config);
//3.创建SQLSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
//4.创建SqlSessionFactory对象
SqlSessionFactory factory=builder.build(in);
//5.【重要】获取SqlSession对象,从SQLSessionFactory中获取
SqlSession sqlSession = factory.openSession();
//6.【重要】指定要执行的sql语句标识。 sql映射文件中的namespace+"."+ 标签的id值
String sqlId="com.yongbin.dao.StudentDao.selectStudents";
//7.执行sql语句,通过sqlId找到语句
List<Student> studentList = sqlSession.selectList(sqlId);
//8.输出结果
studentList.forEach(stu-> System.out.println(stu));
//9.关闭SQLSession对象
sqlSession.close();
}
@Test
public void testInsert() throws IOException {
//1.定义mybatis主配置文件的名称,从类路径的根开始(target/classes)
//一定检查target--》classes---》yongbin---》dao---》是否存在StudentDao.xml,没有的话加上build标签,否则
//报错:Error parsingSQLMapperConfiguration.Cause:java.io.IOException: Could not find resource dao/StudentDao.xml
String config="mybatis.xml";
//2.读取这个config表示的文件
InputStream in = Resources.getResourceAsStream(config);
//3.创建SQLSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
//4.创建SqlSessionFactory对象
SqlSessionFactory factory=builder.build(in);
//5.【重要】获取SqlSession对象,从SQLSessionFactory中获取
// SqlSession sqlSession = factory.openSession();
//自动提交事务的方法
SqlSession sqlSession = factory.openSession(true);
//6.【重要】指定要执行的sql语句标识。 sql映射文件中的namespace+"."+ 标签的id值
String sqlId="com.yongbin.dao.StudentDao.insertStudent";
//7.执行sql语句,通过sqlId找到语句
int rows = sqlSession.insert(sqlId, new Student(1004,"刘亦菲","yifei@qq.com",20));
//mybatis默认不是自动提交事务的,所以在insert,update,delete后要手动提交事务
// sqlSession.commit();
//8.输出结果
System.out.println("执行Insert的结果"+rows);
//9.关闭SQLSession对象
sqlSession.close();
}
如果maven工程下的target–》classes目录下没有mybatis.xml的话
运行上述的测试类会报如下的错误:
解决办法:在pom.xml中加入下面的build标签:
<!--src/main/java 和 src/test/java 这两个目录中的所有*.java 文件会分别在 comile 和 test-comiple 阶段被编译,编-->
<!--译结果分别放到了 target/classes 和 targe/test-classes 目录中,但是这两个目录中的其他文件都会被忽略掉,如果需-->
<!--要把 src 目录下的文件包放到 target/classes 目录,作为输出的 jar 一部分。需要指定资源文件位置。以下内容放到-->
<!--<buid>标签中-->
<build>
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<!--filtering 选项 false 不启用过滤器, *.property 已经起到过滤的作用了 -->
<filtering>false</filtering>
</resource>
</resources>
</build>
然后:
如果实在找不到mybatis,就自己手动复制到target–>classes下面。然后运行上述测试方法,结果如下:
2.1 mybatis对象分析
1、Resource类
Resources 类,顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返回不同类型的 IO 流对象。
2.SqlSessionFactoryBuilder
SqlSessionFactory 的 创 建 , 需 要 使 用SqlSessionFactoryBuilder 对 象 的 build() 方 法 。 由 于SqlSessionFactoryBuilder 对象在创建完工厂对象后,就完成了其历史使命,即可被销毁。所以,一般会将
该 SqlSessionFactoryBuilder 对象创建为一个方法内的局部对象,方法结束,对象销毁
3.SqlSessionFactory接口
SqlSessionFactory接口对象是一个重量级对象(系统开销大)
,是线程安全的,所以一个应用只需要一个该对象即可。创建SqlSession需要使用SqlSessionFactory接口的openSession方法。
openSession(true) | 创建一个有自动提交功能的SqlSession |
---|---|
openSession(false) | 创建一个非自动提交功能的SqlSession,需要手动提交 |
openSession() | 同openSession(false) |
4.SqlSession接口
SqlSession 接口对象用于执行持久化操作。一个 SqlSession 对应着一次数据库会话,一次会话以SqlSession 对象的创建开始,以 SqlSession 对象的关闭结束。SqlSession 接口对象是线程不安全的,所以每次数据库会话结束前,需要马上调用其 close()方法,将
其关闭。再次需要会话,再次创建。 SqlSession 在方法内部创建,使用完毕后关闭。
2.3 创建工具类
创建MyBatisUtil类
在src/main/java建一个叫做:com.yongbin.utils的包。里面新建一个MyBatisUtil的工具类,内容如下:
public class MyBaitsUtil {
private static SqlSessionFactory sqlSessionFactory=null;
static {
//需要和你的项目中的文件名一样
String config="mybatis.xml";
try {
InputStream in = Resources.getResourceAsStream(config);//加载一次就行
//创建SQLSessionFactory对象,使用SQLSessionFactoryBuild
sqlSessionFactory=new SqlSessionFactoryBuilder().build(in);//创建一个工厂就行
} catch (IOException e) {
e.printStackTrace();
}
}
//获取SQLSession的方法
public static SqlSession getSqlSession() throws IOException {
SqlSession sqlSession=null;
if(sqlSessionFactory !=null){
sqlSession=sqlSessionFactory.openSession();//非自动提交事务
}
return sqlSession;
}
}
使用MyBatisUtil工具类测试查询
//测试工具类的使用
@Test
public void testMyBaitsUtil() throws IOException {
SqlSession sqlSession = MyBaitsUtil.getSqlSession();
String sqlId="com.yongbin.dao.StudentDao.selectStudents";
List<Student> stuList = sqlSession.selectList(sqlId);
stuList.forEach(System.out::println);
}
}
2.4 实现添加的功能
在上面的StudentDao中增加插入方法,如下:
/**
* //操作student表
* @author 刘瘦瘦
* @create 2021-07-08-12:23
*/
public interface StudentDao {
//查询student表的所有的数据
List<Student> selectStudents();
/**
* 插入方法
* @param student
* @return 表示insert操作后,影响数据库的行数
*/
public int insertStudent(Student student);
}
在StudentDao.xml中的map标签中进行配置:注意此时我把namespace改成了a,select标签中的id改成了b
mybatis.xml主配置文件不变,只是把sqlId改为了:String sqlId="a.b
下面运行下面的单元测试方法:
@Test
public void testMyBaitsUtil() throws IOException {
//通过工具类获得sqlSession对象
SqlSession sqlSession = MyBaitsUtil.getSqlSession();
//通过sqlId找到要执行的sql语句
String sqlId="a.b";
int insert = sqlSession.insert(sqlId,new Student(1003,"galigaygay","galigaygay@qq.com",23));
//需要手动开启事务
sqlSession.commit();
System.out.println(insert);
}
查看结果:第一个绿框说明,默认mybatis的事务是没有提交的,第二个绿框是设置手动提交。
数据库的结果:
执行到这你有没有什么疑问呢?
1、我在StudentDao.xml中namespace='a'
,select标签中的id设置的为‘b’,我在测试的时候也能正常的插入数据,这说明这个StudentDao好像根本没有什么作用,而上述的String sql="a.b
的作用就是为了找到要执行的sql语句。
不需要StudentDao就可以执行sql语句,在开发中为啥还要需要StudentDao这个类呢?
mybatis使用传统的dao开发方式
传统的方式是有一个StudentDao接口,有一个StudentDaoImpl的实现类供给service层调用。
1、创建StudentDao接口:
/**
* //操作student表
* @author 刘瘦瘦
* @create 2021-07-08-12:23
*/
public interface StudentDao {
//查询student表的所有的数据
List<Student> selectStudents() throws IOException;
//插入学生信息
int insertStudent(Student student) throws IOException;
}
2、创建StudentDao接口的实现类StudentDaoImpl
public class StudentDaoImpl implements StudentDao {
//查询操作
@Override
public List<Student> selectStudents() throws IOException {
//获取SqlSession对象
SqlSession sqlSession= MyBaitsUtil.getSqlSession();
String sqlId="com.yongbin.dao.StudentDao.selectStudents";
//执行sql语句
List<Student> studentList = sqlSession.selectList(sqlId);
//关闭
sqlSession.close();
return studentList;
}
//插入操作
@Override
public int insertStudent(Student stu) throws IOException {
//获取SqlSession对象
SqlSession sqlSession= MyBaitsUtil.getSqlSession();
String sqlId="com.yongbin.dao.StudentDao.insertStudent";
//执行sql语句
int nums=sqlSession.insert(sqlId,stu);
//提交事务
sqlSession.commit();
//关闭
sqlSession.close();
return nums;
}
}
3.测试方法如下:
public class TestMyBatis {
//测试方法,测试查询功能
@Test
public void testSelectStudents() throws IOException {
StudentDao studentDao=new StudentDaoImpl();
List<Student> studentList = studentDao.selectStudents();
for(Student student : studentList){
System.out.println(student);
}
}
//测试方法,测试插入功能
@Test
public void testInsertStudent() throws IOException {
StudentDao studentDao=new StudentDaoImpl();
studentDao.insertStudent(new Student(1004,"changan","changan163.com",15));
}
}
因为实际中,我们需要StudentDao的实现类StudentDaoImpl对象,供service层调用,所以我们想要拥有StudentDao的实现类,必须有StudentDao的接口,但是,你看传统的dao开发所带来的的问题。
- 先创建SQLSession
- 再调用SqlSession的方法
- 在提交SqlSession
- 在关闭SqlSession
设想能否将这些重复代码提取出来,这些重复的代码就是模板代码–.>而且我们还想获得StudentDao的实现类对象,到这应该就想到动态代理了。
Mapper动态代理开发方式
开发规范
Mapper动态代理开发方式只需要程序员编写Mapper接口(相当于dao层的接口),由MyBatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体与上边dao层接口的实现类方法体相似。注意:Mapper动态代理开发需要遵循以下规定
5. Mapper.xml文件中的namespace与Mapper接口的类路径相同,即namepace必须是接口的全限定路径。
2.Mapper接口的方法名和Mapper.xml文件中定义的每个Statement的id相同。
6. Mapper接口方法的输入参数类型和Mapper.xml文件中定义的每个sql的parameterType的类型相同(这个可以不指定,mybatis会通过反射获得的)。
4.Mapper接口方法的输出参数类型和Mapper.xml文件中定义的每个Sql的resultType类型相同。
StudentDao接口的声明如下:
public interface StudentDao {
//查询student表的所有的数据
List<Student> selectStudents() throws IOException;
/**
* 插入一条学生记录到数据库中
* @param student
* @return 影响的行数
*/
int insertStudent(Student student);
}
StudentDao.xml(也叫sql映射文件)
<!--这时,namespace就必须是接口的全限定名称
id:必须是接口中的方法名
-->
<mapper namespace="com.yongbin.dao.StudentDao">
<select id="selectStudents" resultType="com.yongbin.domain.Student">
select id,name,email,age from student;
</select>
<insert id="insertStudent">
insert into student values(#{id},#{name},#{email},#{age})
</insert>
</mapper>
要想加载StudentDao.xml文件,需要在mybati主配置文件中加下面内容
那么mybati.xml主配置文件变成如下的形式:
<?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>
<!--settings:控制mybatis全局行为-->
<settings>
<!--设置mybatis输出日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--环境配置:数据库的连接信息
default:必须和某个environment的id值一样。
告诉mybatis使用哪个数据库的连接信息。也就是访问哪个数据库
-->
<environments default="mydev">
<environment id="mydev">
<!--
transactionManager:mybatis的事务类型
type:JDBC(表示使用jdbc中的Connection对象的commit,rollback做事务处理)
-->
<transactionManager type="JDBC"/>
<!--
dataSource:表示数据源,连接数据库的
type:表示数据源的类型,POOLED表示使用连接池
-->
<dataSource type="POOLED">
<!--
driver、url、username、password是固定的,不能自定义。
-->
<!--数据库的驱动类名-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--连接数据库的url字符串-->
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<!--访问数据库的用户名-->
<property name="username" value="root"/>
<!--密码-->
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--sql mapper(sql映射文件)的位置-->
<mappers>
<!--
一个mapper标签指定一个文件的位置。
从类路径开始的路径信息。 target/clasess(类路径):
-->
<mapper resource="com/yongbin/dao/StudentDao.xml"/>
<!--可以配置多个-->
<!--<mapper resource="com/yongbin/dao/StudentDao.xml"/>-->
</mappers>
</configuration>
编写测试程序:
**
* @author 刘瘦瘦
* @create 2021-07-08-13:59
*/
public class TestMyBatis {
//测试方法,测试功能
@Test
public void testSelectStudents() throws IOException {
/**
* 使用mabtis的动态代理机制,使用SqlSession.getMapper(dao接口)
* getMapper能获取dao接口对应的实现类对象
*/
SqlSession sqlSession=MyBaitsUtil.getSqlSession();
StudentDao dao=sqlSession.getMapper(StudentDao.class);
dao.selectStudents();
}
@Test
public void testInsertStudent() throws IOException {
/**
* 使用mabtis的动态代理机制,使用SqlSession.getMapper(dao接口)
* getMapper能获取dao接口对应的实现类对象
*/
SqlSession sqlSession=MyBaitsUtil.getSqlSession();
StudentDao dao=sqlSession.getMapper(StudentDao.class);
System.out.println(dao.getClass());
dao.selectStudents();
dao.insertStudent(new Student(1005,"安琪拉","anqila@qq.com",5));
sqlSession.commit();
}
}