Mybatis学习

Mybatis学习

  1. mybatis是将对象类和数据库的表进行一一映射,

  2. 多个表之间之间的映射关系,需要用mapper.xml来进行。

  3. 这个文件的创建位置一般是和类在一起的。

  4. 如果是person类,那么一般取名是personMapper.xml,

  5. 里面的内容大致是这样的,
    namespace=“xxx.xxx.xxx.personMapper”>这个是全类名,也就是这个person的全类名
    标签里的id是用来区分查询哪一个的select的,这个resultType是一个返回值,因为是查询所 有,所以就可以返回一个Person对象。如果查询的是int类型,这里就可以改为int

    #{id}是动态传值相当于jdbc里的 ?。

<?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="xxx.xxx.xxx.personMapper">
		 <select id="selectBlog" resultType="Person">
		 select * from Blog where id = #{id}//切记,没有;
		 </select>
</mapper>
  1. [id]:statement的id,要求在命名空间内唯一
    [parameterType]:入参的java类型
    [resultType]:查询出的单条结果集对应的java类型
    [#{}]: 表示一个占位符?[#{id}]:表示该占位符待接收参数的名称为id。注意:如果参数为简单类型时,#{}里面的参数名称可以是任意定义

  2. 要想正确启动,需要在配置文件中添加你的这个类的xml文件
    运行主文件:
    //加载mybatis配置文件

    这里是程序检测时的主程序

  Reader reader = Resources.getResourceAsReader("mybatis.xml");
       SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader,"");
       SqlSession sqlSession = sqlSessionFactory.openSession();
       String statement = "com.ypl.entity.UserMapper.findUserById";
       User user=sqlSession.selectOne( statement,1);
        System.out.println(user.toString());
    //关闭连接
        sqlSession.close();
错误总结
首先今天就只是个简单的实现mybatis的id查找就出现一堆错误
  1. 类的xml配置文件是否加到了主xml中,是否有log4j配置文件,类路径是否写错,xml文件放在jsrc的ava路径下,不能访问是否在pom.xml中添加了以下内容
<resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>
            </resources>
  1. mapper文件中namepace的值是否有,是否被正确引用
  2. 类配置文件中这里要修改 <?xml version="1.0" encoding="UTF8" ?>
<environments default="development">
        <environment id="development">
            <!-- 配置JDBC事务控制,由mybatis进行管理 -->
            <transactionManager type="JDBC"/>
            <!-- 配置数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;userUnicode=true&amp;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="1024101159..ln"/>
            </dataSource>
        </environment>
    </environments>

这里的<environments>标签里面可以配置多个环境,

  1. 他有一个属性叫做*default*用来指定默认的环境,
  2. 每个环境里都可以进行不同的数据库配置,
  3. 如果指定了默认的数据库但是想使用其他数据库,我们可以在主程序运行代码做这些改变
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder()
.build(reader,"指定的数据库环境id");

在这里插入图片描述

  1. POOLED是数据库连接池,UNPOOLED是不用数据库连接池,他就是使用传统的jdbc操作
  2. Mybatis在语法上只允许有一个输入值,有一个输出值
    也就是说在类mapper文件中不同的标签只能有一个parameterType="" 和resultType=""
  3. 如果输入参数:是简单类型(八个基本数据类型+String) 是可以使用任何占位符,#{xxx}
    如果是对象类型,则必须是对象的属性 #{属性名}
  4. 输出参数: 如果返回值类型是一个 对象 (如Student),则无论返回一个。还是多个,在这个返回的类型中都写上 全类名
    在这里插入图片描述

Mybatis接口没有实现类

约定:

在这里插入图片描述

约定的过程:

  1. 根据 接口名找到mapper.xml文件(根据的是namespace=接口全类名)
  2. 根据 接口的方法名找到在mapper.xml该文件中的SQL标签(根据的是 方法名=SQL的ID值)
    以上两点可以保证:当我们调用接口中的方法时,程序能自动定位到某一个Mapper,xml文件中的SQL标签
    在这里插入图片描述
优化:
  1. 可以将配置信息单独放进配置文件当中,然后在动态引入,
    db.properties
    k=v

    引入之后,使用时用${k}进行取值,这样就可以将V值取出
  2. 设置别名:
    (1)单独设置别名时 大小写无所谓
<!--设置单个或者多个别名-->
    <typeAliases>
        <!--设置单个别名-->
        <typeAlias type="com.ypl.entity.User" alias="User"/>
       
    </typeAliases>
 (2)批量设置别名
<typeAliases>
        <!--设置单个别名-->
        <typeAlias type="com.ypl.entity.User" alias="User"/>
        <!--批量定义别名,别名就是该类名-->
        <package name="com/ypl/entity"/>
    </typeAliases>

在这里插入图片描述

类型转换
<select id="findUserById" parameterType="int" resultMap="userResult" resultType="com.ypl.entity.User">
        select *
        from user
        where id = #{id}
    </select>
    <resultMap id="userResult" type="User">
        <!--        分为主键id和非主键result-->
        <!--        属性和列名一一对应起来了-->
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="birthday" column="birthday"/>
        <result property="sex" column="sex"/>
        <result property="address" column="address" />
<!--    类型转换  javaType="boolean" jdbcType="Integer",将布尔类型转换为integer类型-->
    </resultMap>
在进行增删改操作时,发现都没有改变,最后得出原因是因为 没有commit,我们只需要一行代码即可sqlSession.commit();
输入参数:parameterType
  1. 类型为简单类型(8个基本类型+String)
    #{任意值}
    ${value},其中的标识符只能是value
    #{}自动给String类型加上’’(自动类型转换)
    ${}原样输出,但是适合于 动态排序(动态字段)
  2. 对象类别
    #{属性名}
    ${对象的属性名},其中的标识符只能是value
select * from user where username=#{value}
select * from user where username='${value}'

动态排序:

select * from user order by ${value}  asc

3. #{}可以防止SQL注入,${不可以防止SQL注入}

在SQL语句中的if标签里,左边是数据库的字段,右边是属性名,严格区分大小写,使用mybatis简单顺序

  1. 先写工具类
 private static SqlSessionFactory sqlSessionFactory;

   static {
       try {
           //使用mybatis第一步,创建  SqlSessionFactory对象
           String resource = "mybatis-config.xml";
           Reader inputStream = Resources.getResourceAsReader(resource);
           sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
       } catch (IOException e) {
           e.printStackTrace();
       }
   }

   public static SqlSession getSqlSession() {
       return sqlSessionFactory.openSession();
   }

  1. 在写实体类
  2. 写配置类(config.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="db.properties"/>
    <typeAliases>
        <typeAlias type="com.ypl.pojo.User" alias="User"/>
        <!--        <package name="com.ypl.pojo"/>-->
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--        所有的路径以斜杠结尾-->
        <!--        <mapper resource="com/ypl/dao/UserMapper.xml"/>-->
        <package name="com.ypl.dao"/>
    </mappers>

</configuration>
  1. 写mapper接口
  2. 写mapper接口的xml文件
  3. 在写测试类Test
引入mapper资源的方式
<!-- 使用相对于类路径的资源引用 --> <mappers> 
           <mapper resource="org/mybatis/builder/PostMapper.xml"/>
           </mappers> 
     <!-- 使用完全限定资源定位符(URL) --> <mappers> 
           <mapper      url="file:///var/mappers/AuthorMapper.xml"/>
          </mappers> 
    <!-- 使用映射器接口实现类的完全限定类名 需要配置文件名称和接口名称一致,并且位于同一目录下 -->             <mappers>
     <mapper class="org.mybatis.builder.AuthorMapper"/> 
     </mappers> 
      <!-- 将包内的映射器接口实现全部注册为映射器 但是需要配置文件名称和接口名称一致,并且位于同一目录下 --> 
         <mappers> 
         <package name="org.mybatis.builder"/>
       </mappers>

动态SQL

where标签会自动处理第一个if标签里的and但不会处理之后的if标签里的and,if标签

在配置文件里的数据库信息使用中,它是优先使用配置文件db.properties,然后才是properties标签里的内容
生命周期和作用域
生命周期和作用域是至关重要的,因为错误的使用会导致严重的并发问题

1. SqlsessionFactoryBuilder

• 一旦创建了SqlsessionFactory,就不再需要他了
• 局部变量
2. SqlsessionFactory
• 可以将它想象为数据库连接池
• SqlSessionFactory一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃他或重新创建另一个实例
• 程序开始他就开始,程序结束他就结束
• 最简单的就是使用单例模式或者静态单例模式
SqlSession
• 连接到连接池的一个部分
• Sqlsession不是一个线程安全的,因此是不能被共享的,所以它的最佳作用域是请求或方法作用域
• 用完之后需要赶紧关闭,否则资源被占用!

日志工厂
• 如果一个数据库操作出现了异常。我们需要排错

• 注意大小写,不能有空格。
日志工厂简单使用:

-  在要使用log4j的类中,导入包import org.apache.log4j.Logger;
  • 日志对象,参数为当前类的class
 static Logger logger = Logger.getLogger(UserDaoTest.class);

• 日志级别

logger.info("info:进入了testLoj4");
logger.debug("debug:进入了testLoj4");
logger.error("error:进入了testLoj4");

分页

思考:为什么要分页
使用limit分页
select * from user limit startIndex,pageSize

如果这个startIndex是0,pageSize是2,那么查询出来的结果是从第1个开始,第2个结束
pageSize是负数,则是最后一个结束,但是他被修复了,现在不能用了

在使用注解开发时:

在config.xml文件中绑定的是接口
关于Param注解
• 基本类型的参数或者String类型的参数需要加上
• 引用类型不用加
• 如果只有一个基本类型的话,可以忽略,但是建议加上
• 我们在SQL中引用的就是该注解里所设定的属性名
按照查询嵌套处理

 <select id="getStudent" resultMap="StudentTeacher">
        #         select student.id,student.name,teacher.name  from teacher,student where teacher.id=student.tid;
        select *
        from student;
    </select>
    <resultMap id="StudentTeacher" type="Student">
        <!--        result 只能针对单一属性-->
        <result property="id" column="id"/>
        <result column="name" property="name"/>
        <!--        association多个属性
        复杂的属性要单个处理
        对象要用association
        集合使用collection
        -->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
    </resultMap>
    <select id="getTeacher" resultType="Teacher">
        select *
        from teacher
        where id = #{id}
    </select>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值