> 文档中心 > JavaEE——MyBatis持久层框架(2)

JavaEE——MyBatis持久层框架(2)

目录

      • 5.6. 任务 3:添加用户
      • 5.7. 任务 4:UUID 主键策略
      • 5.8. 任务 5:更新用户
      • 5.9. 任务 6:删除用户
      • 5.10. MyBatis 解决了 JDBC 编程的问题

5.6. 任务 3:添加用户

第一步:创建 Mapped Statement ID
在映射文件 userinfo.xml 中添加 Mapped Statement ID,代码如下:

 <insert id="insertUserInfo" parameterType="cn.itlaobing.mybatis.model.UserInfoModel">      <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">     SELECT LAST_INSERT_ID()   </selectKey>   INSERT INTO userinfo(userName,userPass,birthday,gender,address) VALUES(#{userName},#{userPass},#{birthday},#{gender},#{address}); </insert> 

第二步:编写单元测试
在 TestEshop 单元测试类中添加单元测试方法,代码如下:

@Test public void testInsertUser() {   //  通过工厂得到 SqlSession   SqlSession sqlSession = sqlSessionFactory.openSession();   //  插入用户对象   UserInfoModel model = new UserInfoModel();   model.setUserName("宋江");   model.setUserPass("songjiang");    model.setBirthday(new Date());   model.setGender("男");   model.setAddress("山东郓城");   sqlSession.insert("eshop.insertUserInfo", model);   //  提交事务   sqlSession.commit();   //  获取用户信息主键   System.out.println(model.getId());   //  关闭会话   sqlSession.close(); }

第三步:单元测试
运行单元测试,控制台输出日志如下

15:22:11,068 DEBUG insertUserInfo:159 - ==>   Preparing: INSERT INTO userinfo(userName,userPass,birthday,gender,address) VALUES(?,?,?,?,?);   15:22:11,100 DEBUG insertUserInfo:159 - ==> Parameters:  宋江(String), songjiang(String), 2017-09-22 15:22:10.833(Timestamp),  男(String),  山东郓城(String) 15:22:11,100 DEBUG insertUserInfo:159 -   Preparing: SELECT LAST_INSERT_ID()  15:22:11,100 DEBUG insertUserInfo!selectKey:159 - ==> Parameters:  15:22:11,115 DEBUG insertUserInfo!selectKey:159 - <==      Total: 1 15:22:11,115 DEBUG JdbcTransaction:70 - Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4493d195] 新增记录的主键值是:5 
  1. 日志中输出了执行的 sql 语句为 INSERT INTO userinfo(userName,userPass,birthday, gender,address) VALUES(?,?,?,?,?);
  2. 传入参数是 Parameters:宋江(String), songjiang(String), 2017-09-22
    15:22:10.833(Timestamp), 男(String), 山东郓城(String)
  3. 输出结果是:Updates: 1

5.7. 任务 4:UUID 主键策略

使用自增长作为主键生成策略存在缺陷,记录的主键值容易被猜测,从而导致不安全,例如当要删除 id=1 的记录时,如果用户输入 2,导致 id=2,则将第二条记录被删掉。 UUID 是用于生成 36 位长度的用于不重复的字符串,将此字符串作为记录的主键可以避免自增长主键的缺陷。java.util.UUID 类的 randomUUID()方法和MySQL 中的 uuid()函数都可以生成 UUID 字符串。

<insert id="uuid" parameterType="cn.itlaobing.mybatis.model.UserInfoModel">      <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">     SELECT uuid()   </selectKey>   INSERT INTO userinfo(id,userName,userPass,birthday,gender,address)VALUES(#{id},#{userName},#{userPass},#{birthday},#{gender},#{address}); </insert> 

5.8. 任务 5:更新用户

第一步:创建 Mapped Statement ID
在映射文件 userinfo.xml 中添加 Mapped Statement ID,代码如下:

 <update id="updateUserInfo" parameterType="cn.itlaobing.mybatis.model.UserInfoModel">   update userinfo set userName=#{userName},birthday=#{birthday},gender=#{gender},     address=#{address} where id=#{id} </update> 

第二步:编写单元测试
在 TestEshop 单元测试类中添加单元测试方法,代码如下:

@Test public void testUpdateUserInfo() {   //  通过工厂得到 SqlSession   SqlSession sqlSession = sqlSessionFactory.openSession();   //  插入用户对象   UserInfoModel model = new UserInfoModel();   model.setId(5);   model.setUserName("宋江江");   model.setUserPass("songjiang");   model.setBirthday(new Date());   model.setGender("男");   model.setAddress("山东郓城");   sqlSession.update("eshop.updateUserInfo", model);   //  提交事务   sqlSession.commit();   //  关闭会话   sqlSession.close(); } 

第三步:单元测试
运行单元测试,控制台输出日志如下

15:50:39,572 DEBUG updateUserInfo:159 - ==>   Preparing: update userinfo set userName=?,birthday=?,gender=?,address=? where id=?   15:50:39,619 DEBUG updateUserInfo:159 - ==> Parameters:  宋江江(String), 2017-09-22 15:50:39.322(Timestamp),  男(String),  山东郓城(String), 5(Integer) 15:50:39,619 DEBUG updateUserInfo:159 - <==     Updates: 1 15:50:39,619 DEBUG JdbcTransaction:70 - Committing JDBC Connection 
  1. 日志中输出了执行的 sql 语句为 update userinfo set userName=?,birthday=?,gender=?, address=? where id=?
  2. 传入参数是宋江江(String), 2017-09-22 15:50:39.322(Timestamp), 男(String), 山东郓城(String), 5(Integer)
  3. 输出结果是:Updates: 1
  4. 查看数据库,宋江的名字更改为宋江江
  5. 注意:在更新数据时,被更新的 POJO 对象中必须存在主键值

5.9. 任务 6:删除用户

第一步:创建 Mapped Statement ID
在映射文件 userinfo.xml 中添加 Mapped Statement ID,代码如下:

 <delete id="deleteUserInfo" parameterType="java.lang.Integer"> delete from userinfo where id=#{id} </delete> 

第二步:编写单元测试
在 TestEshop 单元测试类中添加单元测试方法,代码如下:

@Test public void testDeleteUserInfo() {   //  通过工厂得到 SqlSession   SqlSession sqlSession = sqlSessionFactory.openSession();   //传入被删除记录的主键值 5   sqlSession.delete("eshop.deleteUserInfo", 5);   //  提交事务   sqlSession.commit();   //  关闭会话   sqlSession.close(); } 

第三步:单元测试
运行单元测试,控制台输出日志如下

15:59:12,021 DEBUG deleteUserInfo:159 - ==>   Preparing: delete from userinfo where id=?  15:59:12,059 DEBUG deleteUserInfo:159 - ==> Parameters: 5(Integer) 15:59:12,069 DEBUG deleteUserInfo:159 - <==     Updates: 1 15:59:12,070 DEBUG JdbcTransaction:70 - Committing JDBC Connection 
  1. 日志中输出了执行的 sql 语句为 delete from userinfo where id=?
  2. 传入参数是 5(Integer)
  3. 输出结果是:Updates: 1
  4. 查看数据库,id=5 的用户被删除

5.10. MyBatis 解决了 JDBC 编程的问题

通过以上对用户的添加、删除、修改、查询的例子,发现 MyBatis 框架让程序开发人员将精力集中在 SQL 本身,而不必将精力放在例如加载驱动、创建 connection、创建 statement、设置参数、结果集检索等 jdbc 繁杂的过程里。解决了 JDBC 编程的问题,具体过程如下:

  1. 数据库连接对象的创建、释放频繁,造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解决此问题。在 SqlMapConfig.xml 中配置数据连接池,使用连接池管理数据库连接。
  2. Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。MyBatis 框架将 Sql 语句配置在映射文件中(mapper.xml)与java 代码分离。
  3. 传入参数繁琐,SQL 语句的 where 条件中占位符的个数可能会变化,Mybatis 自动将 java对象映射至 sql 语句,通过 statement 中的 parameterType 定义输入参数的类型。
  4. 对结果集解析繁琐,sql 变化导致解析代码变化,且解析前需要遍历,Mybatis 自动将 sql执行结果映射至 POJO 对象,通过 statement 中的 resultType 定义输出结果的类型。