MyBatis框架

MyBatis框架

一、引言

MyBatis优秀的持久层框架 ---- 将Java程序中处理的数据信息保存到数据库!

替换原始的JDBC开发方式,同时支持简单查询,存储过程,高级映射(表连接)和缓存。

JDBC中冗余的代码开发、SQL语句的固定书写(动态SQL)、手动ORM过于繁琐。

实现思想

在这里插入图片描述

二、开发步骤

1、搭建环境
  1. jar包 核心 + 三方 + 数据库

  2. 配置文件

    2.1 log4j.properties 位置:放到src根目录下即可

    2.2 Mapper.xml 位置:随意 建议归包

    ​ 书写<select … 等 SQL语句的配置文件 替换之前的 DAOImpl 实现类

    2.3 mybatis-config.xml文件 位置:随意 但是建议src根目录

    ​ 配置mybatis 核心参数 比如:连接中的conn等参数

  3. 初始化配置 ----> mybatis-config.xml

<configuration>

    <!-- mybatis 数据库连接环境 s多个  default=“使用具体的某一个配置”-->
    <environments default="oracle">
        <environment id="oracle">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="oracle.jdbc.OracleDriver"/>
                <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
                <property name="username" value="hr"/>
                <property name="password" value="hr"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 注册mapper  替换DAOImpl 告诉mybaits你写了几个实现类 -->
    <!-- com/baizhi/mapper/Mapper.xml 严格区分大小写 -->
    <mappers>
        <mapper resource="Mapper.xml的路径"/>
    </mappers>

</configuration>
2、开发Mapper.xml
<!-- namespace="接口的全限定名称"  -->
<mapper namespace="com.baizhi.dao.UserDAO">
    <!-- id 方法名称   parameterType 参数类型   resultType 返回值类型 全限定名称 -->
    <!--  #{id}  参数的获取   /   sql  条件 = ? -->
	<select id="queryUserByID" parameterType="int"
            resultType="com.baizhi.entity.User">
		select * from my_user where id = #{id}
	</select>
</mapper>
3、初始环境的加载
    //1.读取配置文件
    	InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    
	//2.获取sqlSessionFactory
    	SqlSessionFactory sqlSessionFactory = 
        	new SqlSessionFactoryBuilder().build(is);

    //3.获取sqlSession对象
    	SqlSession sqlSession = sqlSessionFactory.openSession();
    
	//4.通过sqlSession对象获取DAO实现类
		UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
		User user = userDAO.queryUserByID(1);

    //5.关闭资源
		sqlSession.close();

在这里插入图片描述

三、MyBatis参数绑定

如何传递数据以及如何接收数据!!!!

1、DAO方法中的参数(传递数据)
1.八种基本类型+String+Date

parameterType=“参数的类型” 可以省略

2.一个参数
    <!-- 接口方法 : User queryUserByID(int id); -->

    <select id="queryUserByID"  resultType="com.baizhi.entity.User">
        select * from my_user where id = #{id}
    </select>

    #{爱写啥写啥没人管} !!!!!
3.多个参数
1、方式一
    <!-- 接口方法 : User queryUserByIDAndName(int id,String name); -->

    <select id="queryUserByIDAndName" resultType="com.baizhi.entity.User">
        select * from my_user where id = #{0} and name=#{1}
    </select>

    注意:0/1 代表了参数表的下标

2、方式二
	使用注解   @Param("参数的名称")
	 <!-- User queryUserByIDAndName(@Param("id")int id,@Param("n")String name);-->

	<select id="queryUserByIDAndName" resultType="com.baizhi.entity.User">
		select * from my_user where id = #{id} and name=#{n}
	</select>
4.用户自定义类型
    方法 :  User queryUserByNameAndPWD(User user);

    <select id="queryUserByNameAndPWD" parameterType="com.baizhi.entity.User"  
            resultType="com.baizhi.entity.User">
        select * from my_user where name = #{name} and password=#{password}
    </select>

	parameterType="用户自定义类型的全限定名称"  必须有!!!!
	#{对象的属性名称}!!!!

参数是个集合!! 动态SQL再说!!!

5.数据的DML操作

MyBatis 默认数据回滚 需要开发者手动进行事务的提交!

sqlSession.commit();

	void insertUser(User user);

	<insert id="insertUser" parameterType="com.baizhi.entity.User">
        insert into my_user values(#{id},#{name},#{password})
    </insert>
    //获取DAO接口的实现类对象
    UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
    User user = new User(2,"gaojian","123456");
    //提交事务
    sqlSession.commit();
    //关闭资源
    sqlSession.close();
2、返回值类型
1.对象类型

resultType=“com.baizhi.entity.User” 返回对象的全限定名称

2.集合类型 List<User. / Set<.>

resultType=“com.baizhi.entity.User” 返回集合对象泛型的全限定名称 一模一样!!!!

注意:序列使用
方法一:  单表
    <insert id="insertUser" parameterType="com.baizhi.entity.User">
        insert into my_user values(my_seq.nextval,#{name},#{password})
    </insert>

方法二:  多表操作会使用!!!
	<insert id="insertUser" parameterType="com.baizhi.entity.User">
        <!--keyProperty 查询出来的结果进行命名  在插入的时候使用 -->
        <!--order="BEFORE" 执行顺序  resultType="int" 生成结果的Id 的类型 -->
		<selectKey keyProperty="id" order="BEFORE" resultType="int">
			select my_seq.nextval from dual
		</selectKey>
		insert into my_user values(#{id},#{name},#{password})
	</insert>

四、Util的封装

  1. 冗余代码的抽取!!
  2. 效率 — 配置文件的读取一次 静态代码块!
  3. 线程绑定
	private static SqlSessionFactory sqlSessionFactory = null;
	static{
		InputStream is = null;
		try {
			//在类加载的时候 只执行一次的配置文件读取!
			is = Resources.getResourceAsStream("mybatis-config.xml");
			//共享同一个工厂对象  重量级资源    类似 ServletContext
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			if(is!=null)try {is.close();} catch (IOException e) {}
		}
	}
	
	private static ThreadLocal<SqlSession> tl = new ThreadLocal<SqlSession>();
	//获取连接sqlsession
	public static SqlSession getSqlSession() throws IOException{
		SqlSession sqlSession = tl.get();
		//没有连接对象  创建并绑定在当前线程中!!!
		if(sqlSession==null){
			 sqlSession = sqlSessionFactory.openSession();
			 tl.set(sqlSession);
		}
		return sqlSession;
	}
	//资源的关闭  线程的解除绑定
	public static void close(SqlSession sqlSession){
		if(sqlSession!=null){
			sqlSession.close();tl.remove();
		}
	}
	//提交方法  并 关闭
	public static void commit(SqlSession sqlSession){
		if(sqlSession!=null){
			sqlSession.commit();
			close(sqlSession);
		}
	}
	//回滚  并 关闭
	public static void rollback(SqlSession sqlSession){
		if(sqlSession!=null){
			sqlSession.rollback();
			close(sqlSession);
		}
	}


一、细节

1、实体类别名
    <typeAliases>
            <typeAlias type="com.baizhi.entity.User" alias="User"/>
    </typeAliases>

	简化parameterType=“User”   resultType=“别名”
2、配置文件参数化

将大配置文件中可能存在修改的小范围数据提取到更为具体的小配置文件中,便于后期维护修改

	<properties resource="jdbc.properties"></properties>


    <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
    </dataSource>

二、ResultMap结果映射

resultType 、resultMap 出现在Mapper.xml中 都代表了返回的结果类型

当实体类和数据库字段不相同时,无法接收到数据?????

方式一、

​ select id,name username,password from my_user 直接在SQL语句中·使用as别名

方式二、

    <!-- 标识 表中列名 和 实体类属性的对应关系  手动ORM-->
    <!-- type="具体返回的实体类类型" id=“resultMap名称  随意”-->
    <resultMap type="User" id="UserResultMap">
        <id column="id" property="id"/>  <!-- 主键列 -->
        <result column="name" property="username"/>  <!-- 其他非主键列 -->
        <result column="password" property="password"/>
    </resultMap>

    <select id="queryAll" resultMap="UserResultMap" >
        select * from my_user
    </select>

三、jdbcType

MyBATIS 进行添加或修改操作时不允许进行空值数据操作。如果存在null的可能则需要进行jdbcType的使用

<insert id="insertUser" parameterType="User">
    <selectKey keyProperty="id" order="BEFORE" resultType="int">
        select my_seq.nextval from dual
    </selectKey>
    insert into my_user values(#{id},#{username},#{password,jdbcType=VARCHAR})
</insert>

	#{列名,jdbcType=实际数据库列的类型}

在这里插入图片描述

四、多表操作

1、一对一关系

个人信息 和 身份证信息 两张表需要存在关联关系 — 外键

User : 用户表 ID、用户名、密码、手机、身份证号

​ id(主键)、username 、password、phone、idcard(外键)

IdentityCard : 身份证信息表 姓名、性别、民族、出生日期、住址、身份证号

​ realname、sex、nation、birthday、address、idcard(主键)

select  *  from   User u
inner join  IdentityCard   i
on u.idCard = i.idCard

 User表:
id(主键)、username 、password、  phone、       idcard
  1     liuyangyang   123456   1111111111  12345678901234567
  2     gaojianjian   654321   2222222222  12345678901234568
  3     liuhanghang   123456   3333333333  12345678901234569
  3     adada		  111111   4444444444  1234567890123456x
  
 IdentityCard表    
realname、sex、nation、birthday、 address、idcard(主键)
 刘洋      男    汉族   1980-01-01 北京昌平  12345678901234567
 高健      男    xxx   1989-01-02 北京沙河  12345678901234568
 。。。。。。

实体类怎么定义????
面向对象 对象的属性可以是另一个对象

在这里插入图片描述
MyBatis如何查询数据

在这里插入图片描述

2、一对多关系

一个部门多个员工 / 一个用户的多个地址 / 一个班级的多个学生…

Person员工 (表) : 字段 id name age sex

Deparmnent部门 (表) : 字段 dep_id depname description

在这里插入图片描述

在这里插入图片描述

注意:Struts + MyBatis 有一个jar包冲突,留一个就可以版本随意.

1.导入jar包 注意kar包的冲突

2.struts2的核心过滤器配置

3.引入配置文件

​ struts.xml / log4j.properties / mybatis-config.xml(初始化配置) / mapper.xml

4.代码~~~~

两张表 员工(id name password salary role(角色) 部门外键)和部门(dep_id depname)

1.登陆 需要在多一个password字段

2.展示所有员工信息以及其部门名称

3.删除判断 员工中添加 职称字段(员工 部门经理 总经理) 员工没有删除功能!

​ 可选 部门经理删除员工 总经理都可以

  1. 可选 员工不能修改 (判断) 员工的角色要默认选中、选择新的部门(数据来源于数据库的查询)
3、多对多关系

学生 和 课程 商品和订单

Student表

​ stu_id 、 stu_name 、 hire_date

Course表

​ c_id 、 c_name 、 c_time

在这里插入图片描述

所有的学生以及每个学生所有的课程

public class Course {
	private int c_id;
	private String c_name;
}

public class Student {
	private int stu_id;
	private String stu_name;
	private List<Course>  courses;
}
    <resultMap type="Student" id="StudentResultMap">
        <id column="stu_id" property="stu_id"/>
        <result column="stu_name" property="stu_name"/>
        <collection property="courses" ofType="Course">
            <id column="c_id" property="c_id"/>
            <result column="c_name" property="c_name"/>
        </collection>
    </resultMap>

    <select id="showAll" resultMap="StudentResultMap">
        select  s.*,c.*  from t_student s
        inner join t_stu_course sc
        on s.stu_id = sc.stu_id
        inner join T_course c
        on c.c_id = sc.c_id
    </select>

五、动态SQL

1. <sql id=""

代码片段,sql的复用。

    <sql id="STU_COURSE_SQL">
        s.stu_id,s.stu_name,c.c_id,c.c_name 
    </sql>

    <select id="showAll" resultMap="StudentResultMap">
        select  <include refid="STU_COURSE_SQL"/>
        from t_student s
        inner join t_stu_course sc
        on s.stu_id = sc.stu_id
        inner join T_course c
        on c.c_id = sc.c_id
    </select>
2.where 条件

在这里插入图片描述

使用 where标签 以及 if 标签 动态判断用户传递的数据

如果数据不为null 则将数据拼接入where的查询条件

书写方式一、   
	<select id="queryProduct" parameterType="Product" resultType="Product">
        select * from t_product
        <where>
            <if test="pro_id!=null">
                pro_id = #{pro_id}
            </if>
            <if test="pro_name!=null">
                and pro_name = #{pro_name}
            </if>
            <if test="pro_price!=null">
                and pro_price = #{pro_price}
            </if>
            <if test="hire_date!=null">
                and hire_date = #{hire_date}
            </if>
        </where>
    </select>

书写方式二、
<trim prefix="WHERE" prefixOverrides="and|or"></trim>


两者全等于<where></where>  二选一
3. update 中的 set

update 表 set 列=值… where 条件

每一次修改不一定是一行数据的所有,有可能只是个别字段

方式一、
	<update id="updateProduct" parameterType="Product">
        update t_product  
        <set>
            <if test="pro_name!=null">
                pro_name=#{pro_name},
            </if>
            <if test="pro_price!=null">
                pro_price=#{pro_price},
            </if>
            <if test="hire_date!=null">
                hire_date=#{hire_date}
            </if>
        </set>
        where pro_id=#{pro_id}
    </update>

方式二、
	<trim prefix="set" suffixOverrides=","></trim>
4. foreach遍历
    void deleteProductS(List<Integer> ids)    
    SQL--->
        
    delete from 表  where  id  in(?,?,?);

在这里插入图片描述

注意:

在这里插入图片描述
在这里插入图片描述

六、缓存

在这里插入图片描述

使用应该使用MyBATIS二级缓存、一级缓存是SqlSession默认的没什么用!!

1、配置
1.mybatis-config.xml
	<!--声明     开启二级缓存 -->
	<settings>
		<setting name="cacheEnabled" value="true"/>
	</settings>
	
2.需要缓存的SQL语句的mapper.xml配置   只针对一个mapper.xml中的SQL查询
	<cache></cache>

3.所有的实体类必须实现对象序列化接口
	implements Serializable
2、注意
1. Cache Hit Ratio [com.baizhi.dao.ProductDAO]: 0.5      代表了缓存命中率

2. 当执行DML操作 会清空当前缓存
	空间(金钱)换时间

七、连接池

import org.apache.ibatis.datasource.pooled.PooledDataSourceFactory;

import com.alibaba.druid.pool.DruidDataSource;

/**
 * @author Administrator
 * @time 上午11:12:44
 * 2019年12月12日
 */
public class MyPOOLED extends PooledDataSourceFactory{

	public MyPOOLED() {
		this.dataSource = new DruidDataSource();
	
}

<dataSource type="com.baizhi.util.MyPOOLED">
    <property name="driverClass" value="${driver}"/>
    <property name="jdbcUrl" value="${url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${password}"/>
</dataSource>

功能!

1.登陆 注册 强制登陆 验证码 安全退出

2.省份展示 修改 删除 添加

3.景点展示 修改 删除 添加

4.分页

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值