一、Mybatis概述

1.1 Mybatis介绍

  MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

  MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

  Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

1.2 JDBC操作数据库

【JDBC】操作步骤

  1、加载数据库驱动

  2、创建并获取数据库链接

  3、创建jdbc statement对象

  4、设置sql语句

  5、设置sql语句中的参数(使用preparedStatement)

  6、通过statement执行sql并获取结果

  7、对sql执行结果进行解析处理

  8、释放资源(resultSet、preparedstatement、connection)

【编写一个JDBC程序】

  1. public static void main(String[] args) {
  2. Connection connection = null;
  3. PreparedStatement preparedStatement = null;
  4. ResultSet resultSet = null;
  5.  
  6. try {
  7. // 加载数据库驱动
  8. Class.forName("com.mysql.jdbc.Driver");
  9.  
  10. // 通过驱动管理类获取数据库链接
  11. connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "admin");
  12. // 定义sql语句 ?表示占位符
  13. String sql = "select * from user where username = ?";
  14. // 获取预处理statement
  15. preparedStatement = connection.prepareStatement(sql);
  16. // 设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
  17. preparedStatement.setString(1, "kevin");
  18. // 向数据库发出sql执行查询,查询出结果集
  19. resultSet = preparedStatement.executeQuery();
  20. // 遍历查询结果集
  21. while (resultSet.next()) {
  22. System.out.println(resultSet.getString("id") + " " + resultSet.getString("username"));
  23. }
  24. } catch (Exception e) {
  25. e.printStackTrace();
  26. } finally {
  27. // 释放资源
  28. if (resultSet != null) {
  29. try {
  30. resultSet.close();
  31. } catch (SQLException e) {
  32. // TODO Auto-generated catch block
  33. e.printStackTrace();
  34. }
  35. }
  36. if (preparedStatement != null) {
  37. try {
  38. preparedStatement.close();
  39. } catch (SQLException e) {
  40. // TODO Auto-generated catch block
  41. e.printStackTrace();
  42. }
  43. }
  44. if (connection != null) {
  45. try {
  46. connection.close();
  47. } catch (SQLException e) {
  48. // TODO Auto-generated catch block
  49. e.printStackTrace();
  50. }
  51. }
  52. }
  53. }

【JDBC问题总结如下】

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

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

  ● 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。

  ● 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。

1.3 Mybatis架构

● mybatis配置

  SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。

  mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。

● 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂

● 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。

● mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。

● Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。

● Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。

● Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

二、Mybatis入门案例

2.1 Mybatis下载

mybatis的代码由github.com管理,下载网址:https://github.com/mybatis/mybatis-3/releases

下载完成解压后文件目录如下:

  mybatis-3.2.7.jar mybatis的核心包

  lib文件夹 mybatis的依赖包所在

  mybatis-3.2.7.pdf mybatis使用手册

2.2 环境搭建

【导入jar包(包括核心jar包、依赖包、数据库驱动包)】

【创建SqlMapConfig.xml配置文件】

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6.  
  7. <properties resource="log4j.properties"/>
  8. <!-- 起别名 包以及包下所有的子包 -->
  9. <typeAliases>
  10. <!-- <typeAlias type="com.kevin.entity.User" alias="User"/> -->
  11. <package name="com.kevin.entity"/>
  12. </typeAliases>
  13.  
  14. <!-- 和spring整合后 environments配置将废除 -->
  15. <environments default="development">
  16. <environment id="development">
  17. <!-- 使用jdbc事务管理 -->
  18. <transactionManager type="JDBC" />
  19. <!-- 数据库连接池 -->
  20. <dataSource type="POOLED">
  21. <property name="driver" value="com.mysql.jdbc.Driver" />
  22. <property name="url"
  23. value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
  24. <property name="username" value="root" />
  25. <property name="password" value="admin" />
  26. </dataSource>
  27. </environment>
  28. </environments>
  29. </configuration>

  SqlMapConfig.xml是mybatis的核心配置文件,配置文件内容为数据源、事务管理。

【编写一个User类】 

  1. package com.kevin.entity;
  2.  
  3. import java.io.Serializable;
  4. import java.util.Date;
  5.  
  6. public class User implements Serializable {
  7. /**
  8. * 创建一个简单的bean
  9. */
  10. private static final long serialVersionUID = 1L;
  11. private Integer id;
  12. private String username;// 用户姓名
  13. private String sex;// 性别
  14. private Date birthday;// 生日
  15. private String address;// 地址
  16.  
  17. public Integer getId() {
  18. return id;
  19. }
  20. public void setId(Integer id) {
  21. this.id = id;
  22. }
  23. public String getUsername() {
  24. return username;
  25. }
  26. public void setUsername(String username) {
  27. this.username = username;
  28. }
  29. public String getSex() {
  30. return sex;
  31. }
  32. public void setSex(String sex) {
  33. this.sex = sex;
  34. }
  35. public Date getBirthday() {
  36. return birthday;
  37. }
  38. public void setBirthday(Date birthday) {
  39. this.birthday = birthday;
  40. }
  41. public String getAddress() {
  42. return address;
  43. }
  44. public void setAddress(String address) {
  45. this.address = address;
  46. }
  47. @Override
  48. public String toString() {
  49. return "User [id=" + id + ", username=" + username + ", sex=" + sex
  50. + ", birthday=" + birthday + ", address=" + address + "]";
  51. }
  52.  
  53. }

【创建sql映射文件User.xml】 

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <!-- namespace:命名空间,用于隔离sql -->
  6.  
  7. <mapper namespace="user">
  8.  
  9. </mapper>

【在SqlMapConfig.xml中加载映射文件】

  1. <mappers>
  2. <!-- <mapper resource="sqlmap/User.xml"/> -->
  3. <!-- <mapper class="com.kevin.mapper.UserMapper"/> -->
  4. <package name="com.kevin.mapper"/>
  5.  
  6. </mappers>

2.3 在Mybatis中实现CRUD操作

【根据id查询用户】

在User.xml中添加select标签,编写sql:

  1. <!-- 通过id查询一个用户 -->
  2. <select id="findUserById" parameterType="Integer" resultType="User">
  3. select * from user where id = #{v}
  4. </select>

创建一个测试类编写测试代码:

  1. /**
  2. * 根据用户id查询
  3. * @throws Exception
  4. */
  5. @Test
  6. public void test() throws Exception{
  7. //加载核心配置文件
  8. String resource = "SqlMapConfig.xml";
  9. InputStream in = Resources.getResourceAsStream(resource);
  10. //创建SqlSessionFactory
  11. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
  12. //创建SqlSession
  13. SqlSession sqlSession = sqlSessionFactory.openSession();
  14.  
  15. //执行sql语句
  16. User user = sqlSession.selectOne("user.findUserById", 10);
  17.  
  18. System.out.println(user);
  19.  
  20. }

【根据用户名称进行模糊查询】

在User.xml中添加select标签,编写sql:

  1. <select id="findUserByName" parameterType="String" resultType="com.kevin.entity.User">
  2. select * from user where username like "%"#{va}"%"
  3. </select>

或者

  1. <select id="findUserByName" parameterType="String" resultType="com.kevin.entity.User">
  2. select * from user where username like '%${value}%'
  3. </select>

编写测试代码:

  1. /**
  2. * 根据用户名称模糊查询
  3. * @throws IOException
  4. */
  5. @Test
  6. public void test2() throws Exception{
  7. //加载核心配置文件
  8. String resource = "SqlMapConfig.xml";
  9. InputStream in = Resources.getResourceAsStream(resource);
  10. //创建sqlsessionfactory
  11. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
  12. //创建sqlsession
  13. SqlSession sqlSession = sqlSessionFactory.openSession();
  14.  
  15. //执行sql语句
  16. List<User> users = sqlSession.selectList("user.findUserByName","五");
  17. for (User user : users) {
  18. System.out.println(user);
  19. }
  20. }

小结:区分#{ }和${ }

  #{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。

  ${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。

parameterType和resultType

  parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。

  resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中

selectOne和selectList

  selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:

  selectList可以查询一条或多条记录。

【添加用户】

在User.xml中添加insert标签,编写sql:

  1. <!-- 添加用户 -->
  2. <insert id="insertUser" parameterType="com.kevin.entity.User">
  3. <selectKey keyProperty="id" resultType="Integer" order="AFTER">
  4. select LAST_INSERT_ID()
  5. </selectKey>
  6. insert into user(username,birthday,address,sex)
  7. values(#{username},#{birthday},#{address},#{sex})
  8. </insert>

  其中,LAST_INSERT_ID( )是mysql的函数,返回auto_increment自增列新记录id值。

  如果自增主键形式为uuid,可使用如下配置:

  1. <selectKey keyColumn="id" keyProperty="id" order="BEFORE"
  2. resultType="string">
  3. SELECT LAST_INSERT_ID()
  4. </selectKey>

编写测试代码:

  1. /**
  2. * 保存用户
  3. */
  4. @Test
  5. public void test3() throws Exception{
  6. String resource = "SqlMapConfig.xml";
  7. InputStream in = Resources.getResourceAsStream(resource);
  8. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
  9. SqlSession sqlSession = sqlSessionFactory.openSession();
  10.  
  11. User user = new User();
  12. user.setUsername("Michael");
  13. user.setBirthday(new Date());
  14. user.setAddress("China");
  15. user.setSex("Male");
  16. sqlSession.insert("user.insertUser",user);
  17. sqlSession.commit();
  18.  
  19. //获取最新保存用户的id
  20. System.out.println(user.getId());
  21. }

【更新用户】

在User.xml中添加update标签,编写sql:

  1. <!-- 更新用户 -->
  2. <update id="updateUserById" parameterType="com.kevin.entity.User">
  3. update user
  4. set username = #{username},sex = #{sex},birthday = #{birthday},address = #{address}
  5. where id = #{id}
  6. </update>

编写测试代码:

  1. /**
  2. * 更新用户
  3. * @throws Exception
  4. */
  5. @Test
  6. public void test4() throws Exception{
  7. String resource = "SqlMapConfig.xml";
  8. InputStream in = Resources.getResourceAsStream(resource);
  9. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
  10. SqlSession sqlSession = sqlSessionFactory.openSession();
  11.  
  12. User user = new User();
  13. user.setId(24);
  14. user.setUsername("Michel");
  15. user.setBirthday(new Date());
  16. user.setAddress("America");
  17. user.setSex("Female");
  18. sqlSession.update("user.updateUserById", user);
  19. sqlSession.commit();
  20. }

【删除用户】

在User.xml中添加delete标签,编写sql:

  1. <!-- 删除用户 -->
  2. <delete id="deleteUserById" parameterType="Integer">
  3. delete from user where id = #{id}
  4. </delete>

编写测试代码:

  1. /**
  2. * 删除用户
  3. * @throws Exception
  4. */
  5. @Test
  6. public void test5() throws Exception{
  7. String resource = "SqlMapConfig.xml";
  8. InputStream in = Resources.getResourceAsStream(resource);
  9. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
  10. SqlSession sqlSession = sqlSessionFactory.openSession();
  11.  
  12. sqlSession.delete("user.deleteUserById", 27);
  13. sqlSession.commit();
  14. }

三、Mybatis框架优势(面试常考)

3.1 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定义输出结果的类型。

3.2 Mybatis与Hibernate有哪些不同

  ● Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。

  ● Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。

  ● Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。

  总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。

四、原始Dao开发方法

  使用MyBatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper动态代理开发方法。

【SqlSession】

  SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。

  SqlSession通过SqlSessionFactory创建。

  SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。

【SqlSessionFactoryBuilder】

  SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory创建的。所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围即方法体内局部变量。

【SqlSessionFactory】

  SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory。

【SqlSession】

  SqlSession是一个面向用户的接口,sqlSession中定义了数据库操作方法。

  每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。

  原始Dao开发方法需要编写Dao类和Dao实现类

4.1 编写映射文件如下

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,后面会讲 -->
  6.  
  7. <mapper namespace="com.kevin.mapper.UserMapper">
  8. <!-- 通过id查询一个用户 -->
  9. <select id="findUserById" parameterType="Integer" resultType="User">
  10. select * from user where id = #{v}
  11. </select>
  12.  
  13. <!-- 根据用户名称模糊查询
  14. #{} 占位符 ? == ''
  15. ${} 字符串拼接 '% %'
  16. -->
  17. <select id="findUserByName" parameterType="String" resultType="com.kevin.entity.User">
  18. select * from user where username like "%"#{va}"%"
  19. </select>
  20.  
  21. <!-- 添加用户 -->
  22. <!-- selectKey 标签实现主键返回 -->
  23. <!-- keyColumn:主键对应的表中的哪一列 -->
  24. <!-- keyProperty:主键对应的pojo中的哪一个属性 -->
  25. <!-- order:设置在执行insert语句前执行查询id的sql,孩纸在执行insert语句之后执行查询id的sql -->
  26. <!-- resultType:设置返回的id的类型 -->
  27. <insert id="insertUser" parameterType="com.kevin.entity.User">
  28. <selectKey keyProperty="id" resultType="Integer" order="AFTER">
  29. select LAST_INSERT_ID()
  30. </selectKey>
  31. insert into user(username,birthday,address,sex)
  32. values(#{username},#{birthday},#{address},#{sex})
  33. </insert>
  34.  
  35. <!-- 更新用户 -->
  36. <update id="updateUserById" parameterType="com.kevin.entity.User">
  37. update user
  38. set username = #{username},sex = #{sex},birthday = #{birthday},address = #{address}
  39. where id = #{id}
  40. </update>
  41.  
  42. <!-- 删除用户 -->
  43. <delete id="deleteUserById" parameterType="Integer">
  44. delete from user where id = #{id}
  45. </delete>
  46.  
  47. </mapper>

4.2 Dao接口

  1. package com.kevin.dao;
  2.  
  3. import com.kevin.entity.User;
  4.  
  5. public interface UserDao {
  6.  
  7. public User selectUserById(Integer id);
  8.  
  9. }

4.3 Dao接口实现类

  1. package com.kevin.dao.impl;
  2.  
  3. import org.apache.ibatis.session.SqlSession;
  4. import org.apache.ibatis.session.SqlSessionFactory;
  5. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  6.  
  7. import com.kevin.dao.UserDao;
  8. import com.kevin.entity.User;
  9.  
  10. public class UserDaoImpl implements UserDao {
  11.  
  12. private SqlSessionFactory sqlSessionFactory;
  13. //注入SQLSessionFactory对象
  14. public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
  15. this.sqlSessionFactory = sqlSessionFactory;
  16. }
  17. //根据id查询客户
  18. public User selectUserById(Integer id){
  19. SqlSession sqlSession = sqlSessionFactory.openSession();
  20. return sqlSession.selectOne("user.findUserById", id);
  21. }
  22.  
  23. }

4.4 Dao测试

  1. package com.kevin.junit;
  2.  
  3. import java.io.InputStream;
  4.  
  5. import org.apache.ibatis.io.Resources;
  6. import org.apache.ibatis.session.SqlSessionFactory;
  7. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  8. import org.junit.Before;
  9. import org.junit.Test;
  10.  
  11. import com.kevin.dao.UserDao;
  12. import com.kevin.dao.impl.UserDaoImpl;
  13. import com.kevin.entity.User;
  14.  
  15. public class MybatisTestdao {
  16.  
  17. private SqlSessionFactory sqlSessionFactory;
  18. @Before
  19. public void Before() throws Exception{
  20. //加载核心配置文件
  21. String resource = "SqlMapConfig.xml";
  22. InputStream in = Resources.getResourceAsStream(resource);
  23. //创建sqlsessionfactory
  24. sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
  25. }
  26.  
  27. @Test
  28. public void test(){
  29.  
  30. UserDao userDao = new UserDaoImpl(sqlSessionFactory);
  31. User user = userDao.selectUserById(30);
  32. System.out.println(user);
  33. }
  34.  
  35. }

4.5 产生的问题

  ● Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法

  ● 调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不得于开发维护。

五、Mapper动态代理方式

5.1 开发规范

  Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper接口开发需要遵循以下规范:

  ● Mapper.xml文件中的namespace与mapper接口的类路径相同。

  ● Mapper接口方法名和Mapper.xml中定义的每个statement的id相同

  ● Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同

  ● Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

5.2 创建UserMapper.xml映射文件

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,后面会讲 -->
  6.  
  7. <mapper namespace="com.kevin.mapper.UserMapper">
  8. <!-- 通过id查询一个用户 -->
  9. <select id="findUserById" parameterType="Integer" resultType="User">
  10. select * from user where id = #{v}
  11. </select>
  12.  
  13. <!-- 根据用户名称模糊查询
  14. #{} 占位符 ? == ''
  15. ${} 字符串拼接 '% %'
  16. -->
  17. <select id="findUserByName" parameterType="String" resultType="User">
  18. select * from user where username like "%"#{va}"%"
  19. </select>
  20.  
  21. <!-- 添加用户 -->
  22. <insert id="insertUser" parameterType="User">
  23. <selectKey keyProperty="id" resultType="Integer" order="AFTER">
  24. select LAST_INSERT_ID()
  25. </selectKey>
  26. insert into user(username,birthday,address,sex)
  27. values(#{username},#{birthday},#{address},#{sex})
  28. </insert>
  29.  
  30. <!-- 更新用户 -->
  31. <update id="updateUserById" parameterType="User">
  32. update user
  33. set username = #{username},sex = #{sex},birthday = #{birthday},address = #{address}
  34. where id = #{id}
  35. </update>
  36.  
  37. <!-- 删除用户 -->
  38. <delete id="deleteUserById" parameterType="Integer">
  39. delete from user where id = #{id}
  40. </delete>
  41.  
  42. </mapper>

5.3 创建UserMapper接口文件

  1. package com.kevin.mapper;
  2.  
  3. import java.util.List;
  4.  
  5. import com.kevin.entity.User;
  6.  
  7. public interface UserMapper {
  8.  
  9. /**
  10. * 遵循四个原则
  11. * 接口方法名和user.xml文件id值相同
  12. * 接口返回值和user.xml文件返回值相同
  13. * 接口入参类型和user.xml文件入参类型相同
  14. * 命名空间进行绑定
  15. */
  16.  
  17. public User findUserById(Integer id);
  18.  
  19. public List<User> findUserByName(String username);
  20.  
  21. public void insertUser(User user);
  22.  
  23. public void updateUserById(User user);
  24.  
  25. public void deleteUserById(Integer id);
  26.  
  27. }

5.4 加载UserMapper配置文件

在SqlMapConfig.xml文件中进行如下配置:

  1. <mappers>
  2. <!-- <mapper resource="sqlmap/User.xml"/> -->
  3. <!-- <mapper class="com.kevin.mapper.UserMapper"/> -->
  4. <package name="com.kevin.mapper"/>
  5.  
  6. </mappers>

5.5 编写测试类

  1. package com.kevin.junit;
  2.  
  3. import java.io.InputStream;
  4. import java.util.Date;
  5. import java.util.List;
  6.  
  7. import org.apache.ibatis.io.Resources;
  8. import org.apache.ibatis.session.SqlSession;
  9. import org.apache.ibatis.session.SqlSessionFactory;
  10. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  11. import org.junit.Test;
  12.  
  13. import com.kevin.entity.User;
  14. import com.kevin.mapper.UserMapper;
  15.  
  16. public class MybatisMapper {
  17.  
  18. /**
  19. * 测试mapper接口方式
  20. * @throws Exception
  21. */
  22. //根据用户id查询
  23. @Test
  24. public void findUserById() throws Exception{
  25. String resource = "SqlMapConfig.xml";
  26. InputStream in = Resources.getResourceAsStream(resource);
  27. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
  28. SqlSession sqlSession = sqlSessionFactory.openSession();
  29.  
  30. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  31. User user = userMapper.findUserById(30);
  32. System.out.println(user);
  33. }
  34.  
  35. //根据用户名称查询
  36. @Test
  37. public void findUserByName() throws Exception{
  38. String resource = "SqlMapConfig.xml";
  39. InputStream in = Resources.getResourceAsStream(resource);
  40. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
  41. SqlSession sqlSession = sqlSessionFactory.openSession();
  42.  
  43. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  44. List<User> users = userMapper.findUserByName("王");
  45. for (User user : users) {
  46. System.out.println(user);
  47. }
  48. }
  49.  
  50. //添加用户
  51. @Test
  52. public void insertUser() throws Exception{
  53. String resource = "SqlMapConfig.xml";
  54. InputStream in = Resources.getResourceAsStream(resource);
  55. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
  56. SqlSession sqlSession = sqlSessionFactory.openSession();
  57.  
  58. User user = new User();
  59. user.setUsername("Kevin");
  60. user.setAddress("China");
  61. user.setBirthday(new Date());
  62. user.setSex("Male");
  63. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  64. userMapper.insertUser(user);
  65. sqlSession.commit();
  66. }
  67.  
  68. //更新用户
  69. @Test
  70. public void updateUserById() throws Exception {
  71. String resource = "SqlMapConfig.xml";
  72. InputStream in = Resources.getResourceAsStream(resource);
  73. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
  74. SqlSession sqlSession = sqlSessionFactory.openSession();
  75.  
  76. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  77. User user = new User();
  78. user.setId(25);
  79. user.setUsername("Jackson");
  80. user.setAddress("British");
  81. user.setBirthday(new Date());
  82. user.setSex("Male");
  83. userMapper.updateUserById(user);
  84. sqlSession.commit();
  85.  
  86. }
  87.  
  88. //删除用户
  89. @Test
  90. public void deleteUserById() throws Exception {
  91. String resource = "SqlMapConfig.xml";
  92. InputStream in = Resources.getResourceAsStream(resource);
  93. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
  94. SqlSession sqlSession = sqlSessionFactory.openSession();
  95.  
  96. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  97. userMapper.deleteUserById(32);
  98. sqlSession.commit();
  99.  
  100. }
  101.  
  102. }

5.6 小结

selectOne和selectList

  动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。

namespace

  mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。

六、SqlMapConfig.xml配置文件详解

6.1 配置内容

SqlMapConfig.xml中配置的内容和顺序如下:(其中黑体部分是需要重点掌握,其余已经废弃不用或不常用)

  properties(属性)

  settings(全局配置参数)

  typeAliases(类型别名)

  typeHandlers(类型处理器)

  objectFactory(对象工厂)

  plugins(插件)

  environments(环境集合属性对象)

  environment(环境子属性对象)

  transactionManager(事务管理)

  dataSource(数据源)

  mappers(映射器)

6.2 typeAliases(类型别名)

别名

映射的类型

_byte

byte

_long

long

_short

short

_int

int

_integer

int

_double

double

_float

float

_boolean

boolean

string

String

byte

Byte

long

Long

short

Short

int

Integer

integer

Integer

double

Double

float

Float

boolean

Boolean

date

Date

decimal

BigDecimal

bigdecimal

BigDecimal

map

Map

6.3 自定义别名

  1. <typeAliases>
  2. <!-- <typeAlias type="com.kevin.entity.User" alias="User"/> -->
  3. <package name="com.kevin.entity"/>
  4. </typeAliases>

6.4 mappers映射器

Mapper配置的几种方法:

  1. <mappers>
  2. <!-- <mapper resource="sqlmap/User.xml"/> -->
  3. <!-- <mapper class="com.kevin.mapper.UserMapper"/> -->
  4. <package name="com.kevin.mapper"/>
  5.  
  6. </mappers>

● <mapper resource=" " />

使用相对于类路径的资源(现在的使用方式)

如:<mapper resource="sqlmap/User.xml" />

● <mapper class=" " />

使用mapper接口类路径

如:<mapper class="com.kevin.mapper.UserMapper"/>

注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

● <package name=""/>

注册指定包下的所有mapper接口

如:<package name="com.kevin.mapper"/>

注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

Mybatis学习笔记之一(环境搭建和入门案例介绍)的更多相关文章

  1. Mybatis学习笔记之---环境搭建与入门

    Mybatis环境搭建与入门 (一)环境搭建 (1)第一步:创建maven工程并导入jar包 <dependencies> <dependency> <groupId&g ...

  2. Android Studio 学习笔记(一)环境搭建、文件目录等相关说明

    Android Studio 学习笔记(一)环境搭建.文件目录等相关说明 引入 对APP开发而言,Android和iOS是两大主流开发平台,其中区别在于 Android用java语言,用Android ...

  3. MyBatis学习总结(一)简单入门案例

    MyBatis学习总结(一)简单入门案例 主要内容:本文主要通过对数据库中的use表进行增删改查总结mybatis的环境搭建和基本入门使用 一.需要的jar包: 1.核心包 2.依赖包 3.jdbc数 ...

  4. (十八)整合Nacos组件,环境搭建和入门案例详解

    整合Nacos组件,环境搭建和入门案例详解 1.Nacos基础简介 1.1 关键特性 1.2 专业术语解释 1.3 Nacos生态圈 2.SpringBoot整合Nacos 2.1 新建配置 2.2 ...

  5. 04 Mybatis 框架的环境搭建及入门案例

    1.搭建 Mybatis 开发环境 mybatis的环境搭建 第一步:创建maven工程并导入坐标 第二步:创建实体类和dao的接口 第三步:创建Mybatis的主配置文件 SqlMapConifg. ...

  6. 我的Java学习笔记 -开发环境搭建

    开始学习Java~ 一.Java简介 Java编程语言是一种简单.面向对象.分布式.解释型.健壮安全.与系统无关.可移植.高性能.多线程和动态的语言. Java分为三个体系: JavaSE(J2SE) ...

  7. Django学习笔记 开发环境搭建

    为什么使用django?1.支持快速开发:用python开发:数据库ORM系统,并不需要我们手动地构造SQL语句,而是用python的对象访问数据库,能够提升开发效率.2.大量内置应用:后台管理系统a ...

  8. cocos2d-x lua 学习笔记(1) -- 环境搭建

    Cocos2d-x 3.0以上版本的环境搭建和之前的Cocos2d-x 2.0 版差异较大的,同时从Cocos2d-x 3.0项目打包成apk安卓应用文件,搭建安卓环境的步骤有点繁琐,但搭建一次之后, ...

  9. SpringData JPA的学习笔记之环境搭建

    一.环境搭建 1.加入jar包   spring jar+jpa jar +springData jar >>SpringData jar包     2.配置applicationCont ...

随机推荐

  1. OAuth 2.0中文译本

    (一)背景知识 OAuth 2.0很可能是下一代的“用户验证和授权”标准,目前在国内还没有很靠谱的技术资料.为了弘扬“开放精神”,让业内的人更容易理解“开放平台”相关技术,进而长远地促进国内开放平台领 ...

  2. how to select checkbox on cli environment?

    generally , u can focus on this checkbox and press blank key Ok,that's shit.    

  3. webstorm配置eslint【标记错误,修复错误】

    项目中经常用到eslint语法,结合个人经验,用webstorm配置eslint "文件"->"默认设置"->"语言&框架&quo ...

  4. 算法库中heap应用

    STL中make_heap 的接口为: default (1) template <class RandomAccessIterator> void make_heap (RandomAc ...

  5. 华为专家谈CMDB建设

    CMDB成功的关键因素 对于CMDB项目的失败,普遍的解释是:没有数据的消费场景.工具和技术不行.流程管控不足. 从我自身的实践来看,我对此是有不同看法的.上述原因的确会影响人们使用CMDB,严重时甚 ...

  6. memcached server install(WSL)

    prepare:0) libevent-dev1) libseccomp-dev2) build-essential3) automake install: https://www.liquidweb ...

  7. C#高级编程笔记之第二章:核心C#

    变量的初始化和作用域 C#的预定义数据类型 流控制 枚举 名称空间 预处理命令 C#编程的推荐规则和约定 变量的初始化和作用域 初始化 C#有两个方法可以一确保变量在使用前进行了初始化: 变量是字段, ...

  8. Lua读取CSV文件到table中

    创建Lua函数载入CSV文件并保存到表中的函数: function GetLines(fileName) indx = 0 myLines ={} for line in io.line(string ...

  9. EF Core Model更新迁移

    EF Core 迁移 感觉就是以前EF Code First的自动同步数据库功能 内容:在你新增.更新TableModel后,如何自动化的更新DB中的真实Table.以及对这些更改进行一个版本控制. ...

  10. 3d轮播图(另一种方式,可以实现的功能更为强大也更为灵活,简单一句话,比酷狗优酷的炫)

    前不久我做了一个3d仿酷狗的轮播图,用的技术原理就是简单的jquery遍历+css样式读写. 这次呢,我们换一种思路(呵呵其实换汤不换药),看到上次那个轮播吗?你有没有发现用jquery的animat ...