MyBatis(二)

mybatis(二)

实例源码下载

1.动态代理

  • 使用SqlSession.getMapper(dao接口.class) 获取这个dao接口的对象

  • 封装一个mybatis工具类

    package com.util;
    
    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 java.io.IOException;
    import java.io.InputStream;
    
    /**
     * Created by IntelliJ IDEA.
     * User: LvHaoIT (asus)
     * Date: 2021/5/25
     * Time: 11:01
     */
    public class MyBatisUtil {
        //调用就自动执行一次
        public static SqlSessionFactory factory = null;
    
    
        /**
         * 静态代码块在类初始化阶段就会自动执行
         */
        static {
            String config = "mybatis.xml";
            try {
                InputStream in = Resources.getResourceAsStream(config);
                factory = new SqlSessionFactoryBuilder().build(in);//为了下面获取sqlSession对象
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 静态方法:静态方法在类加载的使用使用,即当其他类中调用或new的时候,他将执行
         *
         * @return SqlSession
         */
        public static SqlSession getSqlSession() {
            SqlSession sqlSession = null;
            if (factory != null) {
                sqlSession = factory.openSession();//获取一个sqlSession对象,(非自动提交事务)
            }
            return sqlSession;
        }
    
        public static SqlSession getSqlSession(boolean flag) {
            SqlSession sqlSession = null;
            if (factory != null) {
                sqlSession = factory.openSession(flag);//获取一个sqlSession对象,(根据结果判断是否自动提交)
            }
            return sqlSession;
        }
    
    }
    
    
  • 调用工具类,完成动态代理

    /**
       * 使用mybatis的动态代理机制,使用SqlSession。getMapper(dao接口)
       *  pper能获取dao接口对应的实现类对象
       */
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    UsersDao dao = sqlSession.getMapper(UsersDao.class);
    //dao=com.sun.proxy.$Proxy2 JDK的动态代理
    System.out.println("dao=" + dao.getClass().getName());
    //调用dao的方法,执行数据库操作
    List<Users> usersList = dao.selectUsers();
    for (Users user : usersList) {
        System.out.println(user);
    }
    

2.传入参数

从java代码中把数据传入到mapper文件的sql语句中。

2.1 parameterType
  • 写在mapper文件中的 一个属性。 表示dao接口中方法的参数的数据类型。
    例如UsersDao接口
    public Users selectUserById(Integer id);

    parameterType="java.lang.Integer"

    <!--
        parameterType : dao接口中方法参数的数据类型
        parameterType 它的值是java的数据类型全限定名称或者是mybatis定义的别名
        例如:parameterType = "java.lang.Interger"
        parameterType="int"
        可以省略不写,可以自动识别
        不是强制的,mybatis通过反射机制能够返现接口参数的类型
        -->
    <select id="selectUserById" parameterType="java.lang.Integer" resultType="com.entity.Users">
      select userId , userName,password,sex,email from users where userId=#{id}
    </select>
    
2.2 一个简单类型的参数

简单类型: mybatis把java的基本数据类型和String都叫简单类型
在mapper文件获取简单类型的一个参数的值,使用 #{任意字符}

接口:public Users selectUserById(Integer id);
mapper:select userId , userName,password,sex,email from users where userId=#{id}

  • UsersDao

    <select id="selectUserById" resultType="com.entity.Users">
      select userId , userName,password,sex,email from users where userId=#{id}
    </select>
    
2.3 使用@Param命名参数(多个参数)

​ 语法格式:使用 @Param(“参数名”) String name

  • 接口:

    public Users selectMutilUsers(@Param("userName") String userName,
                                  @Param("sex") String sex);
    
  • mapper文件

      <!--多个属性,使用多个对应的属性名-->
        <select id="selectMutilUsers" resultType="com.entity.Users">
        select userId , userName,password,sex,email from users where userName=#{userName} and sex=#{sex}
        </select>
    
2.4 多个参数,使用java对象

​ 语法格式:语法 #{属性名}

  • 接口:

     public List<Users> selectMutilUsers_01(Users user);
    
  • mapper文件

      <select id="selectMutilUsers_01" resultType="com.entity.Users">
        select userId , userName,password,sex,email from users where password=#{password} and sex=#{sex}
        </select>
    
2.5 多个参数,使用map传递

​ 语法格式:语法 #{map的key}

  • 接口:

    public List<Users> selectMutilUsers_Map(Map map);
    
  • mapper文件

     <!--多个属性,使用Map传值-->
        <!--使用的语法是:#{map的key}-->
        <select id="selectMutilUsers_Map" resultType="com.entity.Users">
        select userId , userName,password,sex,email from users where password=#{MapPassword} and sex=#{MapSex}
        </select>
    </mapper>
    

3.定义别名(当数据库与java类中属性名不匹配的情况)

  • vo: value object , 放一些存储数据的类。比如说 提交请求参数, name ,age
    现在想把name ,age 传给一个service 类。

    vo: view object , 从servlet把数据返回给浏览器使用的类,表示显示结果的类。

  • pojo: 普通的有set, get方法的java类。 普通的java对象

    Servlet — StudentService( addStudent( MyParam param) )

  • entity(domain域): 实体类, 和数据库中的表对应的类

3.1 第一种解决方式(使用resultMap定义映射关系)
  • 接口:public List selectAllUsers();

  • resultMap

        <!--使用resultMap(解决的是数据库里面的列名和java属性名不统一的情况)
            第一种方法:
            1.先定义resultMap
            2.在select标签中,使用resultMap来引用1定义的
        -->
    
        <!--定义resultMap
            id:自定义名称,表示你定义的这个resultMap
            type: java类型的全限定名称
        -->
        <resultMap id="UsersMap" type="com.entity.Users">
            <!--列名和java属性的关系-->
            <!--主键列,使用id标签
                column:列名
                property:java类型的属性名
                -->
            <id column="userId" property="userId"/>
            <!--非主键列,使用result-->
            <result column="userName" property="userName"/>
            <result column="password" property="password"/>
            <result column="sex" property="sex"/>
            <result column="email " property="email"/>
        </resultMap>
    
  • userDao.xml

        <select id="selectAllUsers" resultMap="UsersMap">
            select * from Users order by userId;
        </select>
    
3.2 第二种解决方式 (使用查询语句内起别名的方式)
  • UsersDao.xml

    <select id="selectAllMyUsers" resultType="com.entity.myUsers">
        select userId as Id, userName as Name,password,sex,email from users order by userId
    </select>
    
    

4.# 和 $

4.1 使用过程
  • select id,name, email,age from student where id=#{studentId}
    
    # 的结果: select id,name, email,age from student where id=? 
       select id,name, email,age from student where id=${studentId}
    
    $ 的结果:select id,name, email,age from student where id=1001
    	String sql="select id,name, email,age from student where id=" + "1001";
    

    使用的Statement对象执行sql, 效率比PreparedStatement低。

    : 可 以 替 换 表 名 或 者 列 名 , 你 能 确 定 数 据 是 安 全 的 。 可 以 使 用 :可以替换表名或者列名, 你能确定数据是安全的。可以使用 :使(#可以防止sql注入)

4.2 # 和 $区别
  • #使用 ?在sql语句中做站位的, 使用PreparedStatement执行sql,效率高
  1. #能够避免sql注入,更安全。
  2. $不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低
  3. $有sql注入的风险,缺乏安全性。
  4. $:可以替换表名或者列名

5.mybatis的输出结果

mybatis执行了sql语句,得到java对象。

5.1 resultType结果类型

指sql语句执行完毕后, 数据转为的java对象, java类型是任意的。
resultType结果类型的它值

  1. 类型的全限定名称
  2. 类型的别名, 例如 java.lang.Integer别名是int

处理方式

  1. mybatis执行sql语句, 然后mybatis调用类的无参数构造方法,创建对象。
  2. mybatis把ResultSet指定列值付给同名的属性
<select id="selectUsers" resultType="com.entity.Users">
    select userId , userName,password,sex,email from users order by userId
</select>

对等的jdbc
ResultSet rs = executeQuery(" select userId , userName,password,sex,email from users order by userId" )
while(rs.next()){
Users  user = new Users();
student.setuserId(rs.getInt("userId"));
student.setuserName(rs.getString("username"))
    ...
}
5.2 定义自定义类型的别名

​ 1)在mybatis主配置文件中定义,使定义别名
​ 2)可以在resultType中使用自定义别名

 <typeAliases>
        <!--第一种方式
       可以指定一个类型一个自定义别名
       type:自动以类型的全限定名称
       alias:别名(短小容易记忆)-->
     <typeAlias type="com.entity.Users" alias="users"/>

        <!--第二种方式
        <package name="com.entity"/> name就是包名,类名就是别名(类名不区分大小写)
        -->
    <package name="com.entity"/>
    </typeAliases>
5.3 resultMap:结果映射, 指定列名和java对象的属性对应关系。

​ 1)你自定义列值赋值给哪个属性
​ 2)当你的列名和属性名不一样时,一定使用resultMap

  <resultMap id="UsersMap" type="com.entity.Users">
        <!--列名和java属性的关系-->
        <!--主键列,使用id标签
            column:列名
            property:java类型的属性名
            -->
        <id column="userId" property="userId"/>
        <!--非主键列,使用result-->
        <result column="userName" property="userName"/>
        <result column="password" property="password"/>
        <result column="sex" property="sex"/>
        <result column="email " property="email"/>

    </resultMap>
 <select id="selectAllUsers" resultMap="UsersMap">
        select * from Users order by userId;
    </select>

注意:resultMap和resultType不要一起用,二选一
5.4 模糊查询

两种方式:

  1. 在java中直接拼接字符串,然后传递给方法(推荐

    //第一种方式 ,直接在java程序中传递已经拼接好的字符串(推荐)
    /*接口*/   public List<Users> selectLikeOne(String name);
    
    <!--模糊查询方式1 java中拼接like字符串-->
        <select id="selectLikeOne" resultType="com.entity.Users">
        select * from Users where userName like #{name}
    </select>
    
  2. 在xml文件中拼接查询

    //第二种方式,传递条件 进入xml中进行拼接
        public List<Users> selectLikeTwo(String name);
    
     <!--模糊查询方式2 xml中拼接like字符串(%和空格都是必要的)-->
        <select id="selectLikeTwo" resultType="com.entity.Users">
            select * from Users where userName like #{name} "%"
        </select>
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LvhaoIT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值