MyBatis的学习

为什么学Mybatis?
  1. 目前最主流的持久层框架为hibernate与mybatis,而且国内目前情况使用Mybatis的公司比hibernate要多。
  2. Hibernate学习门槛不低,要精通门槛更高。门槛高在怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate缓存与数据加载策略方面需要你的经验和能力都很强才行。国内目前前的情况精通hibernate技术大牛非常少。
  3. sql优化方面,Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。当然了,Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。说得更深入一些,如果有个查询要关联多张表,比如5张表,10张表时,而且,我们要取的字段只是其中几张表的部分字段。这时用hibernate时就会显得非常力不从心。就算用hibernate的sqlquery,后续的维护工作也会让人发狂。  

需求列表

根据用户ID查询用户信息
根据用户名查找用户列表
添加用户
修改用户
删除用户

  1. 工程搭建

- 导入依赖jar包
- 配置SqlMapConfig.xml
- 配置log4j.properties
- 编写pojo类
- 配置sql查询的映射文件,加载映射文件,在SqlMapConfig.xml配置mappers节点


项目目录



核心配置文件(右键项目 ——> Source  Folder ——> 新建conf文件夹)  
(在conf文件夹中新建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>

     <!-- 别名的定义 -->
     <typeAliases>
          <!-- 定义单个别名 -->
        <!--  <typeAlias alias="user" type="com.zwk.pojo.User"/> -->

          <!-- 定义别名:包描述,别名就是类的全称不区分大小写   推荐这种方式-->
          <package name="com.zwk.pojo.User"/>
     </typeAliases>

     <!-- 和spring整合后 environments配置将废除,Spring会覆盖这个配置 -->
     <environments default="development">     //  默认的环境ID(比如:default:"development")development : 开发模式    work : 工作模式     test:测试环境
         <environment id="development">     // 每个 environment 元素定义的环境 ID(比如:id=”development”)。
              <!-- 使用jdbc事务管理 -->
         <!-- 事务管理器有两种:type="[ JDBC | MANAGED ]":
    JDBC:这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务范围。
    MANAGED :这个配置从来都不提交和回滚一个连接,而是让容器来管理事务的整个生命周期(比如JEE应用服务的上下文)。
    默认情况下他会关闭连接,然而一些容器并不希望这样,因此需要将closeConnection属性设置为false来阻止它默认的关闭行为。 -->
              <transactionManager type="JDBC" />      
              <!-- 数据库连接池 -->
              <dataSource type="POOLED">     // 三种内建的数据源类型:type=[ UNPOOLED | POOLED | JNDI ]
                   <property name="driver" value="${jdbc.driver}" />
                   <property name="url" value="${jdbc.url}" />
                   <property name="username" value="${jdbc.username}" />
                   <property name="password" value="${jdbc.password}" />
              </dataSource>
          </environment>

          <!-- 测试环境 -->
          <environment id="test">      
              <transactionManager type="JDBC" />
              <!-- 数据库连接池 -->
              <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driver}" />
                   <property name="url" value="${jdbc.url}" />
                   <property name="username" value="${jdbc.username}" />
                   <property name="password" value="${jdbc.password}" />  
              </dataSource>
          </environment>
     </environments>

     <!-- 加载映射文件 有三种方式    resource、class、url  -->
     <mappers>
          <!-- resource方式 加载一个映射文件  在根目录下 -->
          <mapper resource="mybatis/user.xml"/>
          <mapper resource="mybatis/UserMapper.xml"/>

          <!-- class方式加载  映射文件,类加载器规则:
               1、映射文件必需与接口文件同一目录下
               2、映射文件的名称必需与接口名一致
          -->
          <!-- <mapper class="com.itheima.mybatis.mapper.UserMapper"/> -->

          <!-- 映射文件的包扫描,规则(推荐使用):
               扫描 com.itheima.mybatis.mapper 包下所有的映射文件
               1、映射文件必需与接口文件同一目录下
               2、映射文件的名称必需与接口名一致
          -->
          <!-- <package name="com.itheima.mybatis.mapper"/> -->
     
     <!-- url方式加载映射文件 -->
      <mapper url="D://user.xml"/>                               
     </mappers>
</configuration>



jdbc.properties(在conf文件中新建user.xml)
      注意:数据库账号和密码是否需要更改
 
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456

  映射文件(在conf文件中新建User.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">
<!-- namespace:命名空间,用于隔离sql语句的,相当于java包,后续有重要作用
      #{}:占位符,相当于jdbc的? 如果parameterType为基本数据类型时参数可随意填写,推荐使用
      ${}:字符串拼接指令,如果入参为普通数据类型时,括号里只能写value
 -->


   <!-- 在 SqlMapConfig.xml 中已经设置了别名 为user --> 
  <mapper namespace="user">
     <!-- id:sql语句的唯一标识,sql id
           parameterType:入参数据类型
           resultType:查询结果的数据类型,这里为了好理解就不使用别名了。若要使用别名,只需把 com.zwk.pojo.User 改为 user 就行了
     -->
     <select id="getUserById" parameterType="int" resultType="com.zwk.pojo.User">
          SELECT * FROM USER WHERE id = #{id1}  
     </select>

     <!-- resultType:返回结果为集合时,只需设置为集合中每一个元素的数据类型就可 -->
     <select id="getUserByUserName" parameterType="string" resultType="com.zwk.pojo.User">
          SELECT * FROM USER WHERE username LIKE '%${value}%'
     </select>

     <insert id="insertUser" parameterType="com.zwk.pojo.User">
          <!-- sql表达式也可以写成这样 在sqlyog小海豚中右键数据库中的表,选择粘贴sql语句--> INSERT INTO / UPDATE / DELETE FROM / SELECT
          INSERT INTO `user`
                      (`username`,
                       `birthday`,
                       `sex`,
                       `address`
                       )
          VALUES (#{username},
                  #{birthday},
                  #{sex},
                  #{address});
     </insert>

     <!-- 主键返回第一种方式:useGeneratedKeys,同时指定keyProperty -->
     <insert id="insertUserKey" parameterType="com.zwk.pojo.User" useGeneratedKeys="true" keyProperty="id">
          <!-- selectKey配置主键返回
               order:指定执行时机
               keyProperty:查询到的主键给谁
               resultType:主键的数据类型
           -->
           <!-- 返回主键的第一种方式 -->
          <!-- <selectKey order="AFTER" keyProperty="id" resultType="int">
                   SELECT LAST_INSERT_ID()  
              </selectKey> -->
          INSERT INTO `user`
                      (`username`,
                       `birthday`,
                       `sex`,
                       `address`)
          VALUES (#{username},
                  #{birthday},
                  #{sex},
                  #{address});
     </insert>

     <!-- 主键返回第二种方式:useGeneratedKeys,同时指定keyProperty -->
     <insert id="insertUserUUID" parameterType="com.zwk.pojo.User" useGeneratedKeys="true" keyProperty="id">
          <!-- selectKey配置主键返回
               order:指定执行时机
               keyProperty:查询到的主键给谁
               resultType:主键的数据类型
               总结:配置了UUID时,useGeneratedKeys="true" keyProperty="id"两个属性会失效
           -->
          <selectKey order="BEFORE" keyProperty="uuid2" resultType="string">
               SELECT UUID()
          </selectKey>
          INSERT INTO `user`
                      (`username`,
                       `birthday`,
                       `sex`,
                       `address`,
                       `uuid2`)
          VALUES (#{username},
                  #{birthday},
                  #{sex},
                  #{address},
                  #{uuid2});
     </insert>

     <update id="updateUser" parameterType="com.zwk.pojo.User">
          UPDATE `user`
          SET `username` = #{username}
          WHERE `id` = #{id};
     </update>

     <delete id="deleteUser" parameterType="int">
          DELETE
          FROM `user`
          WHERE `id` = #{id};
     </delete>
</mapper>



log4j.properties( 在conf文件中新建 log4j.properties )
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:\mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=info, stdout



User.java(在src目录下新建包 com.zwk.pojo.User , 在此包下新建User.java)
   注意: com.zwk.pojo.User包名与User.xml映射文件中的包名是一致的,还有 SqlMapConfig.xml 配置中的别名中指向 的包名。
/**
 * 用户信息业务实体
 * @author Steven
 *
 */
public class User {

    private Integer id;
    private String username;// 用户姓名
    private String sex;// 性别
    private Date birthday;// 生日
    private String address;// 地址
    private String uuid2; // UUID

    set ...  省略
    get ...




创建数据库,根据User.java创建mybatis数据库,表名为user  (过程略)

测试类 MyBatisTest.java  ( com.zwk.test )
package com.zwk.test;


import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

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 com.zwk.pojo.User;
import com.zwk.utils.SqlSessionFactoryUtils;

public class MybatisTest {

    @Test
    public void getUserId() throws IOException{
        // 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sfb = new SqlSessionFactoryBuilder();
        // 查找配置文件创建输入流
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
            // 加载配置文件,创建SqlSessionFactory对象
        SqlSessionFactory    sqlSessionFactory = sfb.build(inputStream);
        // 创建SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 执行查询,参数一:要查询的statementId ,
        //参数二:sql语句入参   user.getUserById:user代表映射文件user.xml  getUserById  sql语句的唯一标识
        User user = sqlSession.selectOne("user.getUserById", 1);
        // 输出查询结果
        System.out.println(user);
        // 释放资源
        sqlSession.close();
    }

    @Test
    public void getUserName(){

        SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
        List<User> selectList = sqlSession.selectList("user.getUserByUserName", "z");

        for (User user : selectList) {
            System.out.println(user);
        }
        //释放资源
        sqlSession.close();
    }

    //插入语句
    @Test
    public void insertUser(){

        SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();

        User user = new User();
        user.setBirthday(new Date());
        user.setSex("男");
        user.setUsername("张三");
        user.setAddress("深圳");

        int i = sqlSession.insert("user.insertUser", user);
        System.out.println(i);  // i > 0 时,表示程序运行成功
        // 注意:执行DML操作时  必须要提交事务
        sqlSession.commit();
        sqlSession.close();
    }

    //主键返回
    @Test
    public void insertUserKey(){

        SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();

        User user = new User();
        user.setBirthday(new Date());
        user.setSex("男");
        user.setUsername("王五");
        user.setAddress("深圳");

        int i = sqlSession.insert("user.insertUserKey", user);
        System.out.println(i);
        //提交事务
        sqlSession.commit();
        sqlSession.close();
    }

    //设置属性UUID
    @Test
    public void insertUserUUID(){

        SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();

        User user = new User();
        user.setBirthday(new Date());
        user.setSex("男");
        user.setUsername("赵六");
        user.setAddress("深圳");

        int i = sqlSession.insert("user.insertUserUUID", user);
        System.out.println(i);
        System.out.println(user);
        //提交事务
        sqlSession.commit();
        sqlSession.close();
    }

    //修改用户
    @Test
    public void updateUser(){

        SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();

        User user = new User();
        user.setId(1);
        user.setUsername("小明");

        int i = sqlSession.update("user.updateUser", user);
        System.out.println(i);
        System.out.println(user);
        //提交事务
        sqlSession.commit();
        sqlSession.close();
    }

    //删除用户
    @Test
    public void deleteUser(){

        SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();

        User user = new User();
        user.setId(3);

        int i = sqlSession.delete("user.deleteUser", user);
        System.out.println(i);
        System.out.println(user);
        //提交事务
        sqlSession.commit();
        sqlSession.close();
    }

}



工具类SqlSessionFactoryUtils (com.zwk.utils)

package com.zwk.utils;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class SqlSessionFactoryUtils {

    private static SqlSessionFactory sqlSessionFactory = null;

    static{

        SqlSessionFactoryBuilder sfb = new SqlSessionFactoryBuilder();
        // 查找配置文件创建输入流
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
            // 加载配置文件,创建SqlSessionFactory对象
        if (sqlSessionFactory == null) {
           sqlSessionFactory = sfb.build(inputStream);
        }
    }

    public static SqlSessionFactory getSqlSessionFactory(){
        return sqlSessionFactory;
    }
}















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值