mybatis第四天

mybatis第四天

一、内容介绍

1、mybatis改良代码

2、mybatis延迟加载

3、mybatis缓存

4、mybatis注解开发

二、mybatis改良代码

UserDao.xml

    <resultMap id="alluser" type="user">
        <id column="uid" property="id"></id>
        <result column="username" property="username"></result>
        <result column="address" property="address"></result>
        <result column="password" property="password"></result>
        <result column="sex" property="sex"></result>

		 <!--
            column="u_id": 要通过该列去查询用户的对象
            select: 映射到了要执行的方法 :mapperId=namespace.id 
        -->
        <collection property="accountList" ofType="account"
                     column="uid" select="com.itheima.dao.AccountDao.findByAId">
        </collection>
    </resultMap>

    <select id="findAll" resultMap="alluser">
        SELECT * from USER u,account a where a.uid = u.uid
    </select>

AccountDao.xml

    <select id="findByAId" parameterType="int" resultType="account">
        select * from account where id = #{id}
    </select>
三、mybatis延迟加载
a、什么是延迟加载
1. 也叫懒加载
2. 什么时候需要,什么时候去获取
	什么时候需要该数据,什么时候执行sql语句去查询
b、一对一延迟加载

AccountDao.xml

<mapper namespace="com.itheima.dao.AccountDao">
    <resultMap id="accounts" type="account">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <result column="money" property="money"></result>
        <result column="u_id" property="u_id"></result>
        <!--映射user属性:原来的代码-->
        <!--<association property="user" javaType="User">-->
            <!--<id column="uid" property="id"></id>-->
            <!--<result column="uname" property="username"></result>-->
            <!--<result column="address" property="address"></result>-->
            <!--<result column="birthday" property="birthday"></result>-->
            <!--<result column="password" property="password"></result>-->
            <!--<result column="sex" property="sex"></result>-->
        <!--</association>-->
        <!--
            column="u_id": 要通过该列去查询用户的对象
            select: 映射到了要执行的方法 :mapperId=namespace.id

            fetchType="lazy"  :加载的方法:lazy 延迟加载,  eager:立即加载
        -->
        <association property="user" javaType="User" column="u_id"
                     select="com.itheima.dao.UserDao.findById" fetchType="lazy"></association>
    </resultMap>
    <select id="findAll" resultMap="accounts">
        select * from account
    </select>
</mapper>

UserDao.xml

<mapper namespace="com.itheima.dao.UserDao">
    <resultMap id="users" type="user">
        <id column="uid" property="id"></id>
        <result column="uname" property="username"></result>
    </resultMap>
   <select id="findById" resultMap="users" parameterType="int">
        select * from user where uid = #{id}
   </select>
</mapper>
c、一对多延迟加载

UserDao.xml

<mapper namespace="com.itheima.dao.UserDao">
    <resultMap id="users" type="User">
        <id column="uid" property="id"></id>
        <result column="uname" property="username"></result>
        <result column="address" property="address"></result>
        <result column="birthday" property="birthday"></result>
        <result column="password" property="password"></result>
        <result column="sex" property="sex"></result>
        <!--映射List<Account> accountList
            coulmn :属性对应的列
        -->
        <collection property="accountList" ofType="account" column="uid"
        select="com.itheima.dao.AccountDao.findByUserId" fetchType="lazy"></collection>
    </resultMap>

    <select id="findAll" resultMap="users">
      select * from user
    </select>
</mapper>

AccountDao.xml

<mapper namespace="com.itheima.dao.AccountDao">
    <select id="findByUserId" resultType="account" parameterType="int">
        select * from account where u_id = #{userId}
    </select>
</mapper>
d、开启全局的延迟加载
<!--核心配置文件的全局的设置-->
<settings>
	<!--开启全局的延迟加载-->
	<setting name="lazyLoadingEnabled" value="true"/>
</settings>
四、mybatis缓存
一级缓存
/**
 * 一级缓存
 *  1.在同一sqlSession对象范围下,两次执行同一个sql语句,第二层没有执行sql语句,说明缓存的存在
 *  2.如果执行了增删改,提交操作,会清空缓存
 *  3. sqlSession.clearCache();清空缓存
 *  4. 一级缓存是SqlSession级别的, 必须是在一个sqlsession对象范围下才可以的得到一级缓存
 *
 * 一级缓存运行流程
 *  	第一次执行sql语句,查询到数据,会在一级缓存中存储sql语句和数据,
 * 以 sql语句为key值, 以数据为value值
 *  	在第二层执行sql语句时,会先从缓存中查询 ,以sql为key查询,得到数据,直接返回,
 * 如果没有相应的sql语句,则查询数据库
 */
public class TestMybatis {

    @Test
    public void test(){
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("mybatis-config.xml");
        //SqlSession工厂对象:单例模式
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserDao userDao1 = sqlSession.getMapper(UserDao.class);

        List<User> userList1 = userDao1.findAll();
        for (User user : userList1) {
            System.out.println(user);
        }
        sqlSession.close();
        //删除操作
//        UserDao  userDao2 = sqlSession.getMapper(UserDao.class);
//        userDao2.del(14);
//        sqlSession.commit();
        //清空缓存
//        sqlSession.clearCache();

        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        UserDao  userDao3 = sqlSession2.getMapper(UserDao.class);
        List<User> userList3 = userDao3.findAll();
        for (User user : userList3) {
            System.out.println(user);
        }

        sqlSession2.close();
    }
}
二级缓存
/**
 * 二级缓存
 *   1. 是sessionFactory级别的, 可以在多个SqlSession对象共享缓存数据
 *   2. 默认的是开启的
 *      <setting name="cacheEnabled" value="true"/>
 *   3. 在需要使用二级缓存的配置映射文件中开启
 *      <cache/>
 *   4. 需要在二级缓存中保存的pojo对象必须实现序列化接口
 *       User  implements Serializable
 *   5. 在同一namespace范围下,执行提交操作,会清空该namespace的缓存
 *   
 * 二级缓存的工作流程
 *     1,在任意一个sqlSession对象中执行了sql查询语句,
 * 当关闭sqlSession对象时,在二级缓存中保存数据:以 namespace.sql语句为key值
 *      以对象为value存储
 *     2. 当其他sqlSession对象执行时, 需要根据namespace.sql 查询是否存在缓存
 */
public class TestMybatis {

    @Test
    public void test(){
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("mybatis-config.xml");
        //SqlSession工厂对象:单例模式
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserDao userDao1 = sqlSession.getMapper(UserDao.class);

        List<User> userList1 = userDao1.findAll();
        for (User user : userList1) {
            System.out.println(user);
        }
        sqlSession.close();

        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        UserDao  userDao2 = sqlSession2.getMapper(UserDao.class);
        List<User> userList2 = userDao2.findAll();
        for (User user : userList2) {
            System.out.println(user);
        }

        sqlSession2.close();

        SqlSession sqlSession3 = sqlSessionFactory.openSession();
        UserDao  userDao3 = sqlSession3.getMapper(UserDao.class);
        List<User> userList3 = userDao3.findAll();
        for (User user : userList3) {
            System.out.println(user);
        }

        sqlSession3.close();
    }
}
五、mybatis注解开发

1、实现增删改查

public interface UserDao {

//    @Results 映射结果集, value = @Result 数组对象
//    @Result 映射列名与属性名不一样的
//           id 的默认值是false 默认为非主键
//    id=true 指定该列为主键
//    注解中:只需要写列名与属性名不一样的,一样的可以不写
//    特殊情况: 如果某列数据使用了两次或者两次以上,则两次映射都需要写出来
    @Results({
            @Result(id=true, column = "uid",property = "id"),
            @Result(column = "uname",property = "username")
    })
    @Select("select * from user")
    public List<User> findAll();

    @Select("select * from user where uid=#{id}")
    public User findById(Integer id);

    @Select("select * from user where uname like \"%\"#{username}\"%\" ")
    public List<User> findByUsername(String username);

    @Select("select count(*) from user")
    public Integer findTotalCount();

//    保存获取主键(主键回显): @SelectKey   一般在oracle中会使用
//    keyProperty: 主键的属性名
//    keyColumn :主键列名
//    resultType: 主键的类型
//    before=false : 不是在添加之前, 添加之后查询
//    before=true : 在添加之前查询
//    statement: 需要执行的sql语句
//    select last_insert_id() :最后一次执行添加生成的主键
    /**
     *  在xml 主键回显
     *  <selectKey keyColumn="uid" keyProperty="id" resultType="int" order="AFTER">
            select last_insert_id()
         </selectKey>
     */
    @SelectKey(keyProperty = "id",keyColumn = "uid",resultType = Integer.class,before = false,
    statement = "select last_insert_id()")
    @Insert("insert into user values(null ,#{username},#{password},#{sex},#{address},#{birthday})")
    public void insert(User user);


    @Update("update user set uname = #{username}, password=#{password}, sex = #{sex}" +
            ",address=#{address},birthday = #{birthday} where uid = #{id}")
    public void update(User user);

    @Delete("delete from user where uid = #{id}")
    public void del(Integer id);
}

2、实现一对一
AccountDao.java

public interface AccountDao {
    /**
     * 查询全部账户(包含用户信息)
     *  one = @One(select = "" , fetchType=""):对应一个对象
     *          select 属性:mapperId = namespace.id
     *
     *           fetchType = FetchType.LAZY:提取方式为延迟加载,默认是立即加载
     *  Many: 对应多个对象
     * 
     */
    @Select("select * from account")
    @Results({
            @Result(property = "user", column = "u_id",javaType = User.class,
                    one = @One(select = "com.itheima.dao.UserDao.findById", 	
                    fetchType = FetchType.LAZY))
    })
    public List<Account> findAll();
}

UserDao.java

public interface UserDao {
 
    @Select("select * from user where uid = #{id}")
    @Results({
            @Result(id = true,column = "uid" ,property = "id"),
            @Result(column = "uname",property = "username")
    })
    public User findById(Integer id);
}

3、实现一对多
UserDao.java

public interface UserDao {

	/**
     * javaType = List.class,可以省略
     * 
     * <collection property="accountList" column="uid" ofType="Account"
            select="com.itheima.dao.AccountDao.findByUserId" fetchType="lazy">
       </collection>
     * 
     */
    @Results({
            @Result(id = true ,property = "id",column = "uid"),
            @Result(property = "accountList", column = "uid",javaType = List.class,
                    many = @Many(select = "com.itheima.dao.AccountDao.findById" ))
    })
    @Select("select * from user")
    public List<User> findAll();
}

AccountDao.java

public interface AccountDao {
    @Select("select * from account where uid = #{uid}")
    public Account findById(Integer id);
}

4、实现动态sql

UserDao.java

public interface UserDao {
	/**
     * 根据姓名模糊查询,性别等于查询
     *
     * Provider:提供者
     * @SelectProvider: sql语句提供者
     *
     * Type: sql语句提供者的类的字节码
     * method: 提供者类中的方法
     * 
     */
    @SelectProvider(type = UserSqlProvider.class,method = "findByCondition")
    @Results({
            @Result(id = true, property = "id" , column = "uid")
    })
    public List<User> findByCondition(User user);

}

UserSqlProvider.java

public class UserSqlProvider {

    public String findByCondition(User user){
    
        StringBuffer sb = new StringBuffer();
        sb.append("select * from user where 1=1 ");
        if (user.getUsername()!=null){
            sb.append(" and username like \"%\"#{username}\"%\" ");
        }
        if (user.getSex()!=null){
            sb.append(" and sex =#{sex} ");
        }
        return sb.toString();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值