MyBatis的CRUD

根据ID查询

1.持久层接口添加fndById

1
User findById(Integer id);

2.在用户的映射配置文件中配置

细节:

resultType 属性:用于指定结果集的类型。

parameterType 属性:用于指定传入参数的类型。

sql语句中使用#{}字符: 它代表占位符,相当于原来 jdbc 部分所学的 **?**,都是用于执行语句时替换实际的数据。具体的数据是由#{}里面的内容决定的。

**#{}**中内容的写法:由于数据类型是基本类型,所以此处可以随意写。

1
2
3
<select id="findById" resultType="cn.hxx.domain.User" parameterType="Integer">
select * from user where id=#{uid};
</select>

添加操作

1.在持久层接口添加新增方法

1
void insertOneUser(User user);

2.在用户的映射配置文件中配置

细节:

parameterType 属性:代表参数的类型,因为我们要传入的是一个类的对象,所以类型就写类的全名称。

#{}中内容的写法:由于我们保存方法的参数是 一个 User 对象,此处要写 User 对象中的属性名称。它用的是 ognl 表达式。

新增用户之前用户ID为null,新增成功之后ID不为null

1
2
3
4
5
6
7
<insert id="insertOneUser" parameterType="cn.hxx.domain.User">
<!--新增用户后,同时还要返回当前新增用户的 id 值,因为 id 是由数据库的自动增长来实现的,所以 就相当于我们要在新增后将自动增长 auto_increment 的值返回。keyProperty对应类中属性, keyColumn对应表中名-->
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user (username,address,sex,birthday) values (#{username},#{address},#{sex},#{birthday});
</insert>

更新操作

1.在持久层接口中添加更新方法

1
void deleteById(Integer id);

2.配置文件

1
2
3
<update id="updateUser" parameterType="cn.hxx.domain.User">
update user set username=#{username} where id=#{id};
</update>

删除操作

1.在持久层接口中添加删除方法

1
void deleteById(Integer id);

2.配置文件

1
2
3
<delete id="deleteById" parameterType="Integer">
delete from user where id=#{uid};
</delete>

模糊查询

1.在持久层接口中添加查询方法

1
List<User> findByName(String name);

2.配置文件

1
2
3
<select id="findByName" parameterType="String" resultType="cn.hxx.domain.User">
select * from user where username like #{name};
</select>

3.测试

1
List<User> users = userDao.findByName("%王%");

在控制台输出的语句是:

Preparing select *from user where username like ? 我们在配置文件中没有加入%来作为模糊查询的条件,所以在传入字符串实参时,就需要给定模糊查询的标识%。配置文件中的#{username}也只是一个占位符,所以 SQL 语句显示为“?”。

聚合函数

1.在持久层接口中添加聚合方法

1
int findTotal();

2.配置文件

1
2
3
<select id="findTotal" resultType="int">
select count(id) from user;
</select>

MyBatis和JDBC编程的比较

  1. 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

解决:在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。

  1. Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。

解决:将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。

  1. 向 sql 语句传参数麻烦,因为 sql 语句的 where 条件不一定,可能多也可能少,占位符需要和参数对应。

解决:Mybatis 自动将 java 对象映射至 sql 语句,通过 statement 中的 parameterType 定义输入参数的类型。

  1. 对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对

象解析比较方便。

解决:Mybatis 自动将 sql 执行结果映射至 java 对象,通过 statement 中的 resultType 定义输出结果的类型。

OGNL表达式

全称:Object Graphic Navigation Language

通过对象的取值方式来获取数据,在写法上把get省略了。比如,我们获取用户的名称,在类中:user.getUsername(); 在OGNL表达式写法:user.username。

#{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用getUsername()方法把值取出来。但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user.,而直接写username。

#{}或者${}中的值为pojo属性名称

1
2
3
<update id="updateUser" parameterType="cn.hxx.domain.User">
update user set username=#{username} where id=#{id};
</update>

ResultMap结果集

resultMap 标签可以在查询的列名和实体类的属性名称不一致时,建立对应关系。从而实现封装。

在 select 标签中使用 resultMap 属性指定引用即可。同时 resultMap 可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括 pojo 对象和 list 实现一对一查询和一对多查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- resultMap 建立 User 实体和数据库表的对应关系
type 属性:指定实体类的全限定类名
id 属性:给定一个唯一标识,是给查询 select 标签引用用的。
-->
<resultMap type="cn.hxx.domain.User" id="userMap">
<!--
id 标签:用于指定主键字段
result 标签:用于指定非主键字段
column 属性:用于指定数据库列名
property 属性:用于指定实体类属性名称
-->
<id column="id" property="userId"/>
<result column="username" property="userName"/>
<result column="sex" property="userSex"/>
<result column="address" property="userAddress"/>
<result column="birthday" property="userBirthday"/>
</resultMap>

映射配置:原来的resultType修改为配置resultMap=”userMap”

1
2
3
<select id="findAll" resultMap="userMap">
select * from user
</select>