2021-06-12

框架学习一点二:Mybatis的应用场景

1.Mybatis与Hibernate的区别:

Hibernate是一个标准的ORM(对象关系映射:Object Relation Mapper)框架,SQL语句自动生成,不需要写SQL语句,因此对SQL语句进行优化、修改比较困难。
应用:适用于需求变化不多的中小型项目。
Mybatis需要程序员自己编写、修改SQL语句,优化比较方便;Mybatis是一个不完全ORM框架;也可实现输入映射、输入映射。
应用:适用于需求变化较多的项目。
企业进行技术选型:以低成本高回报作为技术选型的原则,根据项目组的技术力量进行选择。

2.SqlMapConfig.xml的配置

SqlMapConfig.xml是Mybatis的全局配置文件,配置内容包括:数据库环境、mapper定义、全局参数设置等。
使用的标签:
	1.properties标签:将数据连接参数单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties的属性值,就不需要对数据库连接参数编码。
	将数据库连接参数只配置在db.properties中的原因:方便参数进行统一管理,其它xml可以引用该db.properties。
	db.properties内容:
#Oracle\u6570\u636E\u5E93\u7684\u9A71\u52A8\u7C7B
jdbc.driver=oracle.jdbc.OracleDriver
#Oracle\u6570\u636E\u5E93\u7684\u8FDE\u63A5\u8DEF\u5F84
jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl
#\u767B\u5F55\u7528\u6237\u540D
jdbc.user=MY
#\u767B\u5F55\u5BC6\u7801
jdbc.password=123456

在SQLMapConfig.xml中加载属性文件

<configuration>
	<!-- 加载属性配置文件(xx.properties)	resource属性:只能使用/连接路径 -->
	<properties resource="db.properties"></properties>	
	<!-- 配置数据源 -->
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" /><!-- 驱动类 -->
				<property name="url" value="${jdbc.url}" /><!-- 连接路径 -->
				<property name="username" value="${jdbc.user}" /><!-- 用户名 -->
				<property name="password" value="${jdbc.password}" /><!-- 密码 -->
			</dataSource>
		</environment>
properties标签特性:
	注意Mybatis按照顺序加载属性:
		在properties元素体内定义的属性首先被读取,然后读取properties元素中的resource或url加载属性,它会覆盖已读取的同名属性;最后读取parameterType传递的属性,它会覆盖已读取的同名属性。
		所以,通过parameterType传递的属性具有最高优先级,resource或url加载的属性次之,最低优先级是properties元素体内定义的属性。

2.setting标签
	mybatis框架运行设置一些全局配置参数,(setting全局参数 配置文档)设置全局参数会影响mybatis框架运行,谨慎设置

3.typeAliases标签
	设置别名。在mapper.xml中配置好多SQL语句,也需要定义许多statement,statement需要parameterType指定输入参数类型,需要resultType指定输出结果的映射类型。若指定类型时输入类的全路径不方便开发,可以针对parameterType或resultType指定的类型定义一些别名,在mapper.xml中通过别名定义,方便开发。

Mybatis默认支持的别名:
	别名         映射的类型        别名           映射的类型  
	_byte       	byte        _double    		double
	_long       	long        _float         	float
	_short     	    short       _boolean  		boolean
	_int          	int         string        	String
	_integer        int        	byte            Byte
	long         	Long       	float           Float
	short           Short      	boolean         Boolean
	int             Integer    	date            Date
	integer         Integer     decimal         BigDecimal
	double          Double      bigdecimal	    BigDecimal
	自定义别名:
	(1)单个别名定义
<!-- 别名定义标签:给实体类设置别名  映射配置文件中的parameterType和resultType可以使用-->
	<typeAliases>
		<!-- 单个类进行别名定义 type属性:实体类的类路径  alias属性:别名定义-->
		<typeAlias type="com.it.model.User" alias="user"/>
		<!-- package标签:批量别名定义  name属性:实体类所在的包名  自动别名定义	mybatis会自动扫描该包下的所有的类进行别名定义,别名为类名(大小写都可以)-->
		<package name="com.it.bean"/>
	</typeAliases>
4.mapper标签
(1)通过resource加载单个映射文件 <mapper resource=" "/>
		使用相对路径的资源
(2)通过url加载单个映射文件  			<mapper url=" "/>
		使用完全限定路径
(3)通过mapper接口加载映射文件	<mapper class=" "/>
		使用mapper接口类路径	
		注意:此方法要求mapper接口名称和mapper映射文件名称相同,且放在同一目录中。
(4)批量加载mapper
		指定mapper接口的包名,mybatis自动扫描包下 所有mapper接口进行加载
		注意:此方法要求mapper接口名称和mapper映射文件名称相同,且放在同一目录下。
(5)typeHandlers(类型处理器)
		Mybatis中类型处理器用于java类型和jdbc类型转换;Mybatis提供的类型处理器满足日常需求,不需要自己定义。

3.输入映射

通过parameterType指定输入参数的类型,类型可以是简单类型,HashMap哈pojo的包装类型。
1.传递pojo包装对象
	(1)需求:完成用户信息的综合查询,需要传入的查询条件可能很复杂(可能包括用户信息、其他信息)
	(2)定义包装类型pojo:针对上边的需求,建议使用自定义包装类型pojo,在自定义包装类型的pojo中将复杂的查询条件包装进去
public class Order {
	private int id;//订单编号
	private String ordertime;//订单时间
	private double total;//订单总价
	private int uid;//用户编号
	
	private User user;//当前订单信息属于哪个用户

	@Override
	public String toString() {
		return "Order [id=" + id + ", ordertime=" + ordertime + ", total=" + total + ", uid=" + uid + /*", user="
				+ user + */"]";
	}
	public User getUser() {
		return user;
	}
	public void setUser(User user) {
		this.user = user;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getOrdertime() {
		return ordertime;
	}
	public void setOrdertime(String ordertime) {
		this.ordertime = ordertime;
	}
	public double getTotal() {
		return total;
	}
	public void setTotal(double total) {
		this.total = total;
	}
	public int getuid() {
		return uid;
	}
	public void setuid(int uid) {
		this.uid = uid;
	}
}
(3)OrderMapper.xml:
<!-- 查询订单信息以及相关用户 -->
	<select id="selectOrderAndUser" resultMap="orderAndUser">
		select o.*,u.id userid,u.username,u.birthday,u.password from orders o, tuser u where o.userid=u.id
	</select>
(4)OrderMapper.java
import java.util.List;
import com.it.bean.Order;
public interface OrderMapper {
	/**
	 * 查询订单信息以及相关用户信息
	 * */
	public List<Order> selectOrderAndUser();
}
(5)测试代码
public class Crud {
	@Test
	public void selectOrderAndUser() throws IOException{
		//加载全局配置文件
		Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
		//创建会话工厂
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
		//打开会话
		SqlSession session = factory.openSession();
		//获取Mapper接口的代理方法
		OrderMapper mapper= session.getMapper(OrderMapper.class);
		//调用响应方法
		List<Order> orders = mapper.selectOrderAndUser();
		for(Order order:orders){
			System.out.println(order);
		}
		//关闭会话
		session.close();
	}
}

4.输入映射

resultType:
1.resultType输出pojo对象:
	使用resultType进行输出映射,只有查询出来的字段名和pojo中的属性名一致,该列才可以映射成功
	若查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象
	只要查询出来的列名和pojo中的属性名有一个一致,就会创建pojo对象
2.resultType输出简单类型
	需求:查询出来的结果集只有一行并且只有一列,可以使用简单数据类型进行输出映射
3.resultType输出HashMap类型
	当多表查询时,可以使用HashMap进行输出映射,查询的字段名即为Map集合的key值,字段值为Map集合的value值。
	
resultMap
1.使用方法:如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性之间做一个映射关系。
a)定义resultMap
<!-- 定义resultMap
	查询出的字段名和实体类中的属性名不一致时,借助resultMap来完成字段和属性之间的映射
		type:表示映射成的Java对象类型,可以使用别名
		id属性:表示当前resultMap的唯一标识
	 -->
	<resultMap type="user" id="resultMap1">
		<!-- id属性用来表示主键和实体类中唯一的属性
			column属性表示查询出的字段名
			property属性要映射到实体类中的属性名
		 -->
		 <id column="id_" property="id"/>
		 <result column="loginname_" property="loginname"/>
		 <result column="password_" property="password"/>
		 <result column="realname_" property="realname"/>
		 <result column="sex_" property="sex"/>
		 <result column="birthady_" property="birthday"/>
		 <result column="dep_" property="dep"/>
		 <result column="email_" property="email"/>
		 <result column="enabled_" property="enabled"/>
		 <result column="createman_" property="createman"/>
	</resultMap>
b)使用resultMap作为statement的输出映射
<!-- 使用resultMap属性 -->
	<select id="login" parameterType="java.util.Map" resultMap="resultMap1">
	<!-- 若参数类型为Map集合时,#{}中写的是map集合中的key值 -->
		select id id_, loginname loginname_,password password_,realname realname_, sex sex_,birthday birthday_,dep dep_,email email_,enabled enabled_, createman createman_,last_login_time last_time from tuser where loginname=#{loginname} and password = #{password}
	</select>
c)测试
@Test
	public void login() throws IOException{
		//加载全局配置文件
		Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
		//根据全局配置文件来创建回话工厂
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
		//根据会话工厂来创建会话对象
		SqlSession session = factory.openSession();
		//获取Mapper接口的代理对象
		UserMapper mapper = session.getMapper(UserMapper.class);
		//创建Map集合
		Map<String, String> loginCondition = new HashMap<>();
		loginCondition.put("loginname", "xiaoli");
		loginCondition.put("password", "123456");
		//调用相应的登录方法
		User user = mapper.login(loginCondition);
		System.out.println(user);
		//关闭事务
		session.close();
	}

5.动态SQL

1。什么是动态SQL:Mybatis核心对SQL语句进行灵活操作,通过表达式进行判断,对SQL进行灵活拼接,组装。
2.需求:对查询条件进行判断,如果输入参数不为空才进行查询条件拼接。
3.Mapper.xml
<!-- 使用动态SQL语句查询用户信息 -->
	<select id="selectUserByDncSql" parameterType="user" resultType="user">
		select * from tuser
		<where>
			<!-- 判断查询条件 -->
			<!-- 判断是否根据用户名模糊查询 
				where标签会自动去掉第一个满足条件的and
			-->
			<if test="loginname!=null and loginname!=''">
				and loginname like '%${loginname}%'
			</if>
			<!-- 判断是否可用查询用户 -->
			<if test="enabled!=0 and enable!=null">
				and enable=#{enable}
			</if>
		</where>
	</select>
4.测试
@Test
	public void selectUserByDncSql() throws IOException{
		//加载全局配置文件
		Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
		//根据全局配置文件来创建回话工厂
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
		//根据会话工厂来创建会话对象
		SqlSession session = factory.openSession();
		//获取Mapper接口的代理对象
		UserMapper mapper = session.getMapper(UserMapper.class);
		//若传null,为全查
		//List<User> users = mapper.selectUserByDncSql(null);
		User user1 = new User();
		user1.setLoginname("a");
		List<User> users = mapper.selectUserByDncSql(user1);
		for(User user:users){
			System.out.println(user);
		}
		//关闭事务
		session.close();
	}
5.sql片段
	(1)将以实现的sql代码块抽取出来,组成一个SQL片段;其它的statement中就可以引用这个sql片段。
	(2)定义SQL片段
<sql id="userColumns">
	id, loginname,password,realname, sex,birthday,dep,email,enabled, createman,last_login_time
</sql>
(3)引用SQL片段:在mapper.xml文件的statement中引用SQL片段
	<select id="selectUserById" parameterType="int" resultType="user">
		<!-- include标签:引用 -->
		select <include refid="userColumns"></include> from tuser where id = #{id}
	</select>
6.foreach
	向sql传递数组或List,mybatis使用foreach解析
(1)需求在用户查询列表中根据多个id批量删除用户信息
(2)使用数组进行批量删除和集合的方式
在输入参数类型中添加多个id
/**
	 * 批量删除用户信息
	 * 使用数组的方式
	 * */
	public int batchDeleteUsers(int[] ids);
	/**
	 * 批量删除用户信息
	 * 使用集合的方式
	 * */
	public int batchDeleteUsers1(List<Integer> ids);
(3)修改mapper.xml
	<!-- 批量删除 -->
	<delete id="batchDeleteUsers">
		delete from tuser
		<where>
			<!--Mapper接口方法中的参数为数组类型,就写array -->
			<if test="array!=null">
				<!-- foreach标签适用于遍历参数类型为数组或集合的 collection属性:若Mapper接口方法中的参数为数组类型,固定写array 
					for(int id:array){}
					ids={3,27,281}
					delete from tuser where id in(3,27,281)
					item属性:表示每遍历一个对象属性赋值给哪个属性
					open属性:开始遍历时拼接的SQL字符串
					separator属性:表示两个对象之间的分隔符
					close属性:表示结束遍历时拼接的SQL字符串
				-->
				<!-- <foreach collection="array" item="id" open="id in (" separator="," close=")">
					#{id}
				</foreach> -->
				<!-- delete from tuser where id = 3 or id = 27 or id = 281 -->
				<foreach collection="array" item="id" separator=" or ">
					id=#{id}
				</foreach> 
			</if>
			<!-- 说明数组为空(必须加,否则全删)说明不删除任何用户信息 -->
			<if test="array==null">
				1=2
			</if>
		</where>
	</delete>
<!-- 批量删除2 通过集合-->
	<delete id="batchDeleteUsers1">
		delete from tuser
		<where>
			<if test="list!=null">
				<foreach collection="list" item="id" open="id in (" separator="," close=")">
					#{id}
				</foreach>
			</if>
			<if test="list == null">
				2=3
			</if>
		</where>
	</delete>
(4)测试
/**
	 * 批量删除用户
	 * 通过数组的方式
	 * */
	@Test
	public void batchDeleteUsers() throws IOException{
		//加载全局配置文件
		Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
		//根据全局配置文件来创建回话工厂
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
		//根据会话工厂来创建会话对象
		SqlSession session = factory.openSession();
		//获取Mapper接口的代理对象
		UserMapper mapper = session.getMapper(UserMapper.class);
		
		int[] ids={4,8};
		int result = mapper.batchDeleteUsers(ids);
		System.out.println("已删除"+result+"条记录。");

		//上传事务
		session.commit();
		//关闭事务
		session.close();
	}
	/**
	 * 批量删除用户
	 * 通过集合的方式
	 * */
	@Test
	public void batchDeleteUsers1() throws IOException{
		//加载全局配置文件
		Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
		//根据全局配置文件来创建回话工厂
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
		//根据会话工厂来创建会话对象
		SqlSession session = factory.openSession();
		//获取Mapper接口的代理对象
		UserMapper mapper = session.getMapper(UserMapper.class);
		List<Integer> ids = new ArrayList<>();
		ids.add(4);
		ids.add(231);
		int result = mapper.batchDeleteUsers1(ids);
		System.out.println("已删除"+result+"条记录。");
		//上传事务
		session.commit();
		//关闭事务
		session.close();
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值