mybatis个人复习资料一

193 阅读7分钟

pom

<dependencies>
        <!--导入mybatis的坐标-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.4</version>
        </dependency>
        <!--因为是数据库的操作还需要:添加mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
            <scope>runtime</scope>
        </dependency>
        <!--日志坐标-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <!--导入JUNIT依赖-->
            <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
              <version>4.12</version>
              <scope>test</scope>
            </dependency>
    </dependencies>

sqlmap

<mappers>
    <!--<mapper resource="cn/itcast/dao/IUserDao.xml"></mapper>-->基于配置文件
    <mapper class="cn.itcast.dao.IUserDao"></mapper>基于注解
</mappers>

映射

 实体类中: private Date birthday;   数据库表中: birthday DATETIME DEFAULT NULL COMMENT '生日'
sql脚本语句插入时可以直接写'2018-01-01'
传递数据到表中时直接可以使用user.setBirthday(new Date());
查询得到的结果也可以直接被封装到实体类上面

单一字段

接口中
void deleteUser (Integer userId)
映射文件中
<delete id="deleteUser" parameterType="java.lang.Integer"或者"Integer"或者"int">
    delete from user where id = #{uid}
</delete>
只传递一个参数且为基本类型或者包装类型时,占位符具体写法不做要求
<!--
resultType也有"java.lang.Integer"或者"Integer"或者"int"这种写法
还有java.lang.String、Integer、string
-->

模糊查询

方式一:userDao.findByName("%王%")===》where username like #{name}
日志文件中的部分重要的信息:PreparedStatement的参数占位符

方式二(几乎不使用):===》where username like '%${value}%' 大括号里面的内容必须要是value 原因见下面源码截图
日志文件中的部分重要的信息:Statement对象的字符串拼接SQL

支持聚合函数查询

<select id = "findTotal" resultType="int">
select count(*)from user
</select>

获取自增id

写法一:select 1641812 结果为0;
写法二:insert into table (colum1,colum2,....) values(value1,value2,....)
select 1641812结果是上一条行记录所分配的自增id

mybatis中如何使用获取自增id

1.mybatis框架可以通过传入的这个参数类型:parameterType=User,然后反射出来里面的属性getXxx()中的Xxx,拿到值
2.配置插入操作后,获取刚才插入数据的id
keyProperty="id"对应实体类的id的属性名称
keyColumn="id"id的列名对应表
order="AFTER"什么时候执行获取id的操作,在执行插入之后
<insert id="saveUser" parameterType="User">
     <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
        select 1641812;
    </selectKey>
    insert into user(username, address, sex, birthday)values (#{username},#{address},#{sex},#{birthday});
</insert>
保存前打印结果为id=null 保存后打印结果为id=52

ognl表达式

parameterType 
传递简单类型 
pojo对象

包装对象
Object Graphic Navigation LanguageCallback 对象 图 导航 语言 它是通过对象的取值方法来获取数据,在写法上把get给省略了。 比如:我们获取用户的名称: 类中的写法:user.getUsername(); OGNL表达式的写法:user.username IUserDao.xml中为什么能直接写username,而不用user.username呢: 因为在parameterType属性中已经提供了属性所属的类,所以此时不需要写对象名属性名 update user set username=#{username}, address=#{address}, sex=#{sex}, birthday=#{birthday} where id=#{id}; //username=#{username} ---- > username=user.username ---- > username=user.getUsername 此时where username like #{name} 或者#{username}都是错误的 因为parameterType是QueryVo它没有这个属性 此时需要写成user.username:user是QueryVo里面的属性 username是user实体类里面的属性

返回类型和参数类型

参数类型使用ongl无法封装时会报错 
返回类型封装结果实体类属性字段和表中字段不对应时不会报错 而是属性封装结果为null
windows上不区分大小写 linux严格区分大小写
<select id="findAll" resultType="com.itheima.domain.User">
	select id as userID,username as userName,address as userAddress,sex as userSex, 
	    birthday as useBirthday from user;
</select>	
这种解决方式的执行效率是最高的,因为是在sql语句层面就解决了。
<resultMap id="userMap" type="com.itheima.domain.User">
	<!--主键段字段的对应-->
	<id property="userId" colum="id"></id>
	<!--非主键段字段的对应-->
	<result property="userNmae" colum="username"></result>
	<result property="userAddress" colum="address"></result>
	<result property="userSex" colum="sex"></result>
	<result property="userBirthday" colum="birthday"></result>
</resultMap> 

<!--
	注意:要加上resultMap属性,resultType不需要了
	结果就可以封装了
-->
<select id="findAll" resultMap="userMap">
	select * from user;
</select>
这种解决方法要多解析一点xml,执行效率变慢,但是开发效率快了。
其他的查询操作,也可以加上resultMap="userMap"属性。

properties属性

 配置properties
    可以在标签内部配置连接数据库的信息,也可以通过属性引用外部配置文件信息
    1.resource属性:
        用于指定配置文件的位置,是按照类路径的写法来写,并且必须存在于类路径下
    2.url属性:
        是要求按照url的写法来写配置文件的地址
        URL:Uniform Resource Locator,统一资源定位符,可以唯一定位一个资源位置
        写法:
            http://localhost:8080/baidu.com
            协议    主机      端口   URI
            url="file:///E:/Idea_Projects/day0603_01mybatisCRUD/src/main/resources/jdbcConfig.properties"
        * URI: Uniform Resource Identifier 统一资源标识符,可以在应用(项目)中唯一定位一个资源。

        * Windows文件:用的是file协议 file:///
    * 在resources下面建立一个属性文件jdbcConfig.properties
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/txl_mybatis
    jdbc.username=root
    jdbc.password=root

<configuration>
<properties resource="jdbcConfig.properties">
    <!--<property name="driver" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/txl_mybatis"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>-->
</properties>

typeAlias属性

<!--使用typeAliases配置别名
        只能配置domain中类的别名,从而让我们在用的时候少写一些包名或全限定类名
    -->
    <typeAliases>
        <!--typeAlias用于配置别名,type属性指定实体类的全限定类名,alias属性指定别名。当指定了别名后就不区分大小写-->
        <!--<typeAlias type="com.itheima.domain.User" alias="user"></typeAlias>-->
        <!--用于指定要指定别名的包,当指定后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写-->
        <package name="com.itheima.domain"/>
    </typeAliases>

mapper属性

<mappers>
    <!--<mapper resource="com/itheima/Dao/IUserDao.xml"></mapper>-->
    <!--package标签是用于指定dao接口所在的包,当指定完成之后,就不需要再写:
        <mapper resource="com/itheima/Dao/IUserDao.xml"></mapper>或
        <mapper class="com/itheima/Dao/IUserDao"></mapper>
    -->
    <package name="com.itheima.Dao"/>
</mappers>

动态语句之if

```
    private Integer id;
    private String username;
    private String address;
    private String sex;
    private Date birthday;
    
    <!--根据条件查询-->
    <select id="findUserByCondition" resultType="com.itheima.domain.User" parameterType="com.itheima.domain.User">
        select * from user where 1 = 1
        <!--判断传入的参数user中是否有username属性-->
        <if test="username != null">
            and username like #{username}
        </if>
        <!--判断传入的参数user中是否有sex属性-->
        <if test="sex != null">
            and sex = #{sex}
        </if>
        <if test="address != null">
            and address = #{address}
        </if>
        <if test="id != null">
            and id = #{id}
        </if>
        <if test="birthday != null">
            and birthday = #{birthday}
        </if>
    </select>
        * 这在一定程度上达到了动态SQL的目的,但是不好的一点就是:如果实体类有许多许多属性,那么就要写许多许多<if>标签。

```

动态语句之where

where 1 = 1去掉了
    <select id="findUserByCondition" resultType="com.itheima.domain.User" parameterType="com.itheima.domain.User">
        select * from user
        <where>
            <if test="username != null">
                and username like #{username}
            </if>
            <if test="sex != null">
                and sex = #{sex}
            </if>
            <if test="address != null">
                and address = #{address}
            </if>
            <if test="id != null">
                and id = #{id}
            </if>
            <if test="birthday != null">
                and birthday = #{birthday}
            </if>
        </where>
    </select>

动态语句之foreach

```
解决这种子查询:select * from user where id in(41, 42, 43, 45)
    <!--根据QueryVo中提供的id集合,查询用户信息-->
    <select id="findUserInIds" resultType="com.itheima.domain.User" parameterType="com.itheima.domain.QueryVo">
        select * from user
        <where>
            <if test="ids != null and ids.size() > 0">
                <foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
                    <!--和item="uid"要一致-->
                    #{uid}
                </foreach>
            </if>
        </where>
    </select>
```

动态语句之sql