Day25---持久层框架:Mybatis(一)

一、今日内容

文章目录

    • 一、今日内容
    • 二、Mybatis概述
    • 三、Mybatis的入门案例(使用xml方式,常用)
    • 四、Mybatis的入门案例(使用注解方式,不常用,不详细介绍)
    • 五、基于代理 Dao 实现 CRUD 操作
    • 六、数据库返回的数据列名与当实体类的类成员名不一致的解决方法
    • 七、使用xml方式时,传入多个参数
      • 7.1 使用@Param()注解 ---推荐使用
      • 7.2 使用Map存放参数 ---不推荐使用
    • 补充:对于dao层的接口,一定要抛Exception异常,接着service也抛,Controller再抛,然后定义异常类交给异常处理器处理

二、Mybatis概述

1. 什么是框架?
	* 他是我们软件开发中的一种解决方案,不同的框架解决的是不同的问题。
2. 使用框架的好处:
	* 框架封装了很多的细节,使开发者可以使用极简的方式实现功能开发
3. 持久层的解决技术
	1. JDBC技术
	2. Spring的JdbcTempate
	3. Apache的DBUtils
	* 以上都不是框架,JDBC是规范,JdbcTempate和DBUtils都只是对JDBC的简单封装,而不是一种解决方法,或者说封装的不够细致。
4. Mybatis概述:
	1. Mybatis是一个持久层框架,用java编写的。他封装了jdbc的很多细节,使得开发者只需要关注sql语句本身。
	2. 使用了ORM思想实现了结果集的封装。
		* ORM:Object Relational Mapping 对象关系映射
		* 简单来说:就是把数据库表和实体类及实体类的属性对应起来,让我们可以操作实体类就实现操作数据库表。
	3. Mybatis好处:
		1. 在dao层,我们只需要写接口,而不需要写实现的实体类,只专注于sql语句本身
		2. 支持动态sql语句。
		3. 支持多表查询。
		4. 能够使用延迟加载技术,提高资源利用率和用户体验
		5. 自带缓存技术。(如果是传统开发需要借助Redis数据库)

5. 补充说明:
	1. mybatis是基于JDK动态代理对接口进行代理的。
	2. 动态代理的技术:
		1. JDK的动态代理。它是基于接口方式实现的,要求所代理的类是一个接口类或者继承了接口,对一般的类就无法代理,spring默认是这种;
		2. CGLIB动态代理。通过设置proxy-target-class="true",可以启动CGLIBD的动态代理,CGLIB直接生成二进制码,使得普通类也可以实现AOP。

三、Mybatis的入门案例(使用xml方式,常用)

1. 用maven建立项目,并在pom.xml中加入mybatis的依赖jar包

 <!--导入mybatis依赖-->
 <dependency>
     <groupId>org.mybatis</groupId>
     <artifactId>mybatis</artifactId>
     <version>3.5.0</version>
 </dependency>

2. 在domain目录下建立的实体类和dao层接口类
Day25---持久层框架:Mybatis(一)_第1张图片
Day25---持久层框架:Mybatis(一)_第2张图片


3. 在resource目录下建立:SqlMapConfig.xml文件,并在该文件中的头部粘贴下面代码:
Day25---持久层框架:Mybatis(一)_第3张图片
外部资源:
在这里插入图片描述
代码:

<?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">

<!--mybatis的主配置文件-->
<configuration>
    <!-- 引入外部资源:mysql配置文件 -->
    <properties resource="druid.properties"></properties>

    <!--使用typeAliases配置别名,用于指定java目录下的包的别名-->
    <typeAliases>
        <!--用于指定java目录下的包的别名,指定包的别名后,后面用到改包中的类时,直接用类名,且类名不区分大小写-->
        <package name="cn.wanghao.mybatis.domain"></package>
    </typeAliases>

    <!--配置环境-->
    <environments default="mysql">     <!--default的值是任意取的,但是必须与下面的id的值一致-->
        <!--配置mysql的配置环境-->
        <environment id="mysql">
            <!--配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--配置连接数据库的4个基本信息-->
                <property name="driver" value="${driverClassName}" />
                <property name="url" value="${url}" />
                <property name="username" value="${username}" />
                <property name="password" value="${password}" />
            </dataSource>
        </environment>
    </environments>

    <!-- 指定映射类 -->
    <mappers>
        <!--用于指定存放xml文件的包的别名,就不需要写mapper标签了及resource或者class属性了-->
        <package name="cn.wanghao.mybatis.dao"></package>
    </mappers>

</configuration>

Day25---持久层框架:Mybatis(一)_第4张图片


4. 在resource目录下必须一次次的建立文件夹:cn再建wanghao再建mybatis再建UserDao.xml。
Day25---持久层框架:Mybatis(一)_第5张图片
5. 在UserDao.xml中编写如下代码:

<?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">

<mapper namespace="cn.wanghao.mybatis.dao.UserDao">  <!-- namespace的值是需要配置的dao层下的接口类 -->
    <!-- id是要简化的方法名; resultType返回值的类型类路径 -->
    <select id="findAll" resultType="User">
        select * from user;
    </select>


    <insert id="insert" parameterType="User" keyColumn="">
        insert into user(userName, passwd, gender, age, brithPlace, email) values (#{userName},#{passwd},#{gender},#{age},#{brithPlace},#{email});
    </insert>
</mapper>

6. 在test目录下编写测试类:
Day25---持久层框架:Mybatis(一)_第6张图片
上述代码的说明:
Day25---持久层框架:Mybatis(一)_第7张图片


7. 运行结果如下:
在这里插入图片描述


四、Mybatis的入门案例(使用注解方式,不常用,不详细介绍)

1. 用maven建立项目,并在pom.xml中加入mybatis的依赖jar包

 <!--导入mybatis依赖-->
 <dependency>
     <groupId>org.mybatis</groupId>
     <artifactId>mybatis</artifactId>
     <version>3.5.0</version>
 </dependency>

2. 在domain目录下建立的实体类和dao层接口类,且dao层的接口类中的方法用注解的方式进行注解:
Day25---持久层框架:Mybatis(一)_第8张图片
Day25---持久层框架:Mybatis(一)_第9张图片


3. 在resource目录下建立:SqlMapConfig.xml文件,并在该文件中的头部粘贴下面代码:
Day25---持久层框架:Mybatis(一)_第10张图片
外部资源:
在这里插入图片描述
代码:

<?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">

<!--mybatis的主配置文件-->
<configuration>
    <!-- 引入外部资源:mysql配置文件 -->
    <properties resource="druid.properties"></properties>

    <!--使用typeAliases配置别名,用于指定java目录下的包的别名-->
    <typeAliases>
        <!--用于指定java目录下的包的别名,指定包的别名后,后面用到改包中的类时,直接用类名,且类名不区分大小写-->
        <package name="cn.wanghao.mybatis.domain"></package>
    </typeAliases>

    <!--配置环境-->
    <environments default="mysql">     <!--default的值是任意取的,但是必须与下面的id的值一致-->
        <!--配置mysql的配置环境-->
        <environment id="mysql">
            <!--配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--配置连接数据库的4个基本信息-->
                <property name="driver" value="${driverClassName}" />
                <property name="url" value="${url}" />
                <property name="username" value="${username}" />
                <property name="password" value="${password}" />
            </dataSource>
        </environment>
    </environments>

    <!-- 指定映射类 -->
    <mappers>
        <!-- 为dao层下进行注解配置的接口类的包指定别名,指定包的别名后,就不需要写mapper标签了及resource或者class属性了-->
        <package name="cn.wanghao.mybatis.dao"></package>
    </mappers>

</configuration>

Day25---持久层框架:Mybatis(一)_第11张图片


4. 在test目录下编写测试类:
Day25---持久层框架:Mybatis(一)_第12张图片
上述代码的说明:
Day25---持久层框架:Mybatis(一)_第13张图片


5. 运行结果如下:
在这里插入图片描述

五、基于代理 Dao 实现 CRUD 操作

1. 使用要求:  
	1、持久层接口和持久层接口的映射配置必须在相同的包下(即:UserDao.java与UserDao.xml目录结构一样)
	2、持久层映射配置中 mapper 标签的 namespace 属性取值必须是持久层接口的全限定类名  (比如:cn.wanghao.mybatis.dao.UserDao)
	3、SQL 语句的配置标签等sql语句标签的属性说明:
	1. resultType 属性:用于指定结果集的类型。 如果返回的是List,也填User的全限定类名
	2. parameterType 属性:用于指定传入参数的类型。
	3. keyProperty属性:值为对应参数的属性名  
	4. keyColumn属性:值为数据库表的列名

3. 映射配置文件中的sql语句说明:
	1. 使用#{}字符(常用):它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。具体的数据是由#{}里面的内容决定的。  
		* #{}中内容的写法:
			1. parameterType是基本数据类型:#{任意取名字}
			2. parameterType是对象:#{类的属性名}。
				* 注意:是属性名,不是类的成员变量名。 
				* 原因:假如parameterType=“cn.wanghao.mybatis.domain.User”,则不应该写#{user.userName}而是#{userName},因为我们用parameterType已经指定了类
			3. parameterType是封装对象(即VO对象):#{VO属性.对象属性}能获取VO对象属性的属性的值
				* 比如:parameterType=“cn.wanghao.mybatis.domain.BeanVO”,BeanVO里面有属性(注意是属性,不是类成员)user,user是User对象,要从VO对象中获取user的userName,#{user.userName}
			* 举例:insert into user(username,birthday,sex,address)  values(#{username},#{birthday},#{sex},#{address}) 

	2. ${}表示拼接sql串。(不常用)通过${}可以将 parameterType 传入的内容拼接在 sql中且不进行 jdbc 类型转换, ${}可以接收简 单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,${}括号中只能是 value。 
		* 注意:如果方法的参数只有一个形参时,使用模糊查询时,${value}里面必须是value
		* 例子: select * from user where userName like '%${value}%';

#{}的例子:
在这里插入图片描述
${}的例子:
在这里插入图片描述
需要注意:
Day25---持久层框架:Mybatis(一)_第14张图片

六、数据库返回的数据列名与当实体类的类成员名不一致的解决方法

这个问题,在我们传的参数是VO对象,或者返回的是VO对象时,可以会遇到!
解决方法有两种:

1. 修改sql语句,用as语句做修改
	* 比如:select id as userId from user;
2. 在持久层接口的映射配置文件中使用标签
	* 使用步骤:
		1. 定义 查询的结果列名与实体类的属性名的对应关系
			* 比如:
					
				    
				        
				          
				        
				        
				        
				    
			* 注意:在resultMap标签里面,如何你确定表字段名和实体类的属性名一样,可以不写该属性的或者标签
		2. 使用上面定义的对应关系
			* 谁要使用上面的对应关系就
				1. 删除resultType属性
				2. 用resultMap属性设置,其属性值为上面的id值

			* 比如:
				   

七、使用xml方式时,传入多个参数

7.1 使用@Param()注解 —推荐使用

public List findRolesByMap(@Param("roleName") String roleName, @Param("note") String note);

7.2 使用Map存放参数 —不推荐使用

在mybatis中 允许map接口通过键值对传递多个参数,把接口方法定义为:
public List findRolesByMap(Map paramenterMap);

此时,传递给映射器的是一个map对象,使用它在SQL中设置对应的参数


注意,参数roleName和note,要求的是map的键,也就是需要按照如下方式传递参数。

RoleMapper roleMapper=sqlSession.getMapper(RoleMapper.class);
Map paramenterMap=new HashMap();
parameterMap.put("roleName","1");
parameterMap.put("note","1");
List roles=roleMapper.findRolesByMap(parameterMap);

补充:对于dao层的接口,一定要抛Exception异常,接着service也抛,Controller再抛,然后定义异常类交给异常处理器处理

你可能感兴趣的:(JavaWeb)