MyBatis学习笔记(二)

Configration.xml中的<properties>标签

使用此标签可以加载.properties文件中的内容
则可以写成用${}取值
Configration.xml

	<!--从配置文件中获取数据库用户信息-->
	<properties resource="com/my/config/jdbcConfig.properties"/>

    <!--配置JDBC的加载驱动、url、用户名、密码-->
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"/>
            <!--type属性表示使用何种连接池方式,POOLED开启连接池,UNPOOLED关闭-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

jdbcConfig.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mydatabase?serverTimezone=GMT
jdbc.username=root
jdbc.password=root

接口式编程

最原先调用xml中的sql语句要用到形如messageList = sqlSession.selectList("User.getUserList", user);的语句,既没有限制参数类型,也没有限制返回值类型,还要知道命名空间跟id,十分不方便,MyBatis提供了一个动态代理方法SqlSession.getMapper()会返回一个实现类,具体实现如下。

1.首先定义一个需要被实现的接口

package com.my.dao.interfaces;

import com.my.bean.User;
import java.util.List;

public interface IUsers {
    //函数名要跟语句id同名
    List<User> getUsers(User user);
}

接口内声明的方法的返回值即为xml文件中配置的sql语句的查询返回值,方法的参数为需要传入的查询条件,方法名和SQL语句的id必须相同

2.配置Configration.xml文件

将接口的包名添加至配置文件内

<!--加载配置SQL语句的配置文件-->
    <mappers>
        <!--动态代理模式-->
        <package name="com/my/config/sqlxml/interfaces"/>
    </mappers>

3.配置存放SQL语句的文件

更改User.xml文件的命名空间为接口的路径

<mapper namespace="com.my.dao.interfaces.IUsers">

4.测试类

调用getMapper()方法

//查询用户
    @Test
    public void selectAllUser(){
        SqlSession sqlSession = DBAccess.getSqlSession();
        IUsers dao = sqlSession.getMapper(IUsers.class);
        List<User> users = dao.getUsers(null);
        for(User user : users){
            System.out.println(user);
        }
    }

一对多查询

1.准备另外一张表和一些数据

里面不仅要包括自身的id还要包括其从属用户的uid

CREATE TABLE account
(
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    uid INT UNSIGNED NOT NULL,
    money DOUBLE NOT NULL,
);

INSERT account(uid, money) VALUES(1, 555.5),(1, 2000),(2, 1222);

相应的Bean

package com.my.bean;

public class Account {

    private Integer uid;
    private Integer id;
    private Double money;
	.
	.
	.
	//Getter and Setter
	//Override toString()
}

2.修改User类

package com.my.bean;

import java.util.List;

public class User {
    private Integer id;
    private String username;

    //增加一个Account的成员作为集合
    private List<Account> accounts;
    .
	.
	.
	//Getter and Setter
}

3.修改映射

使用<collection>标签来配置集合中元素的映射关系
也可以使用resultMap属性使用其他文件的映射关系

<!--一对多映射表-->
    <resultMap id="UserMap" type="com.my.bean.User">
        <id column="id" jdbcType="INTEGER" property="id"/>
        <result column="username" jdbcType="VARCHAR" property="username"/>
        <collection property="accounts" ofType="com.my.bean.Account">
            <id column="aid" jdbcType="INTEGER" property="id"/>
            <result column="uid" jdbcType="INTEGER" property="uid"/>
            <result column="money" jdbcType="DOUBLE" property="money"/>
        </collection>
    </resultMap>

4.SQL语句

<!--一对多查询-->
    <select id="getUsers2Accounts" resultMap="UserMap">
        SELECT u.id,u.username,a.id aid,a.uid,a.money FROM users u
        LEFT JOIN account a on a.uid = u.id;
    </select>

5. 修改IUsers接口

package com.my.dao.interfaces;

import com.my.bean.User;
import java.util.List;

public interface IUsers {
    List<User> getUsers(User user);
	//
    List<User> getUsers2Accounts();
}

6.测试类

@Test
public void testOne2Multi(){
    SqlSession sqlSession = DBAccess.getSqlSession();
    IUsers dao = sqlSession.getMapper(IUsers.class);
    List<User> users = dao.getUsers2Accounts();
    for(User user : users){
        System.out.println(user);
        List<Account> accounts = user.getAccounts();
        for(Account account : accounts){
			System.out.println(account);
		}
    }
}

多对多查询

多对多查询相当于双向的一对多查询,需要一个中间表作为连接,形如

CREATE TABLE user_account(
    uid INT UNSIGNED NOT NULL,
    aid INT UNSIGNED NOT NULL,
);

多次左外连接即可获得想要的表,其余操作与一对多雷同,不再赘述。


连接池

Configration.xml配置文件中有一个<dataSource type="POOLED">标签

  • UNPOOLED
    不使用连接池,每次调用openSession()都会重新开启一个新的连接,相当于JDBC的DriverManager.getConnection(URL, USER, PASSWORD),如每次查询都开启新连接则效率低下
  • POOLED
    使用连接池,连接池类似连接对象的集合,每次调用openSession()都会从连接池中获取连接,关闭连接后则放回连接池,比不使用连接池更高效
  • JNDI
    交给JNDI实现

自动提交事务

  • openSession(true)方法中传入参数true则在增删改时不需要调用commit()来提交操作,会自动提交

延迟加载与按需加载

  • 延迟加载
    在使用数据时才发起查询,不用试不查询。按需加载(懒加载)。一对多查询比较适用
  • 立即加载
    不管用不用,只要一调用方法马上发起查询。一对一查询比较适用

1.修改Configration.xml

<!--配置延迟加载-->
	<settings>
    	<!-- 打开延迟加载的开关 -->
     	<setting name="lazyLoadingEnabled" value="true" />
     	<!-- 将积极加载改为消息加载即按需加载 -->
     	<setting name="aggressiveLazyLoading" value="false"/>
	</settings>

:settings标签一定要写在<prorperties>标签后面,否则会报错

2.修改User.xml

在collection中配置子集合的查询语句,调用子集合对象的SQL语句,column是需要传入的查询条件

	<resultMap id="UserResult" type="com.my.bean.User">
   	 	<id column="id" jdbcType="INTEGER" property="id"/>
    	<result column="username" jdbcType="VARCHAR" property="username"/>
    	<collection property="accounts" ofType="com.my.bean.Account"
    				select="com.my.dao.interfaces.IAccount.getAccountByUid" column="id"/>
	</resultMap>

3.修改Account.xml

添加一条需要被调用的,根据uid查询的查询语句

<!--根据用户id查询账户-->
	<select id="getAccountByUid" resultType="com.my.bean.Account" parameterType="int">
		SELECT * FROM account WHERE uid=#{uid}
	</select>

:由于只有一个参数#{}内不管填什么都可以取到参数

4.修改IAccount接口

声明一条函数

List<Account> getAccountByUid(int uid);

5.测试类

可以将注释部分取消,然后观察结果,很明显,如果没有历遍accounts,MyBatis不会进行查询

@Test
public void testLazyLoad(){
	SqlSession sqlSession = DBAccess.getSqlSession();
    IUsers dao = sqlSession.getMapper(IUsers.class);
    List<User> users = dao.getUsers2Accounts();
    for(User user : users){
        System.out.println(user);
        List<Account> accounts = user.getAccounts();
//        for(Account account : accounts){
//			System.out.println(account);
//		}
    }
}

缓存

  • 什么是缓存及其作用
    存在内存中的临时数据,用于减少与数据库的交互次数,提高运行效率
  • 什么数据适合使用缓存
    经常查询且不经常更改的
    查询结果的正确与否对结果影响不大的
  • 什么数据不适合使用缓存
    不经常查询且经常更改的
    查询结果的正确与否对结果影响很大的
一级缓存
  • 它指的是SqlSession对象的缓存
  • 当我们执行查询之后,查询的结果会同时存入SqlSession为我们提供的一块区域中。该区域是一个Map,当我们再次查询同样的数据时,SqlSession会先在Map中查询,如果没有则查询
  • 当调用SqlSession的增删改和commit()close()方法时,一级缓存会被清空
二级缓存
  • 他指的是MyBatis中SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
  • 使用二级缓存

1.配置Configration.xml

在settings标签下添加

<!--开启二级缓存-->
       <setting name="cacheEnabled" value="true"/>

不添加也行,默认是开启的

2.配置User.xml

添加标签

<!--开启二级缓存-->
	<cache/>

3.配置SQL语句

在需要支持二级缓存的语句下添加useCache="true"

    <select id="getUsers" resultMap="UserResult" useCache="true">
        SELECT * FROM users
    </select>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值