SSM之Mybatis框架

最近在学SSM框架,现在来简单介绍一下,SSM里的mybatis框架。


首先来介绍一下ORM

1.ORM简介

Object Relational Mapping:对象关系映射。

简单的理解:ORM是通过使用描述对象和数据库之间的映射关系的 元数据, 将程序中的对象自动的持久化到关系型数据库中。

SSH里的hibernate和SSM里的mybatis都是ORM框架


其次来简单介绍了一下传统的jdbc,毕竟mybatis的出现就是来代替TA的

2.传统的JDBC

传统的jdbc的操作流程:

  • 加载驱动
  • 获取连接connection
  • 获取预处理对象statement
  • 设置sql(采用占位符,防止sql注入)
  • 给占位符设置值
  • 执行获取结果集
  • 对结果集进行封装
  • 释放资源

在传统的jdbc中存在了一些问题:

  1. 频繁的创建连接、释放资源、造成了系统资源的浪费。(数据库连接池可以解决这个问题)
  2. sql语句在Java代码中,造成后期维护不易
  3. 占位符设置值存在硬编码。where 语句里的条件不固定,造成维护不易
  4. 对结果集的解析封装存在硬编码

以上的问题在mybatis里都可以得到比较好的解决⬇⬇⬇

3.mybatis架构

mybatis架构是一个ORM框架,是一个基于Java的持久化框架。

mybatis会对jdbc的操作过程进行封装,使得卡法这只需要关注SQL本身,而无需花费精力去注册驱动获取连接设置参数结果数据分析释放资源等工作。可以简化jdbc开发成本

 


4.mybatis环境搭建

  1. 新建Java项目,导入jar包 mybatis-3.2.7.jar   和 junit(用来测试)
  2. 配置log4j.properties    打印日志
  3. 配置mybatis全局配置文件   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>
<!-- 运行环境:与spring整合后就不需要了
default:运行哪个环境,里面是id -->
	<environments default="mysql">
		<environment id="mysql">
			<!--事务管理  -->
			<transactionManager type="JDBC"></transactionManager>
			<!-- 数据源 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver"/>
			    	<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=utf-8"/>
				<property name="username" value="root"/>
				<property name="password" value="root"/>
			</dataSource>
		</environment>
	</environments>
	
	<!-- 加载映射文件 -->
	<mappers>
		<mapper resource="UserMapper.xml"/>
	</mappers>
</configuration>

5.入门案例

1.创建一个pojo对象类

	private int id;
	private String username;

    // getter
    // setter

    //toString --- 便于在控制台打印查看信息

2.映射文件 mapper.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的作用:分割sql,也就在调用这个文件的时候来认证 -->
<mapper namespace="UserMapper">
	<!-- 入门程序:根据id查询用户信息
		id:唯一的(本namespace下唯一),用于标识映射文件的sql,成为statement的id
		parameterType:输入参数类型;支持的类型包括java基本类型、pojo对象、hashmap
		resultType:输出结果类型;指定为单挑记录的类型
		#{}:占位符  注意:如果输入的参数类型是基本类型,则#{}里面可以是任意参数。或者是#{value}
	 -->
	 
	<select id="selectById" parameterType="int" resultType="user">
		select * from user where id = #{id}
	</select>
</mapper>

3.测试用例

	private SqlSession sqlSession;
	
	@Before
	public void init() throws IOException {
		// 初始化、加载环境、创建会工厂、获取会话
		// 1.加载mybatis的运行环境 io流的方式去读取全局配置文件
		InputStream is = Resources.getResourceAsStream("mybatis.xml");
		// 2.创建会话工厂
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
		// 3.获取会话,要通过会话来进行操作数据库
		sqlSession = sqlSessionFactory.openSession();
	}

	@Test
	public void selectById() {
        // 4.操作数据库
        // 第一个参数:statement的id 具体执行的sql  写法:namespace.id(具体sql语句的id)
        // 第二个参数:值
		User user = sqlSession.selectOne("UserMapper.selectById",1);
		System.err.println(user);
	}

	@After
	public void after() {
        // 释放资源
		sqlSession.close();
	}

6.会话工厂与会话

SqlSessionFactory:会话工厂。通过全局配置文件创建的,由SqlSessionFactoryBuild对象创建。

作用:创建会话

特点:会话工厂一旦创建,就会在应用程序的执行期间一直存在。我们不需要重复的来创建会话工厂,所以,应该将会话工厂的实现方式设计为单例模式

SqlSession: 会话。 

作用:操作数据库的

特点:线程不安全的。应该把会话声明为局部的。


 7.全局配置文件的其他配置

1.起别名(两种方式)

	<!-- 起别名 -->
	<typeAliases>

        <!-- 方法一 -->
		<!-- type:指的是要被定义别名的类的 全限定名 -->
		<!-- <typeAlias type="com.cbb.pojo.User" alias="user"/> -->
		
        <!-- 方法二 -->
		<!-- 批量起别名
			会扫描配置的包下的所有的类,然后,批量的起别名。别名为类型(首字母大写或者小写都可以) -->
		<package name="com.cbb.pojo"/>
	</typeAliases>

2.加载外部资源

资源文件 db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

全局配置文件 mybatis.xml 里面加载外部资源文件

	<!-- 加载资源文件 -->
	<properties resource="db.properties"></properties>

	<environments default="mysql">
		<environment id="mysql">
			<!--事务管理  -->
			<transactionManager type="JDBC"></transactionManager>
			<!-- 数据源 -->
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}"/>
				<property name="url" value="${jdbc.url}"/>
				<property name="username" value="${jdbc.username}"/>
				<property name="password" value="${jdbc.password}"/>
			</dataSource>
		</environment>
	</environments>

8.动态代理实现

传统的dao开发方法:dao接口、 daoImpl实现

与之相比

动态代理的实现:mapper接口、映射文件mapper.xml

只需要程序员编写Mapper接口(相当于dao接口),和映射文件,由 mybatis框架根据 接口 来创建接口的动态代理 对象,来代理接口方法的实现(类似于传统dao开发方式中的实现类)

规范要求:

  1. mapper.xml映射文件 和 mapper接口的名字 必须一致。
  2. mapper.xml映射文件的 namespace 与 接口 的类全路径相同
  3. mapper.xml映射文件的 statement的id 与 接口的方法名相同
  4. mapper.xml映射文件 的参数类型parameterType 与 接口方法的 参数类型相同
  5. mapper.xml映射文件 的输出结果类型 与 接口方法的 返回类型相同

可以在全局配置文件里批量加载 映射文件

	<!-- 加载映射文件 -->
	<mappers>
		<!-- 批量加载包下的映射文件 -->
		<package name="com.cbb.mapper"/>
	</mappers>

9.servlet与mybatis整合

与servlet整合,其实主要需要更改的地方便是serviceImpl里的代码实现,不再是通过实例化dao对象来调用方法,而是直接通过会话获取代理对象,然后来调用方法。

注意一点:如果是对数据库进行新增修改删除,在关闭会话之前记得调用commit方法,否则数据库里的数据不会改变

public class UserServiceImpl implements UserService{
	
	private SqlSessionFactory factory = SqlSessionFactoryUtil.getSqlSessionFactory();//获取单例模式的会话工厂

	@Override
	public User selectById(int id) {
		SqlSession session = factory.openSession();
		UserMapper userMapper = session.getMapper(UserMapper.class);//获取代理对象
		User user = userMapper.selectById(id);//方法调用
		session.close();//是否资源  如果是新增、修改、删除,关闭前记得要 调用 commit方法
		return user;
	}

}

10.Mapper.xml详解

mapper.xml  - - 映射文件

1.parameterType(输入类型)

  • java简单类型  int、String    占位符的形式  #{任意字符}
  • pojo自定义对象   #{pojo的属性名}
  • hasmap

2.resultType(输出类型)

  • Java简单类型的
  • pojo自定义对象
  • hashmap

3.resultMap

resultType:在指定pojo对象接收映射的结果集时,需要将pojo对象,需要要将pojo对象的属性名和数据库表的字段名要一致。如果有不一致的,则查询的字段为null

解决问题不一致的方法:

方案一:给sql查询的字段 as 别名,别名与pojo的属性名一致

<!-- 方案一:给sql查询的字段 as 别名, 别名和pojo对象的属性名一致 -->        
SELECT  carId carId, `name` carName , userId userId  from car

方案二:

使用resultMap

注意一点:如果使用resultMap来处理这种简单的 名字不一致的问题的时候,可以在resultMap里只配置这个名字不一致的字段,名字一致的可以省略掉。

	<!-- 
		type:把结果集映射到哪个对象上
		<id/>:结果集的主键 唯一标识
		<result/>:结果集的普通字段
			column:表的字段名
			property:pojo对象的属性名
			column和property	在一起表示之间的映射关系
	 -->
	 <!-- 可以只设置名字不一样的字段 -->
	<resultMap type="Car" id="CarMap">
		<id column="carId" property="carId"/>
		<result column="name" property="carName"/>
		<result column="userId" property="userId"/>
	</resultMap>

	<!-- resultMap:对应自定义的 哪个resultMap 的id -->
	<select id="selectAll" resultMap="CarMap">
		select * from car;
	</select>

resultMap:除了能够解决名字不一致的问题之外,还可以解决复杂的pojo问题。

	<resultMap type="UserVo" id="UserVoMap">
		<id column="id" property="id"/>
		<result column="username" property="username"/>
		<result column="sex" property="sex"/>
		<result column="birthday" property="birthday"/>
		<result column="address" property="address"/>
		
		<!-- 一对多集合 ofType:集合的类型 -->
		<collection property="car" ofType="Car">
			<id column="carId" property="carId"/>
			<result column="name" property="carName"/>
			<result column="userId" property="userId"/>
		</collection>
		
		
	</resultMap>


11.动态SQL 

通过mybatis提供的各种标签方法实现动态拼接sql

1.where条件的拼接,if用例

  •  if: 语句判断, <if test=""> 使用and进行合并 
  •  where: 去除多余的and 或者是 or , 所以在每一个条件句之前都加一个 and
	<!-- 动态sql:if用例 -->
	<select id="selectIf" parameterType="map" resultType="User">
		select * from user
		<where>
			<if test="sex!=null and  sex!=''">
				and sex = #{sex}
			</if>
			<if test="address!=null and address!=''">
				and address like concat("%", #{address}, "%")
			</if>
		</where>
	</select>

2.更新语句,set : 能去除多余的逗号(,), 所以在每个条件语句之后都加一个逗号即可

	<!-- set -->
	<update id="updateUser" parameterType="User">
		update user
		<set>
			<if test="username!=null and username!=''">
				username = #{username},
			</if>
			<if test="sex!=null and sex!=''">
				sex = #{sex},
			</if>
			<if test="address!=null and address!=''">
				address = #{address},
			</if>
		</set>
		<where>
			id = #{id}
		</where>
	</update>

3.foreach循环,以批量删除为例

   foreach里各种属性的含义:

        collection:集合的类型,可以是list(list集合) /  array(数组)   /    map / pojo包装类中的属性名
        item:循环中的当前对象
        open:循环的开始
        close:循环的结束
        separator:分割符

	<!-- foreach:批量删除
		collection:集合的类型,可以是list(list集合) /  array(数组)   /    map / pojo包装类中的属性名
		item:循环中的当前对象
		open:循环的开始
		close:循环的结束
		separator:分割符
	  -->
	<delete id="deleteBatch" parameterType="int">
		delete from user where id in
		<foreach collection="list" item="id" open="(" close=")" separator=",">
			#{id}
		</foreach>
	</delete>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值