基于代理 Dao 实现 CRUD 操作
IUserdao
public interface IUserDao {
List<User> findAll();//查询所有用户
void saveUser(User user);//保存用户
void updateUser(User user);//更新
void deleteUser(Integer id);//根据id删除用户
User findByid(Integer id);//根据id查询用户
List<User> findByname(String name);//根据name查询用户(模糊查询)
int findtotal();//查询总用户数
}
IUserDao.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="com.itheima.dao.IUserDao">
<select id="findAll" resultType="com.itheima.domain.User">
SELECT * FROM USER ;
</select>
<insert id="saveUser" parameterType="com.itheima.domain.User">
INSERT into user(username,address,sex,birthday) values (#{username},#{address},#{sex},#{birthday})
</insert>
<update id="updateUser" parameterType="com.itheima.domain.User">
update user set username=#{username}, sex=#{sex} where id=#{id}
</update>
<delete id="deleteUser" parameterType="java.lang.Integer">
delete FROM user where id=#{uid}
</delete>
<select id="findByid" parameterType="Integer" resultType="com.itheima.domain.User">
select * from user where id=#{uid}
</select>
<select id="findByname" parameterType="String" resultType="com.itheima.domain.User">
select * from user where username like #{name} <!--通常用这一种,使用PreparedStatement中的参数占位符-->
<!-- select * from user where username like '%${value}%' 用的是字符串的拼接
1. #{}表示一个占位符号通过#{}可以实现 preparedStatement 向占位符中设置值,
自动进行 java 类型和 jdbc 类型转换,#{}可以有效防止 sql 注入。
#{}可以接收简单类型值或 pojo 属性值。
如果 parameterType 传输单个简单类型值,
#{}括号中可以是 value 或其它名称。
2. ${}表示拼接 sql 串通过${}可以将 parameterType 传入的内容
拼接在 sql 中且不进行 jdbc 类型转换, ${}可以接收简单类型值或
pojo 属性值,如parameterType 传输单个简单类型值,
${}括号中只能是 value。
-->
</select>
<select id="findtotal" resultType="int">
select count(id) from user;
</select>
</mapper>
Test文件
@Test
public void testfindAll() {
List<User> users = mappers.findAll();
for (User user : users) {
System.out.println(user);
}
}
/*
测试保存操作
*/
@Test
public void testSave() {
User user = new User();
user.setUsername("save01");
user.setAddress("湖北武汉");
user.setSex("男");
user.setBirthday(new Date());
mappers.saveUser(user);
}
/*
测试保存用户
*/
@Test
public void testUptate(){
User user = new User();
user.setId(42);
user.setUsername("update01");
user.setSex("女");
mappers.updateUser(user);
}
/*
测试删除用户
*/
@Test
public void testdelete(){
mappers.deleteUser(48);
}
/*
测试根据id查询用户
*/
@Test
public void testfind(){
List<User> users = mappers.findByname("%王%");
/*List<User> users = mappers.findByname("王");*/
for (User user : users) {
System.out.println(user);
}
}
/*
测试查询总用户数
*/
@Test
public void findtotal(){
int findtotal = mappers.findtotal();
System.out.println(findtotal);
}
}
拓展:新增用户id返回值
新增用户后,同时还要返回当前新增用户的id值,因为id是由数据库的自动增长来实现的,所以就相当于我们要在自动增长auto_increment的值返回。
Mysql自增主键的返回,配置如下
<insert id="saveUser" parameterType="com.itheima.domain.User">
INSERT into user(username,address,sex,birthday) values (#{username},#{address},#{sex},#{birthday})
<selectKey keyProperty="id" keyColumn="id" order="AFTER" resultType="Integer">
<!-- keyProperty表示要返回的值的名称 keyColumn:数据库id值 order:取值为after代表插入后的行为 resultType代表返回值的类型-->
SELECT last_insert_id()
</selectKey>
</insert>
Mybatis 与 JDBC 编程的比较
- 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
解决:
在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。 - Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大, sql 变动需要改变 java 代码。
解决:
将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。 - 向 sql 语句传参数麻烦,因为 sql 语句的 where 条件不一定,可能多也可能少,占位符需要和参数对应。
解决:
Mybatis 自动将 java 对象映射至 sql 语句,通过 statement 中的 parameterType 定义输入参数的类型。 - 对结果集解析麻烦, sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对
象解析比较方便。
解决:
Mybatis 自动将 sql 执行结果映射至 java 对象,通过 statement 中的 resultType 定义输出结果的
类型。
Mybatis 实现 DAO 的传统开发方式
以删除 user为例.(Statement 对象用于将 SQL 语句发送到数据库中。)
public void deleteUser(Integer id) {
//根据factory获取Sqlsession对象
SqlSession sqlSession = factory.openSession();
//调用SqlSession中的方法,实现删除
sqlSession.delete("com.itheima.dao.IUserDao.deleteUser",id);//第一个参数为statement
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
Test文件中
/*
测试删除用户
*/
@Test
public void testdelete(){
mappers.deleteUser(48);
}
若数据库表的列名和实体类属性名不一样
则需要 配置 查询结果的列明和实体类属性名的对应关系-
- 直接在Sql执行语句中配置,比较简单,执行快
SELECT id as userId,username as userName,address as userAddress,sex as userSex,birthday as userBirthday FROM USER
2.配置 resultMap,再将Sql语句标签所有的resultType替换为resultMap=“userMap”。方便代码的修改。
<resultMap id="userMap" type="com.itheima.domain.User">
<!--主键字段的对应-->
<id property="userId" column="id"></id>
<!--非主键字段的对应-->
<result property="userName" column="username"></result>
<result property="userAddress" column="address"></result>
<result property="userSex" column="sex"></result>
<result property="userBirthday" column="birthday"></result>
</resultMap>