05-2 mybatis框架

【输入映射和输出映射】


 1. 输入类型 parameterType
    简单类型:int
    pojo对象:自己写的,成员属性和数据库字段一一对应,有getset方法的类
    pojo包装对象:QueryVo类,依赖pojo对象

package com.bwf.bean;

import java.util.ArrayList;
import java.util.List;

public class QueryVo {

	private User user;
	
	private List<Integer> list2 = new ArrayList<>();
	
	private Integer[] array = null;
	

	public Integer[] getArray() {
		return array;
	}

	public void setArray(Integer[] array) {
		this.array = array;
	}

	public List<Integer> getList2() {
		return list2;
	}

	public void setList2(List<Integer> list) {
		this.list2 = list;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
	
	
	
}

 

 2. 输出类型
    简单类型
    pojo对象
    pojo列表

 3. resultMap

resultMap是Mybatis最强大的元素,它可以将查询到的复杂数据(比如查询到几个表中数据)映射到一个结果集当中。

例子:如果我要查询所有订单,并附带相关的用户信息

注意:此时的pojo类里的用户id(userId)和数据库表里的用户id(user_id)并不一样,不改pojo类的属性名和数据库字段名的情况下,那么就可以使用resultmap

<resultMap id="ordersRm" type="Orders">
        <result property="userId" column="user_id" />
    </resultMap>

    <!-- 查询所有订单 -->
    <select id="queryAll" resultMap="ordersRm">
        SELECT * FROM orders
    </select>

复杂一点的resultmap在后面有讲

vo,dto和po的含义(不是同一个):

【动态SQL】

 想根据条件搜索用户, 可以根据id 或名字 或生日 或性别 或地址 或任意组合搜索

这些都是基于OGNL 的表达式

 1. if

在动态 SQL 中所做的最通用的事情是包含部分 where 字句的条件。比如:


	<select id=”findActiveBlogWithTitleLike” parameterType=”Blog”
		resultType=”Blog”>
		SELECT * FROM BLOG
		WHERE state = „ACTIVE‟
		<if test=”title ! null ”>
			AND title like #{title}
		</if>
	</select>


这条语句会提供一个可选的文本查找功能。如果你没有传递 title,那么所有激活的博客
都会被返回。但是如果你传递了 title,那么就会查找相近的 title(对于敏锐的检索,这中情
况下你的参数值需要包含任意的遮掩或通配符)的记录。
 

 2. Where

where 元素知道如果由被包含的标记返回任意内容,就仅仅插入“WHERE”。而且,如
果以“AND”或“OR”开头的内容,那么就会跳过 WHERE 不插入。

<!-- 动态SQL -->
	<!-- 根据条件搜索用户 -->
	<select id="selectUserBy" parameterType="User" resultType="User">
		<include refid="selectFromUser"></include>
		<where>
			<if test="id != null">
				id = #{id}
			</if>
			<if test="username != null">
				 AND username = #{username}
			</if>
			<if test="sex != null">
				 AND sex = #{sex}
			</if>
			<if test="address != null">
				 AND address = #{address}
			</if>
		</where>
	</select>

 3. sql片段

这个元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。比如:

<sql id="selectFromUser">
		SELECT id,username,birthday,sex,address FROM user
	</sql>

这个 SQL 片段可以被包含在其他语句中,例如:

<select id="selectByName" parameterType="QueryVo" resultType="User">
		<include refid="selectFromUser"></include>
		WHERE username LIKE "%"#{user.username}"%"
	</select>

 4. foreach

foreach 元素是非常强大的,它允许你指定一个集合,声明集合项和索引变量,它们可
以用在元素体内。它也允许你指定开放和关闭的字符串,在迭代之间放置分隔符。这个元素
是很智能的,它不会偶然地附加多余的分隔符。
注意:你可以传递一个 List 实例或者数组作为参数对象传给 MyBatis。当你这么做的时
候,MyBatis 会自动将它包装在一个 Map 中,用名称作为键。List 实例将会以“list”
作为键,而数组实例将会以“array”作为键

<!-- 查询指定id的用户集合 -->
	<select id="queryByIds" resultType="User">
		<include refid="selectFromUser"></include>
		WHERE id IN
		<foreach item="item" index="index" collection="list2"
			open="(" separator="," close=")">
			#{item}
		</foreach>
		
	</select>
	
	
	<select id="queryByIds2" resultType="User">
		<include refid="selectFromUser"></include>
		WHERE id IN
		<foreach item="item" index="index" collection="array"
			open="(" separator="," close=")">
			#{item}
		</foreach>
		
	</select>

定义的接口方法:

        List<User> queryByIds(List<Integer> list);
	List<User> queryByIds(QueryVo vo);
	List<User> queryByIds2(Integer[] ids);
	List<User> queryByIds2(QueryVo vo);

 

【Mybatis整合spring】

以后再学

 

【表和表的三种关系】


 看的是记录的对应关系

1.一对多
 一对多 - 用户对订单
 多对一(一对一) 订单对用户

 做法: 
表结构设计:多方设置外键指向一方主键

用户表(一方)   订单表(多方)
 Idname iduid
1张三 1    
             
                          
1
  2李四21
  32

 

 

 

 

 

 

 

实体类

     User{
        private int id;
        private String name;
        // 一对多关系
        private List<Order> orders;
     }

     Order{
        private int id;
        // 一对一关系    
        private User user;

    }

 2.双向一对一

(本质就是一张表,但是拆成了两张)
 用户表            用户自我介绍表
 id name age         id 自我介绍

     User{
        id
        name 
        age 
        自我介绍
    }

 3.多对多

学生表             课程表
 张三     高等数学
 李四     微积分
 王五   计算机


  

 

 

 

 表结构设计

学生表中间表(选课表)课程表
 idsnamesidlididlname
1张三111高等数学
2李四122微积分
3王五233计算机

 

 

 

 

 


对象设计
    

Student{
        private int id;
        private String sname;

        // 多对多 -> 一对多
        private List<Lesson> lList;

    }

    Lesson{
        private int id;
        private String lname;

        // 多对多 -> 一对多
        private List<Student> sList;
    }

    两个成员保留哪个取决于业务要求


【关联查询】


 1. 一对一

每一条订单记录对应一个用户

用mybatis就可以很好的获取数据,真的吗?

    <select id="queryById" parameterType="int" resultMap="order_user">
		SELECT o. *, u.username, u.birthday, u.sex, u.address 
		FROM orders o, user u
		WHERE o.user_id = u.id
		AND o.id = #{id};
    </select>

结果发现打印出的tostring方法里面,user为空,为什么呢?

因为mybatis并不知道user表的id和orders表的userid是外键映射关系,所以就需要再添加一个resultmap建立两者之间的映射关系

<!-- 一对一  -->
	
	<resultMap type="Orders" id="order_user">
		<id property="id" column="id"/>
		<result property="number" column="number"/>
		<result property="createtime" column="createtime"/>
		<result property="note" column="note"/>
		<association property="user" column="user_id" javaType="User">
			<id property="id" column="user_id"/>
			<result property="username" column="username"/>
			<result property="birthday" column="birthday"/>
			<result property="sex" column="sex"/>
			<result property="address" column="address"/>
		</association>
	</resultMap>

 

 2. 一对多

每一个用户对应多条订单,写法如下


	<!-- 多对多  -->
	<resultMap type="User" id="user_order">
		<id property="id" column="id"/>
		<result property="username" column="username"/>
		<result property="birthday" column="birthday"/>
		<result property="sex" column="sex"/>
		<result property="address" column="address"/>
		<collection property="orders" ofType="Orders">
			<id property="id" column="oid"/>
			<result property="number" column="number"/>
			<result property="createtime" column="createtime"/>
			<result property="note" column="note"/>
		</collection>
	</resultMap>
	
	<select id="queryUserAndOrderByUid" parameterType="int" resultMap="user_order">
		SELECT u.* , o.id oid, o.number, o.createtime, o.note 
		FROM user u LEFT JOIN orders o
		ON u.id = o.user_id 
		WHERE u.id = #{id}
	</select>

 

【逆向工程】

因为有了逆向工程的存在,我们不需要手动写pojo类,mapper映射文件和接口了,大大提高了开发速度.
通过已知的数据库表,逆向生成该表对应的pojo类,mapper映射xml文件和接口

暴力入门:

1.导入项目generatorSqlmapCustom

2.修改generatorConfig.xml文件

配置连接数据库参数

		<jdbcConnection driverClass="com.mysql.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/crm_ssm" userId="root"
			password="root">
		</jdbcConnection>

配置生成的pojo类存放到哪个包中

		<!-- targetProject:生成PO类的位置 -->
		<javaModelGenerator targetPackage="com.wowowo.bean"
			targetProject=".\src">
		<!-- 中间的属性略,暂时用不到 -->	
		</javaModelGenerator>

配置mapper映射文件的生成位置
 

 <!-- targetProject:mapper映射文件生成的位置 -->
		<sqlMapGenerator targetPackage="com.wowowo.mapper" 
			targetProject=".\src">
			<!--  略 -->
		</sqlMapGenerator>

配置mapper接口生成的位置

		<!-- targetPackage:mapper接口生成的位置 -->
		<javaClientGenerator type="XMLMAPPER"
			targetPackage="com.wowowo.mapper" 
			targetProject=".\src">
			<!-- 略 -->
		</javaClientGenerator>

指定数据库表

<!-- 指定数据库表 -->
		<table schema="" tableName="cst_linkman"></table>

3.运行GeneratorSqlmap类

 

注意:逆向工程生成的mapper映射文件和接口不存在limit查询的sql语句,但是可以手动添加

生成的持久化对象中(POJO),多了一个xxxExample.java类,这个类是用来[构造复杂的筛选条件],通俗点讲就是[专门用来封装自定义查询条件],等会会介绍他的使用方法。

摘自:https://www.cnblogs.com/whgk/p/7140638.html

a.在example类中添加以下属性和getset方法:

这2个属性是limit的2个参数

	protected Integer off;
	protected Integer len;

	public Integer getOff() {
		return off;
	}

	public void setOff(Integer off) {
		this.off = off;
	}

	public Integer getLen() {
		return len;
	}

	public void setLen(Integer len) {
		this.len = len;
	}

b.在xml文件中的id=selectByExample的sql标签中添加以下基于OGNL 的表达式

    <!-- 注意:xml文件的空格,&&等字符无法直接显示,需要用转义字符来表达 -->
    <!-- &amp表示& -->
    <if test="off!=null &amp;&amp; len!=null">
        limit #{off} ,#{len}
    </if>

逆向工程中生成的mapper对象的方法

查询

按照主键查找对应记录

selectByPrimaryKey(传入一个主键参数);
返回一条记录

按照一定条件查询(模糊查询:),用到了exampe(查询条件对象)

        
        //这里以customer表,模糊查询custName字段带百记录的为例        
        //封装查询条件的对象在该类(xxxExample)中,所以先构造该对象
        CstCustomerExample example = new CstCustomerExample();
        //通过example的对象获取封装查询条件的对象Criteria
        Criteria criteria = example.createCriteria();
        //构建查询条件,这里使用方法将其内部实现封装了,其实做的事情就是在
        //sql语句的where后面加入: and name like "%百%"
        criteria.andCustNameLike("%" + "百" + "%");
        //调用查询方法,传入查询条件example。
        //构建查询条件,相当于在语句最后跟上where custIndustry= "教育行业"
        criteria.andCustIndustryEqualTo("教育行业");
        List<CstCustomer> poList = customerMapper.selectByExample(example);
        //按照一定条件查询记录总数,如果传入空参,那么默认查询该表所有记录总数
        CstCustomerExample example = new CstCustomerExample();
        Criteria criteria = example.createCriteria();
        int count=countByExample(example);

 

除此之外还有很多查询条件方法,就不一一列举了.

修改:

updateByPrimaryKeySelective :只更新model中不为空的字段

updateByPrimaryKey:将model中为空的字段也置为NULL

注意:在html中,某个text如果不填入值, 那么其实这个属性值只是长度为0,并不是空,这导致了我测试以上2个修改方法时发现效果是一样的.如果非要测试,那么可以把update方法作如下修改:

	@Override
	public void update(CstLinkman linkman) {
		if(linkman.getLkmPhone().length()<=0){
			linkman.setLkmPhone(null);
		}
		System.out.println(linkman);
		linkmanMapper.updateByPrimaryKeySelective(linkman);
		//linkmanMapper.updateByPrimaryKey(linkman);
	}

添加

insert:只插入model中不为空的字段

insertSelective:所有字段都添加一遍即使没有值

删除:

deleteByExample(example):模糊删除

deleteByPrimaryKey(主键):根据主键删除

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值