Week--My batis

1.使用mybatis的操作步骤--

1.1Mybatis核心配置以及映射配置文件

<!--在maven项目下导入mybatis的jar包-->
 <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.4</version>
</dependency>

<!--mybatis的xml配置方式:需要在resources的目录创建xml文件配置mybatis的核心配置文件-->

	<!--头部文件-->
<?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>
	<!--环境配置-->
    <!--需要连接mysql 给default属性设置一个标识-->
    <environments default="msyql">
        <!--id和上面default一致-->
        <environment id="msyql">
            <!--事务管理器:Jdbc控制事务-->
            <transactionManager type="JDBC"/>
            <!--配置数据源mybatis里面涉及三种数据源
                            mybaits自带连接池 POOLED
                            不用自带的连接池 UNPOOLED
                            JNDI(web相关的一种连接池)
 -->
            <dataSource type="org.apache.ibatis.datasource.pooled.PooledDataSourceFactory">

                <!--配置数据源的一些属性,连接数据库的信息-->
                <!--配置驱动类-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <!--配置url-->
<property name="url" value="jdbc:mysql://localhost:3306/myee_2113?characterEncoding=utf8"/>
                <!--配置用户名-->
                <property name="username" value="root"/>
                <!--配置密码-->
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
	<!--当读取SqlMapConfig.xml文件的时候,需要加载映射文件xxxMapper.xml-->
    <!--配置映射器-->
    <mappers>
        <mapper resource="com/qf/mapper/UserMapper.xml"></mapper>
    </mappers>
</configuration>

1.2定义mapper接口

//定义mapper接口(相当于之间xxxDao:数据访问接口)

 /*查询所有用户*/
        List<User> findAllUser() ;

1.3配置映射文件

<!--在resources资源路径下配置xxxMapper对应的 xxxMapper.xml (sql映射文件)-->
	<!--头部文件-->
<?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:名称空间-->
<mapper namespace="com.qf.mapper.UserMapper">
    <!--查询所有用户列表-->
    <!--id:和接口中的方法名要一致: 才能定位到具体的方法上
             parameterType:指定的是输入映射参数和当前接口中的方法的参数类型一致
						如果int,书写java.lang.Integer/Integer...
                        如果String.书写java.lang.String/String
			 resultType:输出映射参数
                    返回的List :需要返回的list集合中泛型的类型的全限定名称
                    返回字符串,输入映射:String,java.lang.String
    -->
    <select id="findAllUser" resultType="com.qf.pojo.User">
            select  * from  user
    </select>
</mapper>

1.3测试类

public class MyBatisTest {

    InputStream inputStream ;
    SqlSession sqlSession ;
    StudentMapper studentMapper ;//接口对象声明

    @Before
    public void init() throws Exception {
        //1)驱动mybatis核心配置文件
         inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建SqlSessionFactoryBuilder构造者设计模式
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder() ;

        //通过加载资源文件输入流,获取SqlSessionFactory接口工厂
        SqlSessionFactory sqlSessionFactory = builder.build(inputStream);
        //创建执行对象
         sqlSession = sqlSessionFactory.openSession();//开启手动提交

        //获取接口代理对象
        studentMapper = sqlSession.getMapper(StudentMapper.class) ;
    }
    
    //测试查询所有的学生
    @Test
    public void testFindAll(){

        List<Student> list = studentMapper.findAll();
        if(list!=null){
            for(Student student:list){
                System.out.println(student);
            }
        }
    }
}

2.mybatis插入数据,获取自增长主键id的值

mybatis插入数据的时候,获取表中自增长主键id的值
 	insert标签中有子标签seletkey,属性如下:
     keyProperty:实体类中的属性值 (通过id字段要和表中id字段映射)
     keyColumn:表中的主键字段  id字段
     order:什么时候执行 sekectKey标签中的语句
            AFTER 在执行插入之后,执行selectkey的语句,获取最后一次自增长主键的id值
            	SELECT LAST_INSERT_ID()
            BEFORE: 插入数据之前执行
			resultType:获取到的自增长主键的类型 int
<!--在执行插入之后,执行语句,获取最后的自增长主键id的值-->

<insert id="addStudent" parameterType="com.qf.pojo.Student">
    <selectKey keyProperty="id" keyColumn="id" order="AFTER" resultType="int">
                    SELECT LAST_INSERT_ID()
    </selectKey>
 insert  into  student(name,age,address,birthday) values(#{name},#{age},#{address},#{birthday})
</insert>

3.1封装vo实体类

//包装的实体类--里面包含的一个学生类
public class QueryVo {
    
    private Student student ;

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }
}

3.2mybatis基本模糊查询

<!--模糊查询学生列表-->
    <select id="findStudentByName" resultType="student">
                <!-- mybaits固定属性‘%${value}%’
                                ${} :字符串拼接符号,值和 % %之间进行拼接
                mybatis开发中,不要使用这种符号,尽量去使用#{},而不是用${},这也是sql的一种
                -->
       <!-- select * from student where name like '%${value}%' -->
       <!--使用#{}推荐-->
       select * from student where name like  #{name}
    </select>

3.3封装的vo实体来模糊查询学生列表

<select id="findUserByQueryVo" resultType="student" parameterType="queryvo">
        <!--QueryVo类型包含的是Student类型,访问的时候可以 queryvo对象.getStudent().getName()
                对象图导航语言 简写书写格式 将get()去掉
                    student是QueryVo的bean属性
                    name又是学生对象的bean属性
					可以简写为:#{student.name}
 -->
        select * from student where name like #{student.name}
    </select>

4.传统dao的弊端

1)开发过程还需要核心配置文件,也需要映射文件,代码大量加大,还需要提供接口实现类
2)从内存角度考虑:以后需要在业务层需要频繁的数据访问接口,不断的开辟堆内存空间;
3)开发中遵循"低耦合,高内聚",而传统dao的程序之间出现耦合性,而降低耦合性经常使用的技术"反射技术";
mapper代理的方式:使用到了jdk动态代理,就比这种传统方式优秀!

5.mybatis注解开发流程

<!--注解开发,不需要加载 映射文件,class属性直接指定接口的全限定名称-->
<mapper>
	<mapper class="com.qf.mapper.StudentMapper"></mapper>
</mapper>
//StudentMapper

@Select("select * from student")
 //@Select注解:查询的---替代了xx.xml映射文件中的select标签
    List<Student> findAll() ;

@Delete("delete from student where id = #{id}") //代替映射文件中的delete标签
    void deleteStudent(int id) ;

@Update("update student set name = #{name},age = #{age},address = #{address},birthday = #{birthday} where id = #{id}) //代替update标签
    void updateStudentById(Student student) ;

 @Insert("insert into student(name,age,address,birthday) values(#{name},#{age},#{address},#{birthday})) //代替了insert标签
    void addStudent(Student student) ;

6.读取外部配置文件,获取jdbc连接信息以及加入实体类包扫描

<!--别名的包扫描,它直接将实体所在包指定,别名默认就是当前类名小写,(一般不区分大小写)-->
<typeAliases>
	<package name="com.qf.pojo"/>
</typeAliases>


<!--属性配置,加载类路径下的其他properties配置文件
	属性:resource="指定资源目录下的配置文件名称"-->
<properties resource="jdbc.properties"/>

<!--value:通过${获取配置文件中的key对应的value}-->
    <property name="driver" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.user}"/>
    <property name="password" value="${jdbc.password}"/>

 <!--mapper的别名包扫描的方式-->
        <!--将包内的映射器接口实现全部注册为映射器,因为映射文件和接口的包结构一致,自动扫描-->
<mappers>
	<package name="com.qf.mapper"/>
</mappers>

7.mybatis的原理

架构体现:
    1)准备核心配置文件 mybatis-Config.xml---->mybatis的Resources就来读取配置文件的内容
    2)将配置文件内容---->每一个标签--->封装到一个类中,作为它的属性:Configuration类(配置类)
    3)加载映射器 Mappers -->里面配置的mapper的sql映射文件---->MapperRegister:Mapper注册器
    
Configuration类(配置类):
    //创建SqlSessionFactoryBuilder--->构建者,就是将资源输入流的内容,封装Configuration类
    //创建SqlSessionFactory接口工厂------>通过子实现类 DefaultSqlSessionFactory进行创建
    
    4)创建SqlSesison:执行对象---->底层有接口Executor执行器 ----->最终就是创建一个PreparedStatement:预编译对象
    5)T <T> getMapper(Class<T> class):---->mapper代理底层就是一个jdk动态代理,针对XXXMapper接口 产生代理对象(jdk动态代理前提基于接口实现)--->MapperProxy implements InvocationHandler

8.mybatis的参数绑定

//@Param("将指定的参数绑定到这个注解中,起一个名称")
//按照学生姓名和地址查询学生信息
Student findStudentByNameAndAddress(@Param("name") String name,@Param("addr") String address) ;

//参数绑定的使用
<select id="findStudentByNameAndAddress"
            resultType="student">
        select * from student where name = #{name} and
        address = #{addr}
    </select>

9.参数为复杂类型的Map集合

 <!--Student findStudentByNameAndBirthday(Map values) ;-->

<select id="findStudentByNameAndAddress"resultType="student">
        select * from student where name = #{name} and
        address = #{birthday}
</select>

<!--测试-->
//创建Map集合
Map map  = new HashMap<>() ;
//给映射文件中的参数进行赋值
map.put("name","刘桑") ;
map.put("birthday","1996-12-10 00:00:00") ;

10.连接池的特点

连接池的特点:
	创建一些固定的可重用的连接对象,重复利用它,当某个连接对象被某个持有的线程使用完毕之后,然后归还连接池中.

11.mybatis启用德鲁伊的连接池

1)导包
<dependency>
            <!--导入阿里的德鲁伊 druid 连接池-->
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.13</version>
</dependency>

2)配置文件:使用自己的连接池:自定义一个工厂类 继承了 mybatis里面的PooledDataSourceFactory
         <dataSource type="com.qf.datasource.MyDruidDataSourceFactory">
         <property name="driverClass" value="${jdbc.driverClassName}"/>
         <property name="url" value="${jdbc.url}"/>
         <property name="username" value="${jdbc.username}"/>
         <property name="password" value="${jdbc.password}"/>
         <!--最大激活数量-->
         <property name="maxActive" value="${jdbc.maxActive}"/>
            </dataSource>
         
3)自定义这个类继承自mybatis的连接池数据源工厂类
	public class MyDruidDataSourceFactory extends
        PooledDataSourceFactory {
        //构造方法
        public MyDruidDataSourceFactory(){
        //创建德鲁伊的数据源对象
        this.dataSource = new DruidDataSource() ;
    }
}

12.mybatis的高级映射resultMap

使用场景:
	 1)当实体类属性和字段一样 
	 2)mybatis多表查询的时候可以用
	 
使用步骤:
	首先在映射文件中定义resultMap,然后在具体的增删改,查询语句中将reusltMap引入,resultMap里面就是可以将每一个字段和实体类的属性一一映射

12.1 定义resultMaop

	<!--  定义resultMap
            id:resultMap它的标识id,不可以重复;
            type:就是实体类的全限定名称/别名  (返回值类型)
         -->
<resultMap id="myMap" type="student">
        <!--配置主键字段: 表中主键字段 id 和 实体类的属性 id一致
            property:实体类的属性名称 stuId
            column:表中字段列的名称 主键id
        -->
        <id property="stuId" column="id"></id>
        <!--普通字段和实体类的其他属性名称一一对应-->
        <result property="stuName" column="name"></result>
        <result property="stuAge" column="age"></result>
        <result property="stuAddress" column="address"></result>
        <result property="stuBirthday" column="birthday"></result>
    </resultMap>

 <!--引入resultMap 引入上面id属性值 -->
<select id="findAll" resultMap="myMap">
	select  * from student
</select>

13.动态sql语句---where

    <select id="findStudentByConditon"  resultMap="myMap">
       select * from student
        <!---利用where标签来代替where关键字-->
         <where>
             <!--
           此时后面的条件利用if标签进行判断 当前这些属性不为null的时候才能查询
            test属性:判断当前实体类型的属性是否满足条件,true还是false,true则执行, 否则不执行-->
             <if test="stuName!=null">
                 name = #{stuName}
             </if>
             <if test="stuAddress!=null">
                and  address = #{stuAddress}
             </if>
         </where>
    </select>

14.动态sql片段

动态的sql片段将重复性的sql抽取出来,在其他sql中引入这个sql片段即可
 <sql id="mySelectSql">
        select  * from student
    </sql>   
 <select id="findAll" resultMap="myMap">
		  <!--引入sql片段 refid:引入sql片段指定的id值 -->
        <include refid="mySelectSql"/>
 </select>

15.动态aql--for each遍历数据

<select id="findStudentByVO" parameterType="queryvo" resultMap="myMap">
        <!--引入sql片段-->
        <include refid="mySelectSql"/>
        <where>
            <!--foreach标签属性
                       collection:当前实体类中封装的集合属性名称
                       open:使用子查询 in(x,x,x) 以什么格式开始查询
                       separator:分割符号:,隔开
                       close:以什么格式结束:")"
                       item:循环遍历过程中的变量名称
					   foreach中间的内容:#{item里面指定的变量名称} -->
            <foreach collection="ids" open=" id in(" separator="," close=")"
            item="id">
                   #{id}
            </foreach>
        </where>
    </select>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值