一、今日内容
文章目录
二、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层接口类
3. 在resource目录下建立:SqlMapConfig.xml文件,并在该文件中的头部粘贴下面代码:
外部资源:
代码:
<?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>
4. 在resource目录下必须一次次的建立文件夹:cn再建wanghao再建mybatis再建UserDao.xml。
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目录下编写测试类:
上述代码的说明:
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层的接口类中的方法用注解的方式进行注解:
3. 在resource目录下建立:SqlMapConfig.xml文件,并在该文件中的头部粘贴下面代码:
外部资源:
代码:
<?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>
4. 在test目录下编写测试类:
上述代码的说明:
5. 运行结果如下:
五、基于代理 Dao 实现 CRUD 操作
1. 使用要求:
1、持久层接口和持久层接口的映射配置必须在相同的包下(即:UserDao.java与UserDao.xml目录结构一样)
2、持久层映射配置中 mapper 标签的 namespace 属性取值必须是持久层接口的全限定类名 (比如:cn.wanghao.mybatis.dao.UserDao)
3、SQL 语句的配置标签<select>,<insert>,<delete>,<update>的 id 属性必须和持久层接口的 方法名相同。
2. 映射配置文件<select>、<insert>等sql语句标签的属性说明:
1. resultType 属性:用于指定结果集的类型。 如果返回的是List<User>,也填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}%';
#{}的例子:
${}的例子:
需要注意:
六、数据库返回的数据列名与当实体类的类成员名不一致的解决方法
这个问题,在我们传的参数是VO对象,或者返回的是VO对象时,可以会遇到!
解决方法有两种:
1. 修改sql语句,用as语句做修改
* 比如:select id as userId from user;
2. 在持久层接口的映射配置文件中使用<resultMap></resultMap>标签
* 使用步骤:
1. 定义 查询的结果列名与实体类的属性名的对应关系
* 比如:
<!--配置查询的结果列名与实体类的属性名的对应关系-->
<resultMap id="userMap" type="cn.wanghao.mybatis.domain.User">
<!--配置主键对应关系,,如果确定一样可以不写-->
<id property="userID" column="id"></id> <!-- property是实体类的属性名;column是表的字段名 -->
<!--配置其他列名的对应关系,如果确定一样的可以不写,写不确定一样的-->
<result property="userName" column="name"></result>
<result property="userPasswd" column="passwd"></result>
</resultMap>
* 注意:在resultMap标签里面,如何你确定表字段名和实体类的属性名一样,可以不写该属性的<id >或者<result>标签
2. 使用上面定义的对应关系
* 谁要使用上面的对应关系就
1. 删除resultType属性
2. 用resultMap属性设置,其属性值为上面的id值
* 比如:
<select id="findAll" resultMap="userMap">
select * from user;
</select>
七、使用xml方式时,传入多个参数
7.1 使用@Param()注解 —推荐使用
public List<Role> findRolesByMap(@Param("roleName") String roleName, @Param("note") String note);
7.2 使用Map存放参数 —不推荐使用
在mybatis中 允许map接口通过键值对传递多个参数,把接口方法定义为:
public List findRolesByMap(Map<String,Object> paramenterMap);
此时,传递给映射器的是一个map对象,使用它在SQL中设置对应的参数
<select id="findRolesByMap" parameterType="map" resultType="role">
select id,role_name as roleName,note from t_role where role_name like concat('%#{roleName}%')
and note like concat('%#{note}%')
</select>
注意,参数roleName和note,要求的是map的键,也就是需要按照如下方式传递参数。
RoleMapper roleMapper=sqlSession.getMapper(RoleMapper.class);
Map<String,Object> paramenterMap=new HashMap<String,Object>();
parameterMap.put("roleName","1");
parameterMap.put("note","1");
List<Role> roles=roleMapper.findRolesByMap(parameterMap);