2020-11-12-Mybatis

框架

1.什么是框架?
	他是我们软件开发中的一套解决方案,不同的框架解决的时不同的问题
	使用框架的好处:
		框架封装了很多细节,使开发者可以使用极简的方式实现功能。大大提高开发效率
2.三层架构
	1.表现层
	2.业务层
	3.持久层
3.持久层解决方案
	JDBC技术:
			Conection
			PrepareStatement
			ResultSet
	Spring的JdbcTemplate
			pring中对jdbc的简单封装
4.mybatis概述
	mybatis是一个持久层的框架。
	它封装了许多jdbc的细节,使开发者只关注sql语句的编写,而不用关注注册驱动,获取连接,创
	建链接等繁杂操作。它使用了ORM的思想实现了结果集的封装
	ORM:
		object relational mapping
		简单的说就是把数据库表中数据及其字段和java类及其属性对应起来,实现数据库数据的封装

mybatis入门

入门

5.mybsatis的入门
	mybatis的环境搭建
		1.创建maven工程,导入mybatis的jar包,和jdbc的java包
		2.创建实体类和Dao接口
		3.创建mybatis的主配置xml文件,配置驱动,连接,url等参数
		4.创建映射配置xml文件,获取接口类,写入sql语句
6.环境搭建的注意事项
	1.创建UserDao.xml和UserDao.java时名称是为了和我们之前的知识保持一致。
		在mybatis中他把持久层操作接口名称和映射文件也叫Mapper
		所以UserDao和UserMapper是一致的
	2.在idea中创建目录时,他和包是不一样的
		在包创建时:com.itheima.dao是三级目录
		目录在创建时:com.itheima.dao是一级目录
		因此我们在创建UserDao.xml时一定要一个目录一个目录的创建
	3.myatis的映射配置文件的位置必须和包结构相同
	4.映射配置文件里的mapper标签的namespace属性的取值必须是dao接口的全限定类名
	5.映射配置文件里的select的id属性必须是dao接口中的方法名
	当我们遵从了三四五点之后,我们在开发中就不用再写dao接口的实现类了
7.Tset
	import com.itheima.dao.UserDao;
	import com.itheima.domain.User;
	import org.apache.ibatis.io.Resources;
	import org.apache.ibatis.session.SqlSession;
	import org.apache.ibatis.session.SqlSessionFactory;
	import org.apache.ibatis.session.SqlSessionFactoryBuilder;
	import sun.security.smartcardio.SunPCSC;
	
	import java.io.IOException;
	import java.io.InputStream;
	import java.util.List;
	
	public class Test {
	    public static void main(String[] args) throws IOException {
	        //1.读取配置文件
	        InputStream inputStream=Resources.getResourceAsStream("SqlMapConfig.xml");
	        //2.创建SqlSessionFactory工厂
	        SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
	        SqlSessionFactory factory = builder.build(inputStream);
	        //3.使用工厂创建SqlSession对象
	        SqlSession session = factory.openSession();
	        //4.使用session对象创建UserDao接口实现类的代理对象
	        UserDao mapper = session.getMapper(UserDao.class);
	        //5.使用代理对象执行对应方法
	        List<User> users = mapper.findAll();
	        //5.1遍历
	        for (User user : users) {
	            System.out.println(user);
	        }
	        //6.释放资源
	        inputStream.close();
	        session.close();
	    }
	}

在这里插入图片描述

CRUD

1.在UserMappper接口中写对应的方法
1.Test格式:
	import com.itheima.domain.User;
	import com.itheima.mapper.UserMapper;
	import org.apache.ibatis.io.Resources;
	import org.apache.ibatis.session.SqlSession;
	import org.apache.ibatis.session.SqlSessionFactory;
	import org.apache.ibatis.session.SqlSessionFactoryBuilder;
	import org.junit.After;
	import org.junit.Before;
	
	import java.io.IOException;
	import java.io.InputStream;
	import java.util.Date;
	import java.util.List;
	
	public class Test {
	    private InputStream inputStream;
	    private SqlSession session;
	    private UserMapper mapper;
	    @Before
	    public void init() throws IOException {
	        //1.获取配置文件输入流
	        inputStream= Resources.getResourceAsStream("SqlMapConfig.xml");
	        //2.通过输入流创建SqlSessionFactory工厂
	        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);//创建者模式,封装细节
	        //3.通过工厂创建SqlSession对象
	        session = factory.openSession();//工厂模式,增强解耦性
	        //4.通过SqlSession对象创建UserMapper的代理对象
	        mapper = session.getMapper(UserMapper.class);
	    }
	    @After
	    public void destroy() throws IOException {
	        session.commit();//这一部时事务的提交
	        //6.释放资源
	        inputStream.close();;
	        session.close();
	    }
	    @org.junit.Test
	    public void findAllUser() throws IOException {
	        //5.通过代理对象执行对应方法
	        List<User> users = mapper.findAll();
	        for (User user : users) {
	            System.out.println(user);
	        }
	    }
	    @org.junit.Test
	    public void saveUser() throws IOException {
	        //4.5创建User对象
	        User user=new User();
	        user.setUsername("张三");
	        user.setBirthday(new Date());
	        user.setSex("男");
	        user.setAddress("河北省石家庄市裕华区裕祥街26号");
	        //5.通过代理对象执行对应方法
	        mapper.saveUser(user);
	    }
	}
2.UserMapper.xml格式
<select id="方法名" parameterType="输入的数据类型" resultType="返回数据要存储的对象">
    sql语句
    1.传入数据用法:
    	#{属性名},如果只用输入类型的数据:#{随便一个名}
    2.如果用模糊查询
    	%和_等符号要写在string中,不要写在sql语句中
    3.在插入语句中我们可以写入selectKey标签来给插入后的User赋值
    	<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
            select last_insert_id();
        </selectKey>
        keyProperty代表User的属性id
        keyColumn代表表中字段名称id
        resultType表示返回值的类型
</select>
4.数据库字段名和接收对象属性名的对应
	方法一:起别名:在用查询语句给字段起别名,让别名和对象的属性名相同,效率高,但是每写一次查询就的写一次别名,操作困难,耦合性低
	方法二:在语句外写一个resulteMap标签来实现字段于属性的对应
		<resultMap id="userMap" type="com.itheima.domain.User">
	        <!--主键字段的对应-->
	        <id property="userId" column="id"></id>
	        <!--非主键字段的对应-->
	        <result property="userName" column="username"></result>
	        <result property="userAddress" column="address"></result>
	        <result property="userSex" column="sex"></result>
	        <result property="userBirthday" column="birthday"></result>
	    </resultMap>
	  	然后把查询语句中的resultType改为resultMap,值为resultMap的id即可

一、C增

1.在UserMapper.xml配置文件中
	<insert id="saveUser" parameterType="com.itheima.domain.User">
        insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address});
    </insert>

二、R查

1.在UserMapper.xml配置文件中
	<select id="findAll" resultType="com.itheima.domain.User">
        select * from user;
    </select>

三、U改

1.在UserMapper.xml配置文件中
	<update id="updateUser" parameterType="com.itheima.domain.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id};
    </update>

四、D删

1.在UserMapper.xml配置文件中
	<delete id="deleteUser" parameterType="int">
        delete from user where id=#{id};
    </delete>

mybatis中的连接池以及事务控制

1.连接池:
	1.我们在实际开发中都会使用连接池,因为他可以减少我们获取连接所消耗的时间
	2.连接池就是存储链接的容器,容器其实就是一个集合对象,该集合必须是线程安全的,不能两个线程拿到同一个连接 
	3.该集合还必须满足队列的特性:先进先出
2.mybatis中的连接池
	mybatis中的连接池提供了3种方式的配置
		配置的位置:
			主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是表示采用何种连接池方式
			type属性的取值:
				POOLED:采用创痛的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现
				UNPOOLED:采用传统获取连接的方式,对然也实现javax.sql.DataResource接口,但是没有使用池的思想
				JNDI:采用服务器提供的JNDI技术实现,来获取DateSource对象,不同的服务器所能拿到的DataSource是不一样的

mybatis基于XML配置的动态SQL语句使用

这种动态语句是加在sql上的
1.if
	格式:
		<if test="条件"><!--注意条件中可直接用穿过来对象的属性,但不能用&&,只能用and,但可以使用&amp;来代替&-->
			要添加的sql语句
		</if>
	注意:
				如果使用条件查询,要在被添加的语句上加where 1=1 ,来确保sql的正确性
	           还有一种方法,把要写的语句加到where标签中,例:
	           <where>
	           		<if test="birthday != null " >
	           			birthday =#{birthday}    <!--and都不用写-->
	           		</if>
	           </where>	
2.foreach
	格式
		<foreach connection="集合" open="前边的语句" close="后边的语句" item="给集合中元素命名"  separator="语句之间的分隔符">
			sql语句片段
		<foreach/>
3.注意
	1.if是判断其标签中语句是否添加
	2.where是把其标签中语句改成符合where语句规范的语句
	3.foreach是按照某一规则重复某一语句块

mybatis中的多表操作

表之间的关系

	一对一
	一对多
	多对一
	多对多
举例:
	用户和订单就是一对多
		一个用户可以有多个订单
		多个订单可以是一个用户
	身份证和人就是一对一
		一个人只能对应一个身份证号
		一个身份证号只能对应一个人
	老师和学生就是多对多
		一个学生可以有多个老师
		一个老师可以叫多个学生
特例:
	如果拿出每一个订单,他们都对应一个用户
	所以mybatis就把他们看成了一对一

步骤

1.建立两张表
2.建立两个实体类
3.建立两个配置文件
4.实现配置

一对一(多对一)

1.给(外键所在的表的)对象添加(外键所关联表的)对象属性
2.利用resultMap中的association标签给外键所关联表的对象属性添加关联property属性为user,javaType属性为com.itheima.domain.User
3.给User中每一个字段建立连接
	<resultMap id="accountUserMap" type="com.itheima.domain.Account">
        <id property="id" column="aid"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <association property="user"  javaType="com.itheima.domain.User">
            <id property="id" column="id"></id>
            <result property="username" column="username"></result>
            <result property="address" column="address"></result>
            <result property="sex" column="sex"></result>
            <result property="birthday" column="birthday"></result>
        </association>
    </resultMap>

一对多

1.给(外键所在的表的)对象添加(外键所关联表的)对象集合属性
2.利用resultMap中的collection标签给外键所关联表的对象属性添加关联property属性为accounts,ofType属性为com.itheima.domain.Account
3.给User中每一个字段建立连接
	<resultMap id="userAccountMap" type="com.itheima.domain.User">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="address" column="address"></result>
        <result property="sex" column="sex"></result>
        <result property="birthday" column="birthday"></result>
        <collection property="accounts" ofType="com.itheima.domain.Account">
            <id property="id" column="aid"></id>
            <result property="uid" column="uid"></result>
            <result property="money" column="money"></result>
        </collection>
    </resultMap>

多对多

1.查询语句
	select r.id rid,r.ROLE_DESC,r.ROLE_NAME,u.* from role r left outer join user_role ur on ur.rid=r.id left outer join user u on ur.uid=u.id;
2.其实和一对多一样,只是在查询语句不一样
	xml文件里还是创建一个resultMap里面写一个collection连接起来就行
	还有就是在创建对象是加上另一个对象的集合

mybatis的缓存

延迟加载

1.什么是延迟加载
	在真正使用数据时才发起查询,在不用的时候不查询。按需加载(懒加载)
2.什么是立即加载
	不管用不用,只要调用方法就会立即执行
3.延迟加载和立即加载的选择
	四中表的关系,一般多对一和一对一用的是立即加载
	而一对多和多对多用的是延迟加载
4.延迟配置的方法
	在总配置文件configuration标签中设置setting
		<settings>
	        <setting name="lazyLoadingEnabled" value="true"/>
	        <setting name="aggressiveLazyLoading" value="false"/>
	    </settings>

延迟加载查询数据

1.一对一(多对一)
	<resultMap id="accountMap" type="com.itheima.domain.Account">
        <id property="id" column="id"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <association property="user"  javaType="com.itheima.domain.User" column="uid" select="com.itheima.mapper.UserMapper.findById"></association>
    </resultMap>
    <select id="findById" parameterType="int" resultType = "com.itheima.domain.User">
    	select * from user where id=#{id}
	</select>
2.多对一
	<resultMap id="userMap" type="com.itheima.domain.User">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="address" column="address"></result>
        <result property="sex" column="sex"></result>
        <result property="birthday" column="birthday"></result>
        <collection property="accounts" ofType="com.itheima.domain.Account" column="id" select="com.itheima.mapper.AccountMapper.findByUid"></collection>
    </resultMap>
    <select id="findByUid"  parameterType="int" resultType="com.itheima.domain.Account">
        select * from account where uid=#{uid};
    </select>

缓存

1.什么是缓存
	存在于内存中的临时数据
2.为什么使用缓存
	减少与数据库的交互次数,提高查询效率
3.什么样的数据要用缓存,什么样的数据不能用
	适用于缓存
		1.经常要查询但不经常修改的数据
		2.数据的正确与否对最终结果影响不大的数据
	不适用于缓存
		1.经常修改的数据
		2.数据的正确与否对最终结果影响很大的

一级缓存

1.概念
	它是指Mybatis中SqlSession中的缓存
	当我们执行查询语句时,查询到的数据会存到SqlSession为我们提供一块区域中
	该区域是一个Map。当我们再次查询同样的数据时,mybatis会先看session中是否有同样的数据,有的话直接拿来用
2.清空一级缓存的条件
	mybatis中,当SqlSession调用它的clearCache,delete,update,insert,commit,close方法时,会清空一级缓存

二级缓存

1.概念
	它是指Mybatis中SqlSessionFactory对象中的缓存。有同一个SqlSessionFactory对象创建的Sqlsession对象共享其缓存
2.使用步骤
	1.让mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
	2.让映射文件支持二级缓存(在UserMapper.xml中配置)
	3.让大哥前操作支持二级缓存(在select标签中配置)

mybatis中的注解开发

环境搭建

环境的搭建和xml配置文件开发没什么两样
只不过是在总配置文件里导入的是接口的位置

注解开发

概述:

	注解开发就是在接口中通过编写注解来进行开发,由于是在接口中写的
	自然就包括了包名,接口名,方法名,返回值类型和形参,我们只需要写方法体
	也就是sql语句即可,这样书写方便了开发,简化了操作步骤,提高了效率

步骤:

	1.编写Dao接口
	2.在接口的方法上加上Select,Insert,Update,Delete注解value值为sql语句
	3.如果想使用userMap对属性和字段进行关联应添加Results注解
	4.在注解中使用Options注解即可配置配置文件中标签属性的信息
	其中添加Result注解,用这样的方式模拟userMap,也可使用ResultMap注解来引用之前写过的注解。
		@Select("select * from user where id=#{id}")
	    @Results(id="userMap",value={
	            @Result(id=true,property = "id",column = "id"),
	            @Result(property = "username",column = "username"),
	            @Result(property = "sex",column = "sex"),
	            @Result(property = "birthday",column = "birthday"),
	            @Result(property = "address",column = "address")
	    })
	    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
	    public User findById(int id);


	    @Select("select * from user")
	    @ResultMap("userMap")
	    public List<User> findAll();

一对一

@Result(property = “user”,column = “uid” ,one=@One(select = “com.itheima.mapper.UserMapper.findById”,fetchType = FetchType.EAGER))

一对多

@Result(property = “accounts”,column = “id” ,many = @Many(select =“com.itheima.mapper.AccountMapper.findByUid”,fetchType = FetchType.LAZY))

缓存

1.主配置文件之中
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>
2.Dao中
@CacheNamespace(blocking = true)//此注解写到接口上面
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狴犴ys

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值