Mybatis基础知识汇总

Mybatis学习总结:

背景介绍:

mybatis:前身ibatis,于2010年迁移到google code,并改名为Mybatis。最后在2013年11月迁移到gitbub(全球开源网站)。

Mybatis 的初步认知:

  • Mybatis 是一个半自动的ORM持久成框架。apache下的顶级项目。
  • Mybatis是JDBC的轻量级的封装,使用时程序员只需要注入sql语句,mybatis通过映射可以灵活生成满足数据库的sql语句。
  • 解决了jdbc的一下几个问题:

    • 1.jdbc创建和销毁数据库的连接耗资源过大
    • 解决方法:mybatis框架内置连接池。

    • 2.sql语句在javaWeb 项目中,修改sql语句需要修改java项目中的代码不利于维护。
      -解决方法:mybatis采用配置文件注入sql语句,使sql语句与java代码分离。
      1. 使用jdbc查询对象时,够多的参数书写不方便。(每一个参数需要书写一个?占位符,并且还需要写一句对应的java语句)且不利于维护;
    • 解决方法:Mybatis使用自动映射java对象至sql语句,通过statement的parameterType进行传参
    • 4.jdbc查询时存在硬编码,当sql语句改变,系统解析是也发生变化,造成系统不利于维护。
    • 解决方法:Mybatis使用自动sql语句至Java对象,通过statement的resultType进行传参

Mybatis的使用步骤:

    1. 导入所需要的jar包,配置SqlMapConfig.xml,写入数据库连接信息,类的别名以及映射关系等信息;
    1. 加载配置文件,获取SqlSessionFactory对象
  • 3.获取SqlSession对象:调用Mapper.xml的sql语句(insert,update,delete,selectOne,selectLists)
  • 4.释放资源

案例展示:Mybatis的DAO层的两种方式:

原始DAO层开发方式:
1.数据库创建数据表本案例使用如下数据表:

1).创建t_user数据表

CREATE TABLE `t_user` (
  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `uname` varchar(255) DEFAULT NULL,
  `usex` varchar(255) DEFAULT NULL,
  `uage` int(11) DEFAULT NULL,
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

2). 插入5条数据:

INSERT INTO t_user VALUES ('1', '张三', '男', '25');
INSERT INTO t_user VALUES ('2', '李四', '男', '26');
INSERT INTO t_user VALUES ('3', '王五', '男', '27');
INSERT INTO t_user VALUES ('4', '赵六', '男', '30');
INSERT INTO t_user VALUES ('5', '小敏', '男', '25');
2.导入jar包,并配置SqlMapConfig.xml文件:

1.1}. 导入如下图所示jar包和log4j.properties

注:jar包说明:

- asm-4.2.jar
- cglib-3.1.jar
-1. 处理字节码的jar包
- mybatis-3.3.0.jar
- mybatis的核心jar包
- mysql-connector-java-5.1.12-bin.jar
- 2.连接数据库jdbcjar包
- jstl-1.2
- 3.标签jar包
- 4.其余jar为日志记录jar包,因为mybatis没有日志记录系统需要引用日记jar包完成打印。

1.2). log4j.properties配置信息:

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

2}.完善配置配置信息如下:

2.1)配置jdbc.properties,基本事项信息:

jdbc.driverName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?characterEncoding=utf-8
jdbc.user=root
jdbc.pass=520

2.2)配置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>

<properties resource="jdbc.properties"></properties>

<typeAliases>
    <package name="com.web.dto"/>
</typeAliases>

<environments default="development">
    <environment id="development">
        <transactionManager type="JDBC" />
        <dataSource type="POOLED">
            <property name="driver" value="${jdbc.driverName}" />
            <property name="url" value="${jdbc.url}" />
            <property name="username" value="${jdbc.user}" />
            <property name="password" value="${jdbc.pass}" />
        </dataSource>
    </environment>
</environments>

<mappers>
    <mapper resource="com/web/mapper/UserMapper.xml"></mapper>
</mappers>

</configuration>

(一).配置文件信息解读:
1)

<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">

写入约束文件:
注:约束标签中有DTD表示:该文件的标签的书写必须按照内部规定。

2).属性标签:properties 目的:为连接数据库提供基本四项的信息:

两种使用如下:

2.1).手动单个设置属性信息(在xml文件中)



设置一个名称为jdbc.user 值为 root的属性。

2.2).引入写好的properits文件信息中的信息

注:properties标签会先加载内部标签,再加载外部文件,名称一致时,会替换内容

解析如下:


当执行properties,先将已有的属性(即在xml中先配置的信息)记性加载,然后在加载xml外的文件即(jdbc.properties),如果加载外部信息的时候遇到相同的属性名,则先加载的内容会被覆盖。

2.3)typeAliases 别名标签 作用 :给自定义的类设置别名:

两种使用方法:

[1].通过包设置别名:

<typeAliases>
    <package name="com.web.dto"/>
</typeAliases> 

解读:将com.web.dto下的所有类都以类名为别名,可简化在mapper.xml中的传参和返回类型的书写。配置好的别名都是类的类名,别名不部分大小写。

[2].通过类设置别名:

<typeAliases>
     <typeAlias type="com.web.dto.User" alias="user"></typeAlias>
</typeAliases> 

解读:将com.web.dto下的User类起名为user;

2.4)environments 环境配置标签 作用用于配置连接数据库的信息(当使用spring框架的时候就可以不用再配置)

<environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverName}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.user}" />
                <property name="password" value="${jdbc.pass}" />
            </dataSource>
        </environment>
    </environments>

解读:

  <environments default="development"> </environments>

设置模式为:开发模式

 <transactionManager type="JDBC" />

使用的连接方式:jdbc

<dataSource type="POOLED"></dataSource>

配置连接的信息

2.5)mapper映射

四种使用方式:
[1].使用Mapper.xml配置文件的路径:

<mappers>
    <mapper resource="com/web/mapper/UserMapper.xml"></mapper>
</mappers>

[2].使用Mapper的接口类的路径:

<mappers>
   <mapper class="com.web.mapper.UserMapper"></mapper>
</mappers>

[3]. 使用Mapper.xml和Mapper接口所在的包配置映射

 <package name="com.web.mapper"/>

[4]. 使用Mapper.xml在本机上的路径

 <mapper url="e:/ssh/com/web/mapper/UserMapper.xml"></mapper>

3}.创将Mybatis工具类和实体类以及测试类

工具类:

/**
 * 功能描述:加载文件信息,获取sqlSession
 *
 * @Author 落叶尘纷
 * @Date 2019/8/13 10:22
 * @Version 1.0
 */
public class MybatisUtil {
    private static SqlSessionFactory sqlSessionFactory;

    static {
        InputStream in = null ;
        try {
            in = Resources.getResourceAsStream("sqlMapConfig.xml");

            sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession(){

        return sqlSessionFactory.openSession();
    }

    public static void release(SqlSession sqlSession) {
        sqlSession.close();
    }
}

实体类

    /**
 * 功能描述:分装user用户实体类
 *
 * @Author 落叶尘纷
 * @Date 2019/8/13 8:10
 * @Version 1.0
 */
public class User {
    private  Integer uid;
    private  Integer uage;
    private  String uname;
    private  String usex;

    public User() {
    }

    public User(Integer uid, Integer uage, String uname, String usex) {
        this.uid = uid;
        this.uage = uage;
        this.uname = uname;
        this.usex = usex;
    }

    @Override
    public String toString() {
        return "User{" +
                "uid=" + uid +
                ", uage=" + uage +
                ", uname='" + uname + '\'' +
                ", usex='" + usex + '\'' +
                '}';
    }

    public Integer getUid() {
        return uid;
    }

    public void setUid(Integer uid) {
        this.uid = uid;
    }

    public Integer getUage() {
        return uage;
    }

    public void setUage(Integer uage) {
        this.uage = uage;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getUsex() {
        return usex;
    }

    public void setUsex(String usex) {
        this.usex = usex;
    }
}

创建UserMapper 接口 和UserMapper.xml文件:

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.xml 配置了映射时,此处的namespace可以随意,使用原生的DAO时就需要namespace的名称 + 方法名称>
<mapper namespace="com.web.mapper.UserMapper">

<!--书写sql 语句-->
    
</mapper>

开始测试:(原生DAO方式调用)

1.)查询所有的记录信息

mapper接口中的方法:

 List<User> findAllUsers();

mapper.xml中的sql

   <select id="findAllUsers" resultType="com.web.dto.User">
        select * from t_user;
    </select>

测试类中的方法:

   @Test
    /**
     * 查询所有记录
     * */
    public void showAllUsers(){
        //获取 sqlSession
        SqlSession session = MybatisUtil.getSqlSession();

        // 调用查询方法:查询所有的信息
        List<User> userList = session.selectList("com.web.mapper.UserMapper.findAllUsers");

        // 循环打印信息
        for (User user : userList) {
            System.out.println(user);
        }

        // 关闭资源
        session.close();

    }

执行结果:

2.1)条件查询相关记录:查询姓张的用户

mapper接口中的方法:

   List<User> findUserLikeName( String name);
   

mapper.xml中的sql

   <select id="findUserLikeName" parameterType="string" resultType="com.web.dto.User">
    select * from t_user where uname like '${value}%';
</select>

测试类中的方法:

public void findUserLikeName(){
    //获取 sqlSession
    SqlSession session = MybatisUtil.getSqlSession();

    //设置传给的参数
    String name = "张";

    // 调用查询方法:查询所有的信息
    List<User> userList = session.selectList("com.web.mapper.UserMapper.findUserLikeName",name);

    // 循环打印信息
    for (User user : userList) {
        System.out.println(user);
    }

    // 关闭资源
    session.close();

}

执行结果:

2.2)通过姓名查询记录

mapper接口中的方法:

  1.List<User> findUserByName(@Param("name") String name);

取值方式可以是#{name}

  2.    List<User> findUserByName( String name);

取值方式只能是#{value}

mapper.xml中的sql

  1.  <select id="findUserByName" parameterType="string" resultType="com.web.dto.User">
    select * from t_user where uname = #{name};
</select>

  2.  <select id="findUserByName" parameterType="string" resultType="com.web.dto.User">
    select * from t_user where uname = #{value};
</select>

测试类中的方法:

      @Test
   public void findUserByName(){
        //获取 sqlSession
        SqlSession session = MybatisUtil.getSqlSession();

        //设置传给的参数
        String name = "王五";

        // 调用查询方法:查询所有的信息
        User u  = session.selectOne("com.web.mapper.UserMapper.findUserByName",name);

        // 打印信息
        System.out.println(u);

        // 关闭资源
        session.close();
    }

2.2)通过id查询记录

mapper接口中的方法:

 User findUserByID( Integer uid);

mapper.xml中的sql

  <select id="findUserByID" parameterType="int" resultType="com.web.dto.User">
    select * from t_user where uid = #{uid};
</select>

测试类中的方法:

         @Test
   public void findUserByID(){
        //获取 sqlSession
        SqlSession session = MybatisUtil.getSqlSession();

        //设置传给的参数
        Integer uid = 2;

        // 调用查询方法:查询所有的信息
        User u  = session.selectOne("com.web.mapper.UserMapper.findUserByID",uid);

        // 打印信息
        System.out.println(u);

        // 关闭资源
        session.close();

    }

执行结果:

3)插入数据:

mapper接口中的方法:

  void addUser(User user);

mapper.xml中的sql

 1.<insert id="addUser" parameterType="User" keyProperty="uid" useGeneratedKeys="true">
   insert into t_user(
      uname,
      uage,
      usex
   )values (
     #{uname},
     #{uage},
     #{usex}
   )
</insert>

2.在idea中插入的selectKey 会报错但是不影响执行
 <insert id="addUser" parameterType="User">

 <selectKey order="AFTER"  resultType="int" keyProperty="uid" >
     select  LAST_INSERT_ID()
 </selectKey>

   insert into t_user(
      uname,
      uage,
      usex
   )values (
     #{uname},
     #{uage},
     #{usex}
   )
</insert>

测试类中的方法:
@Test
public void addUser(){
//获取 sqlSession
SqlSession session = MybatisUtil.getSqlSession();

        //设置传给的参数
        User user = new User();
        user.setUage(36);
        user.setUname("石敢当");
        user.setUsex("男");

        // 调用添加方法并返回影响行数
        int insert = session.insert("com.web.mapper.UserMapper.addUser", user);
        //添加
        session.commit();
        // 打印信息
        System.out.println(user);

        // 关闭资源
        session.close();
    }

执行结果

4)修改信息

mapper接口中的方法:

    void updateUser(User user);

mapper.xml中的sql

<update id="updateUser" parameterType="User">
        update  t_user set uname = #{uname},
          uage = #{uage},usex = #{usex} where uid =#{uid}
    </update>

测试类中的方法:

    @Test
   public void updateUser(){
        //获取 sqlSession
        SqlSession session = MybatisUtil.getSqlSession();

        //设置传给的参数
        User user = new User();
        user.setUid(1);
        user.setUage(36);
        user.setUname("赵小花");
        user.setUsex("男");

        // 查询修改修改的记录的信息
        User user1 = session.selectOne("com.web.mapper.UserMapper.findUserByID", 1);
        System.out.println(user1);

        // 调用修改方法并返回影响行数
        session.update("com.web.mapper.UserMapper.updateUser", user);
         
        session.commit();
        // 打印信息
        System.out.println(user);

        // 关闭资源
        session.close();
    }

执行结果

总结:

    1. :用于非条件拼接sql语句 例如 name like '#{name}' 这种不可取。

    1. $:用于条件拼接sql语句 正常使用会报错 例如 name = ${name} 或 name = ${value}
  • 3.当在mapper接口中的参数没有使用@Param("别名")设置别名时,对于String类型的数据只能使用#{value} 或者 ${value} ,当起了别名时只有#可以使用别名获取。但是#和$使用的时候还需要注意使用的情况是否拼接。
  • 4.其余类型的参数如果是单个可直接使用其参数名获取。
  • 5.如果是多个相同的参数类型,可以使用@Param("别名")设置别名。
  • 6.当数据过多可以使用map集合,通过主键名获取值。
  • 7.使用list集合只能自定义封装类或是起别名。
  • 8.使用时注意mapper.xml中的id名称是唯一的,且方法和mapper中的接口对应。
  • 9.原始的DAO和动态DAO单个框架使用增删改的时候都需要使用 session.commit() 提交到数据库。(在联合spring框架就不需要,因为他有很完善的事务管理机制)
动态DAO层开发方式:

(mapper中的方法和mapper.xml和原始的一样);
1).查询所有信息:

测试类中的测试方法:
@Test
public void showAllUsers1(){
// 获取SqlSession
SqlSession session = MybatisUtil.getSqlSession();
// 通过sqlsession 放射 获取Mapper接口
UserMapper mapper = session.getMapper(UserMapper.class);
// 调用接口中的方法
List allUsers = mapper.findAllUsers();
// 循环打印
for (User allUser : allUsers) {
System.out.println(allUser);
}
// 释放资源
session.close();
}

2).添加信息:

     @Test
public void addUser1(){
    // 获取SqlSession
    SqlSession session = MybatisUtil.getSqlSession();
    // 通过sqlsession 放射 获取Mapper接口
    UserMapper mapper = session.getMapper(UserMapper.class);

    //设置传给的参数
    User user = new User();
    user.setUage(37);
    user.setUname("赵花");
    user.setUsex("男");
    // 调用添加方法
    mapper.addUser(user);
    // 事务提交到数据库
    session.commit();
    System.out.println(user);
    session.close();
}

3).修改信息

@Test
public void addUser1(){
// 获取SqlSession
SqlSession session = MybatisUtil.getSqlSession();
// 通过sqlsession 放射 获取Mapper接口
UserMapper mapper = session.getMapper(UserMapper.class);

    //设置传给的参数
    User user = new User();
    user.setUid(1);
    user.setUage(37);
    user.setUname("赵类");
    user.setUsex("女");
    // 调用添加方法
    mapper.updateUser(user);
    // 事务提交到数据库
    session.commit();
    System.out.println(user);
    session.close();
}
  • 1.动态DAO方法:使用sqlSession通过反射获取Mapper接口对象。增删改查的方法直接利用

动态sql语句:

1) if 标签:

如果判断正确,将if标签内的信息拼接进去。如下:

      <select id="findUserLikeName" parameterType="string" resultType="com.web.dto.User">
    
            select * from t_user
            <where>
                uname like
                <if test="value!=null">
                    '${value}%'
                </if>
            </where>
        </select>
  • 使用的String类型只有一个的时候如果是模糊,依旧不能使用

2.1)不报错:

 <select id="findUserByName" parameterType="string" resultType="com.web.dto.User">
        select * from t_user
           <where>
                <if test="value != null">
                    uname = #{value};
                </if>
           </where>
    </select>

2.2)报错:

 <select id="findUserByName" parameterType="string" resultType="com.web.dto.User">
        select * from t_user
           <where>
                <if test="name != null">
                    uname = #{name};
                </if>
           </where>
    </select>

2).总结:当只有一个String类型的参数时,使用动态sql语句取值,非拼接转态只能使用#{value},拼接只能使用${value}。对于非动态,没有拼接的可以使用别名。拼接的只能使用${value}获取值。

3)Where 标签:
相当于一个添加一个where 关键字:语句解释如下:

<select id="findUserByName" parameterType="string" resultType="com.web.dto.User">
        select * from t_user
           <where>
                    uname = #{name};
           </where>
    </select>

等同于 :

 <select id="findUserByName" parameterType="string" resultType="com.web.dto.User">
        select * from t_user where uname = #{name};
    </select>

4).sql标签:动态标签中唯一一个和select 同级别的标签:
作用:通常书写一个常用的条件,一般使用 </include>引入<insert>,<update>,<delete>等标签如下所示

findAllUsers 方法查询所有的记录数据

 <select id="findAllUsers" resultType="com.web.dto.User">
    <include refid="findAllUser" ></include>
</select>

<sql id="findAllUser">
        select * from t_user;
  </sql>

正确格式sql语句

 <![CDATA[
   sql 拼接语句
 ]>

正确识别大于号和小于号:无法识别的原因是因为标签使用的就是大于号和小于号,容易结束整条标签语句。

5).forEach标签:(集合数据循环)

 <delete id="deleteAll" parameterType="list">
   delete from t_user
        <where>
              uid in
            <foreach collection="uids" separator="," item="id" open="(" close=")">
                ${id}
            </foreach>
        </where>
</delete>

相当于sql语句:
delete form t_user where uid in (1,2){小括号好内是集合中的数据}

解释:

  • collection:list属性的别名
  • item :循环中使用时的别名
  • separator每次循环中间的拼接字符
  • open:开始符号
  • close:结束符号

list 类型使用:

  • 在mapper接口中的list参数起一个别名
  • 封装在另一个类中作为属性使用

猜你喜欢

转载自www.cnblogs.com/yizhichenfen/p/11348983.html