MyBatis

框架

ORM对象关系映射

MyBatis是ORM框架,作用是以面向对象的方式完成数据库操作。ORM框架有MyBatis、Hibernate、SpringJPA。

原始JDBC的缺陷:

MyBatis:

介绍:

小结:MyBatis封装了JDBC,是Java用来操作数据库的框架,只需要关注SQL语句本身,且能自动实现Java类和数据库的映射。

使用步骤:

1.准备数据

2.导jar包,添加到路径

3.src目录下创建映射配置文件、核心配置文件

映射配置文件:

第一行文档声明,第二行约束(什么是约束:配置了mybatis的约束那么写的文档不符合mybatis的规则就会报错):

mapper标签(核心根标签):

配置SQL语句的标签:

结果封装成Student对象,resultType就是student;

参数是student对象的一个属性,parameterType就是该属性类型,

参数是student对象的多个属性,要传递一个student对象,parameterType就是student。

核心配置文件:

第一行第二行依然是文档声明、约束;

第三行是核心根标签:

这里引入数据库连接的配置文件,下面配置数据库环境时用$ { 键名 }来获取连接配置,而不会写死。

起别名,在映射配置文件中就可以不用写全类名,写别名就行了。MyBatis自带的别名:int,string,double,long,boolean。

起别名<package>标签指定整个配置文件的全类名的包名,设置<package>标签后写类名就不用写全类名了,只写类名小写。

 

environments标签里可以有多个environment标签,<environments default="mysql">指定默认环境配置是id为"mysql"的environment标签。

MyBatis测试:

DaoImpl类的findAll()方法:

Resources用的是org.apache.ibatis.io包下的,因为MyBatis前身名字叫ibatis:

执行SQL语句时,通过 名称空间.标签id 找到SQL语句。

 

MyBatis相关API:

true开启自动提交事务后,增删改涉及到事务操作就不需要我们自己来了。

 

 

映射配置文件

手动提交事务:

自动提交事务:

核心配置文件

配置数据库环境、引入映射配置文件、配置一些工具。

 

LOG4J

LOG4J配置文件只关注第一条,输出级别,debug及以上的级别都输出,stdout标准输出(控制台)。

 

MyBatis接口代理方式实现Dao层

1.名称空间和Dao接口全类名相同:

2.SQL标签id和Dao接口方法名相同:

3.SQL标签parameterType属性和Dao接口方法参数相同:

4.SQL标签resultType属性和Dao接口方法返回值:

实现Service层

传统方式是Service层调用Dao层实现类,现在没有Dao层实现类了,所以Service层要重新写:

@Override
public List<Student> selectAll() {
	List<Student> list = null;
	SqlSession sqlSession = null;
	InputStream is = null;
	try{
		//1.加载核心配置文件
		is = Resources.getResourceAsStream("MyBatisConfig.xml");

		//2.获取SqlSession工厂对象
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

		//3.通过工厂对象获取SqlSession对象
		sqlSession = sqlSessionFactory.openSession(true);

		//4.获取StudentMapper接口的实现类对象
		StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl();

		//5.通过实现类对象调用方法,接收结果
		list = mapper.selectAll();

	} catch (Exception e) {

	} finally {
		//6.释放资源
		if(sqlSession != null) {
			sqlSession.close();
		}
		if(is != null) {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	//7.返回结果
	return list;
}

注意:用MyBatis的接口代理来获取动态代理对象(Dao接口实现类对象),调用操作方法。

使用JDK的动态代理技术实现接口代理。

 

动态SQL

<if>

为了应对查询条件不确定的情况。

<where>标签用来代替WHERE关键字,<if>标签如果test满足了,就会把标签内的SQL语句拼接上:

这样传入一个domain对象,不作为查询条件的属性不赋值(默认null),就可以实现任意查询条件查询。

MyBatis没有if-else结构,有

<choose>内是个整体,<when><otherwise>相当于if-else,如果想嵌套,那么应该把<choose>一个整体嵌套在<when>或者<otherwise>里。

<foreach>

为了应对传入多个id查询多条数据。

参数是list,是id的集合;

<foreach>标签的属性:collection是要遍历的集合,

open是要拼接的SQL片段的开始,close是结束,

item="id"是collection里拿出的元素赋值给<foreach>内的局部变量id,

separator是拼接上的分隔符。

<sql>

抽取sql语句,重复使用。(就像模板)

抽取:

使用:

 

MyBatis多表操作

一对一

在任一表中设置外键。如IDCard表和Person表,在IDCard表中存储外键pid记录对应Person的id。

<select>标签,因为现在涉及两个表,不能用resultSet指定一个映射的实体类,要用resultMap。

现在是card和person一对一,card设置外键,实体类中card中保存person对象,即person类是被包含的类。

<resultMap>标签,id是唯一标识,用来被<select>标签引用,type是映射的实体类(存有外键的)。

<id>标签是card表主键的映射关系,column是列名,property是card实体类属性名。

<result>标签是card表非主键的映射关系,column是列名,property是card实体类属性名。

<association>标签是被包含类(person被包含在card里)的映射关系,property是被包含类在card类中的属性名,javaType是被包含类的类名。(如果Card类里有个Person p,那么property="p",javaType="person");

        <id>是外键表的主键映射关系,column是列名,property是person实体类属性名。

        <result>标签是card表非主键的映射关系,column是列名,property是person实体类属性名。

一对多

一个班级对应多个学生,学生表中有外键记录班级的id,注意:学生类中没有班级类对象作为属性,班级类中有学生类对象的集合,因此一对多关系里面,多的一方作为被包含类。

和一对一的区别仅在于设置被包含类映射的标签换成了<collection>,property是班级类里学生集合的属性名,resultMap

多对多

一个学生对应多个课程,一个课程也对应多个学生,增加中间表实现多对多。注意:采取课程类作为被包含类,学生类里有课程类对象的集合。

映射配置文件中的实现方式和一对多完全一样,只不过查询语句变了、一的一方变成学生类、多的一方变成课程类。

 

注解开发代替映射配置文件

使用映射配置文件的缺点是麻烦,还要编写映射配置文件,<mapper>的namespace还要和Dao层接口的全类名相同。

使用注解大好处是简化开发操作,省去了编写映射配置文件。

核心配置文件

这里用引入映射配置文件了,而是指定Dao层接口的包名。

带注解定义接口方法

Seivice层实现方法

方法传入stu对象,会从里面提取id、name、age等属性:

 

注解多表操作

一对一

一个card对应一个person,一个person也对应一个card,card表中有外键pid,Card类中有Person成员变量。

核心配置文件配置映射关系:(可以写Dao层接口所在目录的父目录,只要其下有那些映射接口,就都能找到)   

Dao层card接口,带注解声明方法:

因为是多表操作,所以没法完成自动映射,除了@Select注解还要写@Results注解,@Results是个父注解,参数是个数组,包含多个子注解,每个子注解指定card类每个成员变量的映射关系。

column是列名,property是成员变量名,和映射配置文件的写法类似。

Card类里的Person成员变量(被包含类)的映射就复杂一些,property是被包含对象的变量名,javaType是被包含对象的类型,column是外键名(即根据查出的card表中的pid字段再去查询person表),one是被包含对象,one = @one是一对一注解的固定写法,select指定再调用哪个接口方法去映射出一个Person对象。

刚才指定的接口在这:

这里只设计单表操作,因此只写@Select,能自动映射。

Service层方法:

一对多

一个学生对应一个班级,一个班级对应多个学生,学生表中有外键记录班级id,班级类中有学生类集合记录所有学生。

Dao层映射接口:只需要把javaType换成List.class,对另一个表查询用many = @Many:

Service层方法:

多对多:

一个学生对应多个课程,一个课程也对应多个学生,添加中间表实现多对多。学生类里有课程类集合。

Dao层student映射接口:和一对多完全一样,因为多对多本来就是通过和中间表的一对多来实现的。

查询语句如果直接写SELECT * FROM STUDENT;的话,会把没有课程的学生也查询出来,其实我们只看有课程的学生,因此用多表查询限制一下。

Dao层course映射接口:

根据student的id调用此方法查询对应的课程,用的是课程表和中间表多表查询:

Service层方法:

 

ORM框架缓存:

一级缓存:SQLSession级缓存,默认开启,记录和数据库交互的session会话的数据,SQLSession生命周期很短,在交互玩一次就完了,

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值