Bootstrap

MyBatis最佳实践:提升数据库交互效率的秘密武器

第一章:框架的概述:

  1. MyBatis 框架的概述:
    1. MyBatis 是一个优秀的基于 Java 的持久框架,内部对 JDBC 做了封装,使开发者只需要关注 SQL 语句,而不关注 JDBC 的代码,使开发变得更加的简单
    2. MyBatis 通过 XML 或者注解的方式将要执行的各种 Statement 对象配置起来,通过 Java  对象和 statement 中 SQL 后,最终将结果已 Java 对象返回
    3. MyBatis 采用了 ORM 的思想
  2. ORM 思想:
    1. 在 web 阶段学习 JavaBean 更正确的叫法是:实体类
    2. ORM:object  relational  mapping  对象映射关系
      1. O:面向对象领域的 Object(JavaBean 对象)
      2. R:关系数据库领域的 Relational(表的结构)
      3. M:映射 Mapping(XML 的配置文件)、
    3. 让实体类和数据库表进行 一 一  对应关系
      1. 先让实体类和数据库表对应
      2. 再让实体类属性和表里面字段对应
    4. 不需要直接操作数据库表,直接操作表对应的实体类对象即可
  3. 推荐插件:

第二章:MyBatis 的入门程序(重点)

  1. 创建数据库和表结构:
    create database mybatis_demo;
    use mybatis_demo;
    ​
    CREATE TABLE `user` (
      `id` int(11) NOT NULL auto_increment,
      `username` varchar(32) NOT NULL COMMENT '用户名称',
      `birthday` datetime default NULL COMMENT '生日',
      `sex` char(1) default NULL COMMENT '性别',
      `address` varchar(256) default NULL COMMENT '地址',
      PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    ​
    insert  into `user`(`id`,`username`,`birthday`,`sex`,`address`) values 
    (1,'老王','2018-02-27 17:47:08','男','北京'),
    (2,'熊大','2018-03-02 15:09:37','女','上海'),
    (3,'熊二','2018-03-04 11:34:34','女','深圳'),
    (4,'光头强','2018-03-04 12:04:06','男','广州');
  2. MyBatis 的入门程序:
    1. 创建 maven 项目,Java 工程即可
    2. 引入坐标:
      1. 引入 MyBatis 的 3.4.5 的版本的坐标
      2. 引入 MySQL 驱动的 jar 包,5.1.6 版本
      3. 引入 Junit 单元测试的 jar 包
      4. 引入 log4h 的 jar 包,1.2.12 版本(需要引入log4j.propertiees 的配置文件)
        <dependencies>
            <!--mybatis核心包-->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.5</version>
            </dependency>
            <!--mysql驱动包-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.6</version>
            </dependency>
            <!-- 单元测试 -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.10</version>
                <scope>test</scope>
            </dependency>
            <!-- 日志 -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
        </dependencies>
    3. 编写 User 的实现类,属性尽量使用包装类型:
      public class User implements Serializable {
          private Integer id;
          private String username;
          private Date birthday;
          private String sex;
          private String address;
      
          public Integer getId() {
              return id;
          }
      
          public void setId(Integer id) {
              this.id = id;
          }
      
          public String getUsername() {
              return username;
          }
      
          public void setUsername(String username) {
              this.username = username;
          }
      
          public Date getBirthday() {
              return birthday;
          }
      
          public void setBirthday(Date birthday) {
              this.birthday = birthday;
          }
      
          public String getSex() {
              return sex;
          }
      
          public void setSex(String sex) {
              this.sex = sex;
          }
      
          public String getAddress() {
              return address;
          }
      
          public void setAddress(String address) {
              this.address = address;
          }
      
          @Override
          public String toString() {
              return "User{" +
                      "id=" + id +
                      ", username='" + username + '\'' +
                      ", birthday=" + birthday +
                      ", sex='" + sex + '\'' +
                      ", address='" + address + '\'' +
                      '}';
          }
      }
    4. 编写 UserMapper 的接口和方法(即 Spring 框架中 UserDao 接口):
      public interface UserMapper {
          public List<User> selectAll;
      }
    5. 在 resources 目录下,创建 mapper 文件夹。编写 Usermapper.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.qcby.mapper.UserMapper">
      
          <select id="findAll" resultType="com.qcby.model.User">
              select * from user;
          </select>
      </mapper>
      1. mapper  namespace="com.qcby.mapper.UserMapper":叫名称空间,表明以后查找 UserMapper 接口中的 findAll 方法
      2. select  id = "findAll" 中的 id 属性编写的 UserMapper 接口中方法的名称,固定写法
      3. resultType = "com.qcby.model.User":表明的是 findAll 方法的返回值类型
    6. 编写配置文件,在 resources 目录下创建 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">
      <configuration>
          <!-- 配置具体的环境 -->
          <environments default="mysql">
              <environment id="mysql">
                  <transactionManager type="JDBC"></transactionManager>
                  <!-- 配置是否需要使用连接池, POOLED 使用,UNPOOLED 不适用-->
                  <dataSource type="POOLED">
                      <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                      <property name="url" value="jdbc:mysql:///mybatis_demo"/>
                      <property name="username" value="root"/>
                      <property name="password" value="root"/>
                  </dataSource>
              </environment>
          </environments>
      
          <!-- 加载映射的配置文件 -->
          <mappers>
              <mapper resource="Mapper/UserMapper.xml"/>
          </mappers>
      
      </configuration>
    7. 编写入门程序(重点掌握入门的步骤):
      import com.qcby.mapper.UserMapper;
      import com.qcby.model.User;
      import org.apache.ibatis.io.Resources;
      import org.apache.ibatis.session.SqlSession;
      import org.apache.ibatis.session.SqlSessionFactory;
      import org.apache.ibatis.session.SqlSessionFactoryBuilder;
      import org.junit.Test;
      
      import java.io.IOException;
      import java.io.InputStream;
      import java.util.List;
      
      public class MyBatisDemo {
          
          @Test
          public void run() throws Exception {
              //加载主配置文件,目的是构建 SqlSessionFactory 的对象
              InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
      
              //创建 SqlSSessionFactory 对象
              SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
      
              //使用 SqlSessionFactory 工厂对象创建 SqlSession 对象
              SqlSession session = factory.openSession();
      
              //通过 session 创建 UserMapper 接口的代理对象
              UserMapper mapper = session.getMapper(UserMapper.class);
      
              //调用 findAll 方法
              List<User> list = mapper.findAll();
      
              //遍历集合并输出
              for (User u : list){
                  System.out.println(u);
              }
      
              //释放资源
              session.close();
              in.close();
          }
      }

第三章:代理 Dao 方式的 CURD 操作

  1. Dao 方式的增删改查:
    1. 创建项目
    2. 注意:除了查询方法之外,其他增删改操作需要进行 session.commit 提交
    3.  UserMapper 接口代码:
      public interface UserMapper {
          public List<User> findAll();
      
          //根据 id 查询
          public User findById(Integer id);
      
          // 插入
          public void insert(User user);
      
          //修改
          public void update(User user);
      
      
          //删除
          public void delete(int id);
      
          //根据姓名模糊查询
          public List<User> findByName(String username);
      
          //查询总数
          public Integer findByCount();
      }
    4. UserMapper.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.qcby.mapper.UserMapper">
      
          <!--保存操作-->
          <insert id="insert" parameterType="com.qcby.model.User">
              /*
              keyProperty表示要返回的属性名称
              order取值AFTER表示插入数据后的行为
              resultType表示返回值的类型
              */
              <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
                  select last_insert_id();
              </selectKey>
              insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
          </insert>
      
          <!-- 修改 -->
          <update id="update" parameterType="com.qcby.model.User">
              update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
          </update>
      
          <!-- 根据 id 删除 -->
          <delete id="delete" parameterType="integer">
              delete from user where id = #{id}
          </delete>
      
          <!-- 查询所有 -->
          <select id="findAll" resultType="com.qcby.model.User" >
              select * from user;
          </select>
      
          <!-- 根据 id 查询 -->
          <select id="findById" resultType="com.qcby.model.User">
              select * from user where id=#{id};
          </select>
      
          <!-- 根据姓名模糊查询-->
          <select id="findByName" parameterType="string" resultType="com.qcby.model.User">
              /**
                第一种方式的 SQL 语句
             */
      --        select * from user where username like #{username}
             /**
               第二种 SQL 语句的编写,强调: '%${value}%' 不能修改,固定写法(推荐使用)
               注意:使用第二种 SQL 写法时需要把 SQL 中的注释全部删除否则会报错
              */
              select * from user where username like %${value}%
          </select>
      
          <!-- 查询总数量 -->
          <select id="findByCount" resultType="java.lang.Integer">
              select count(*) from user;
          </select>
      
      </mapper>
    5. 测试代码:
      public class MyBatisDemo {
      
          private InputStream in;
          private SqlSession session;
          private UserMapper userMapper;
      
          @Before
          public void init() throws IOException {
              //加载配置文件
              in = Resources.getResourceAsStream("SqlMapConfig.xml");
      
              //创建工厂对象
              SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
      
              //创建 Session 对象
              session = factory.openSession();
      
              //获取到代理对象
              userMapper = session.getMapper(UserMapper.class);
          }
      
          @After
          public void dstory() throws IOException {
              in.close();
              session.close();
          }
      
          //查询所有
          @Test
          public void fundAll() throws IOException {
              List<User> users = userMapper.findAll();
              for (User u : users){
                  System.out.println(u);
              }
      
              in.close();
          }
      
          //根据 id 查询
          @Test
          public void findById() throws IOException {
              User user = userMapper.findById(1);
              System.out.println(user);
              in.close();
          }
      
          //插入方法
          @Test
          public void insert() throws IOException {
              User user = new User();
              user.setAddress("河北");
              user.setBirthday(new Date());
              user.setSex("男");
              user.setUsername("张翰里");
              System.out.println(user);
              userMapper.insert(user);
              session.commit();
              in.close();
          }
      
          //修改方法
          @Test
          public void updage() throws IOException {
              User user = new User();
              user.setId(1);
              user.setAddress("河北");
              user.setBirthday(new Date());
              user.setSex("男");
              user.setUsername("张翰里");
              userMapper.update(user);
              session.commit();
              in.close();
          }
      
          //删除方法
          @Test
          public void delete() throws IOException {
              userMapper.delete(2);
              session.commit();
              in.close();
          }
      
          //模糊查询
          @Test
          public void findByName() throws IOException {
              List<User> list = userMapper.findByName("%张%");
              for(User u : list){
                  System.out.println(u);
              }
              in.close();
          }
      
          //查询总量
          @Test
          public void findCount(){
              System.out.println(userMapper.findByCount());
          }
      }
;