• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

MyBatis学习总结

互联网 diligentman 4个月前 (12-14) 41次浏览

一. 三层架构

界面层: 和用户打交道的, 接收用户的请求参数, 显示处理结果的。(jsp ,html ,servlet)
业务逻辑层: 接收了界面层传递的数据,计算逻辑,调用数据库,获取数据
数据访问层: 就是访问数据库, 执行对数据的查询,修改,删除等等的。

三层对应的包

界面层: controller包 (servlet)
业务逻辑层: service 包(XXXService类)
数据访问层: dao包(XXXDao类)

三层中类的交互

用户使用界面层–> 业务逻辑层—>数据访问层(持久层)–>数据库mysql

三层对应的处理框架

界面层—servlet—springmvc(框架)
业务逻辑层—service类–spring(框架)
数据访问层—dao类–mybatis(框架)

二.框架

模版:
1. 规定了好一些条款,内容。
2. 加入自己的东西

框架特点:
1. 框架一般不是全能的, 不能做所有事情
2. 框架是针对某一个领域有效。 特长在某一个方面,比如mybatis做数据库操作强,但是他不能做其它的。
3. 框架是一个软件

三.mybatis框架

介绍: 一个框架,早期叫做ibatis, 代码在github。
mybatis是 MyBatis SQL Mapper Framework for Java (sql映射框架)
(1)sql mapper :sql映射
可以把数据库表中的一行数据 映射为 一个java对象。
一行数据可以看做是一个java对象。操作这个对象,就相当于操作表中的数据

(2) Data Access Objects(DAOs) : 数据访问 , 对数据库执行增删改查。

mybatis提供了哪些功能:

  1. 提供了创建Connection ,Statement, ResultSet的能力 ,不用开发人员创建这些对象了
  2. 提供了执行sql语句的能力, 不用你执行sql
  3. 提供了循环sql, 把sql的结果转为java对象, List集合的能力
    while (rs.next()) {
    Student stu = new Student();
    stu.setId(rs.getInt(“id”));
    stu.setName(rs.getString(“name”));
    stu.setAge(rs.getInt(“age”));
    //从数据库取出数据转为 Student 对象,封装到 List 集合
    stuList.add(stu);
    }
    4.提供了关闭资源的能力,不用你关闭Connection, Statement, ResultSet

开发人员做的是: 提供sql语句
最后是: 开发人员提供sql语句–mybatis处理sql—开发人员得到List集合或java对象(表中的数据)

总结:
mybatis是一个sql映射框架,提供的数据库的操作能力。增强的JDBC,使用mybatis让开发人员集中精神写sql就可以了,不必关心Connection,Statement,ResultSet的创建,销毁,sql的执行。

3.1 开发mybatis程序从步骤:

1.配置mybatis

(1)conf.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>
<!--通过environments的default值和environment的id来制定MyBatis运行时的数据库环境-->
	<environments default="development">
		<!--开发环境(自己的计算机)-->
		<environment id="development">
		<!--事务提交方式:
			JDBC:利用JDBC方式处理事务(commit rollback close)
			MANAGED:将事务提交由其他组件去托管(spring,jobss),默认会关闭连接。
		-->
		<transactionManager type="JDBC"/>
			<!--数据源类型:
				UNPOOLED:传统JDBC模式(每次访问数据库,均需要打开,关闭等数据库)
				POOLED:使用数据库连接池
				JNDI:从tomcat中获取一个内置的数据库连接池(数据库连接池-数据)
			-->
			<dataSource type="POOLED">
			<!-- 配置数据库信息 -->
			<property name="driver" value="oracle.jdbc.OracleDriver"/>
			<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:ORCL"/>
			<property name="username" value="scott"/>
			<property name="password" value="tiger"/>
		</dataSource>
		</environment>
	</environments>
	<mappers>
		<!-- 加载映射文件 -->
		<mapper resource="org/lanqiao/entity/personMapper.xml"/>
	</mappers>
</configuration>

注意事项:
如果使用的 事务方式为 jdbc,则需要 手工commit提交,即session.commit();

(2)映射文件personMapper.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 namespace="org.lanqiao.entity.personMapper">

	<!--mybatis约定:输入参数parameterType 和 输出参数resultType ,在形式上都只能有一个-->
	<select id="queryPersonById" resultType="org.lanqiao.entity.Person"  parameterType="int">
		select * from person where  id = #{id} 
	</select>		
</mapper>

输出参数: 如果返回值类型是一个 对象(如Student),则无论返回一个、还是多个,
resultType都写成org.lanqiao.entity.Student

(3)测试类:
session.selectOne(“需要查询的SQL的namespace.id”,“SQL的参数值”);

public class TestMyBatis {
	public static void main(String[] args) throws IOException {
		//加载MyBatis配置文件(为了访问数据库)
		Reader reader = Resources.getResourceAsReader("conf.xml") ;
		SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader) ;
		//session - connection
			
		SqlSession session = sessionFactory.openSession() ;
		String statement = "org.lanqiao.entity.personMapper.queryPersonById" ;
		Student person = session.selectOne( statement,1 ) ;
		System.out.println(person);
		session.close(); 	
	}

3.2 mapper动态代理方式的CRUD(MyBatis接口开发):

原则:约定优于配置
硬编码方式

abc.java
Configuration conf = new Configuration();
con.setName(“myProject”) ;

配置方式:

abc.xml
myProject

约定:默认值就是myProject

1.具体实现的步骤:

1.基础环境:mybatis.jar/ojdbc.jar、conf.xml、mapper.xml
2.(不同之处)
约定的目标: 省略掉statement,即根据约定 直接可以定位出SQL语句

a.接口,接口中的方法必须遵循以下约定:

  1. 方法名和mapper.xml文件中标签的id值相同
  2. 方法的 输入参数 和mapper.xml文件中标签的 parameterType类型一致 (如果mapper.xml的标签中没有 parameterType,则说明方法没有输入参数)
  3. 方法的返回值 和mapper.xml文件中标签的 resultType类型一致 (无论查询结果是一个 还是多个(student、List),在mapper.xml标签中的resultType中只写 一个(Student);如果没有resultType,则说明方法的返回值为void)

(List ),在mapper.xml标签中的resultType中只写 一个(Student);如果没有resultType,则说明方法的返回值为void)

package org.lanqiao.mapper;
import java.util.List;
import org.lanqiao.entity.Student;

//操作Mybatis的接口  需要和StudenetMapper.xml配置文件一个目录
public interface StudentMapper {

//		public abstract Student  queryStudentByStuno(int stuno);
		Student  queryStudentByStuno(int stuno);
		//查询全部
		List<Student> queryAllStudents();
		//增加
		void addStudentWithConverter(Student student);	
		
		void addStudent(Student student);
		//删除
		void deleteStudentByStuno(int stuno);
		
		//修改
		void updateStudentByStuno(Student student);
				
		Student queryStudentByStunoWithConverter(int stuno);

除了以上约定,要实现 接口中的方法 和 Mapper.xml中SQL标签一一对应,还需要以下1点:

  • namespace的值 ,就是 接口的全类名( 接口 – mapper.xml 一一对应)👴

匹配的过程:(约定的过程)

  1. 根据 接口名 找到 mapper.xml文件(根据的是namespace=接口全类名)
  2. 根据 接口的方法名 找到 mapper.xml文件中的SQL标签 (方法名=SQL标签Id值)

以上2点可以保证: 当我们调用接口中的方法时,程序能自动定位到 某一个Mapper.xml文件中的sqL标签

习惯:SQL映射文件(mapper.xml) 和 接口放在同一个包中 (注意修改conf.xml中加载mapper.xml文件的路径)

3.以上,可以通过接口的方法->SQL语句

执行:

StudentMapper studentMapper = session.getMapper(StudentMapper.class) ;
studentMapper.方法();

//可以通过build的第二参数 指定数据库环境
				SqlSessionFactory sessionFacotry = new SqlSessionFactoryBuilder().build(reader,"development") ;
				SqlSession session = sessionFacotry.openSession() ;
				
				StudentMapper studentMapper = session.getMapper(StudentMapper.class) ;
				Student student = studentMapper.queryStudentByStuno(2) ;//接口中的方法->SQL语句
				
				System.out.println(student);
				session.close();

通过session对象获取接口(session.getMapper(接口.class);),再调用该接口中的方法,程序会自动执行该方法对应的SQL。

四. 优化(属性文件,全局参数,别名,类型转换器,resultMap)

4.1 属性文件

可以将配置信息 单独放入 db.properties文件中,然后再动态引入

 db.properties:
	k=v
<configuration>
	<properties  resource="db.properties"/>
</configuration>

引入之后,使用${key}

4.2 MyBatis全局参数

在conf.xml中设置

<settings>
			<setting name="cacheEnabled" value="false"  />
			<setting name="lazyLoadingEnabled" value="false"  />
</settings> 

4.3 别名 conf.xml

<!-- 设置单个/多个别名 -->
	<typeAliases>
		<!-- 单个别名 (别名 忽略大小写) -->
		<typeAlias type="org.lanqiao.entity.Student" alias="student"/>
		<!--  批量定义别名  (别名 忽略大小写),以下会自动将该包中的所有类 批量定义别名: 别名就是类名(不带包名,忽略大小写)   -->
		<package name="org.lanqiao.entity"/>
	</typeAliases>

4.4 类型处理器(类型转换器)

1.MyBatis自带一些常见的类型处理器

  • int – number

2.自定义MyBatis类型处理器
java -数据库(jdbc类型)
示例:

  • 实体类Student : boolean stuSex
    true:男
    false:女

  • 表student: number stuSex
    1:男
    0:女

自定义类型转换器(boolean -number)步骤:

  • a.创建转换器:需要实现TypeHandler接口
    通过阅读源码发现,此接口有一个实现类 BaseTypeHandler ,因此 要实现转换器有2种选择:
    i.实现接口TypeHandler接口
    ii.继承BaseTypeHandler
  • b.配置conf.xml

4.5 resultMap可以实现2个功能:

1.类型转换
2.属性-字段的映射关系

<select id="queryStudentByStuno" 	parameterType="int"  	resultMap="studentMapping" >
	select * from student where stuno = #{stuno}
	<!--insert into student(stuno,stuname,stuage,graname,stusex) values(#{stuNo},#{stuName},#{stuAge},#{graName} ,#{stuSex ,javaType=boolean  ,jdbcType=INTEGER   } )-->
</select>
		
<resultMap type="student" id="studentMapping">
	<!-- 分为主键id 和非主键 result-->
	<id property="id"  column="stuno"  />
	<result property="stuName"  column="stuname" />
	<result property="stuAge"  column="stuage" />
	<result property="graName"  column="graname" />
	<result property="stuSex"  column="stusex"  javaType="boolean" jdbcType="INTEGER"/>
</resultMap>

4.6 两种取值符号,ParameterType输入参数类型

1.类型为简单类型(8个基本类型+String
#{} ${}

2.对比

#{} ${}
#{任意值} 里面可以是任意值 ${value} 期中的表示符只能是value
#{}自动给String类型加上 ’ '(自动类型转换) ${} 原样输出,但是适用于动态排列(动态字段)
#{} 可以防止SQL注入 ${} 不可防注入

相同:都可以获取对象的值,对象类型的时候,都需要${}#{} 写属性名

<!--mybatis约定:输入参数parameterType 和 输出参数resultType ,在形式上都只能有一个-->
	<select id="queryPersonById" resultType="org.lanqiao.entity.Person"  parameterType="int">
		select * from person where  id = #{id} //${value}
	</select>	


程序员灯塔
转载请注明原文链接:MyBatis学习总结
喜欢 (0)