MyBatis连接池、事务、动态sql、多表查询

一、Mybaits 连接池技术

在 Mybatis 的 SqlMapConfig.xml 配置文件中,通过<dataSource type=”pooled”>来实现 Mybatis 中连接池的配置

1.1 Mybaits连接池的分类

Mybatis 将它自己的数据源分为三类:

  1. UNPOOLED 不使用连接池的数据源
  2. POOLED 使用连接池的数据源
  3. JNDI 使用 JNDI 实现的数据源

如下图:
在这里插入图片描述
MyBatis 内部分别定义了实现了 java.sql.DataSource 接口的 UnpooledDataSource,PooledDataSource 类来表示 UNPOOLED、POOLED 类型的数据源。

在这里插入图片描述
在这三种数据源中,我们一般采用的是 POOLED 数据源(很多时候我们所说的数据源就是为了更好的管理数据库连接,也就是我们所说的连接池技术)。

1.2 Mybatis中数据源的配置

我们的数据源配置就是在 SqlMapConfig.xml 文件中,具体配置如下:
<!-- 配置数据源(连接池)信息 -->
<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>
MyBatis 在初始化时,根据<dataSource>的 type 属性来创建相应类型的的数据源 DataSource,即:
type=”POOLED”:MyBatis 会创建 PooledDataSource 实例
type=”UNPOOLED” : MyBatis 会创建 UnpooledDataSource 实例
type=”JNDI”:MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使用

1.3 Mybatis 中连接的获取过程

	当我们需要创建 SqlSession 对象并需要执行 SQL 语句时,这时候 MyBatis 才会去调用 dataSource 对象
来创建java.sql.Connection对象。也就是说,java.sql.Connection对象的创建一直延迟到执行
SQL语句
的时候。
	@Test
	public void testSql() throws Exception {
		InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
		SqlSession sqlSession = factory.openSession();
		List<User> list = sqlSession.selectList("findUserById",41);
		System.out.println(list.size());
	}
只有当第 4 句sqlSession.selectList("findUserById"),才会触发 MyBatis 在底层执行下面这个方
法来创建 java.sql.Connection 对象。

二、Mybaits的事务控制

对数据库记录进行增删改的时候必须进行事务的提交才可以,但是可以实现不用写session.commit()进行提交事务,就是在创建SqlSession对象的时候sqlSession工厂对象调用openSession()方法时,给一个参数true。不写默认时false。false默认不提交事务,当加上参数true时就可以不用写提交事务的操作了。

三、动态sql

1 、< if > 标签

if标签:见名思意,就是说if某个条件成立,就执行条件里面的
示例:
dao层:

//dao层
/**
* 根据用户信息,查询用户列表
* @param user
* @return
*/
List<User> findByUser(User user);

mapper.xml:

<select id="findByUser" resultType="user" parameterType="user">
	select * from user where 1=1
		<if test="username!=null and username != '' ">
			and username like #{username}
		</if>
		<if test="address != null">
			and address like #{address}
		</if>
</select>
注意:<if>标签的 test 属性中写的是对象的属性名,如果是包装类的对象要使用 OGNL 表达式的写法。
另外要注意 where 1=1 的作用~!

测试类:

public void testFindByUser() {
	User u = new User();
	u.setUsername("%王%");
	u.setAddress("%顺义%");
	//6.执行操作
	List<User> users = userDao.findByUser(u);
	for(User user : users) {
		System.out.println(user);
	}
}

2、< where >标签

当sql语句where后面要跟条件的时候么可以动态生成后面的语句

<!-- 根据用户信息查询 -->
<select id="findByUser" resultType="user" parameterType="user">
	<include refid="defaultSql"></include>
	<where>
		<if test="username!=null and username != '' ">
			and username like #{username}
		</if>
		<if test="address != null">
			and address like #{address}
		</if>
	</where>
</select>

3、< foreach >标签

当我们where后面有条件跟的是一个集合的时候该怎么办呢?
传统的sql语句如下:

SELECT * FROM USERS WHERE username LIKE '%张%' AND (id =10 OR id =89 OR id=16)
SELECT * FROM USERS WHERE username LIKE '%张%' AND id IN (10,89,16)

示例:
pojo类对象

/**
*
* <p>Title: QueryVo</p>
* <p>Description: 查询的条件</p>
* <p>Company: http://www.itheima.com/ </p>
*/
public class QueryVo implements Serializable {
	private List<Integer> ids;
	
	public List<Integer> getIds() {
		return ids;
	}
	public void setIds(List<Integer> ids) {
		this.ids = ids;
	}
}

dao层:

	**
	* 根据 id 集合查询用户
	* @param vo
	* @return
	*/
	List<User> findInIds(QueryVo vo);

mapper.xml:

<!-- 查询所有用户在 id 的集合之中 -->
<select id="findInIds" resultType="user" parameterType="queryvo">
<!-- select * from user where id in (1,2,3,4,5); -->
	<include refid="defaultSql"></include>
	<where>
		<if test="ids != null and ids.size() > 0">
			<foreach collection="ids" open="id in ( " close=")" item="uid" separator=",">
				#{uid}
			</foreach>
		</if>
	</where>
</select>
SQL 语句:
select 字段 from user where id in (?)
<foreach>标签用于遍历集合,它的属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符

测试方法:

@Test
public void testFindInIds() {
	QueryVo vo = new QueryVo();
	List<Integer> ids = new ArrayList<Integer>();
	ids.add(41);
	ids.add(42);
	ids.add(43);
	ids.add(46);
	ids.add(57);
	vo.setIds(ids);
	//6.执行操作
	List<User> users = userDao.findInIds(vo);
	for(User user : users) {
		System.out.println(user);
	}
}

三、多表查询

使用多表查询时,要根据对应关系,在映射的pojo类中添加对象。
有三种对应关系(直接贴mapper.xml代码):
一对一:在一个实体类中创建一个实体类对象

<!-- 自定义返回值类型   映射-->
	<resultMap type="User" id="UserAndRole">
		<id property="id" column="ID"/>
		<result property="userCode" column="USERCODE"/>
		<result property="userName" column="USERNAME"/>
		<result property="userPassword" column="USERPASSWORD"/>
		<!-- 一对一关系 -->
		<association property="role" javaType="com.zhiyou.pojo.Role">
			<id property="id" column="ID"/>
			<result property="roleCode" column="ROLECODE"/>
			<result property="roleName" column="ROLENAME"/>
		</association>
	</resultMap>

一对多:在实体类中创建对象集合

<resultMap type="Role" id="RoleAndUser">
  		<id property="id" column="ID"/>
  		<result property="roleName" column="roleName"/>
  		<result property="createBy" column="createBy"/>
  		<!-- 继续写  有几个属性写几个对应关系 -->
  		<!-- 用于一对多 -->
  		<collection property="list" ofType="User">
		<id property="id" column="ID"/>
		<result property="userCode" column="userCode"/>
		<result property="userName" column="userName"/>
		<result property="birthday" column="birthday"/>
  		</collection>
  	</resultMap>

多对多:就需要一张中间表,中间表实体类分别有两边对象集合。
实现从一张表到另一张表的多对多。
示例:

<!--定义 role 表的 ResultMap-->
<resultMap id="roleMap" type="role">
	<id property="roleId" column="rid"></id>
	<result property="roleName" column="role_name"></result>
	<result property="roleDesc" column="role_desc"></result>
	<collection property="users" ofType="user">
		<id column="id" property="id"></id>
		<result column="username" property="username"></result>
		<result column="address" property="address"></result>
		<result column="sex" property="sex"></result>
		<result column="birthday" property="birthday"></result>
	</collection>
</resultMap>

<!--查询所有-->
<select id="findAll" resultMap="roleMap">
	select u.*,r.id as rid,r.role_name,r.role_desc from role r
	left outer join user_role ur on r.id = ur.rid
	left outer join user u on u.id = ur.uid
</select>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值