我是靠谱客的博主 迷你河马,最近开发中收集的这篇文章主要介绍MyBatis学习笔记(二)Configration.xml中的标签接口式编程一对多查询多对多查询连接池自动提交事务延迟加载与按需加载缓存,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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>

最后

以上就是迷你河马为你收集整理的MyBatis学习笔记(二)Configration.xml中的标签接口式编程一对多查询多对多查询连接池自动提交事务延迟加载与按需加载缓存的全部内容,希望文章能够帮你解决MyBatis学习笔记(二)Configration.xml中的标签接口式编程一对多查询多对多查询连接池自动提交事务延迟加载与按需加载缓存所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(79)

评论列表共有 0 条评论

立即
投稿
返回
顶部