整体介绍
-
mybatis中的连接池以及事务控制
- mybatis中连接池使用及分析
- mybatis事务控制分析
-
mybatis基于xml配置动态SQL语句使用
mappers 配置文件中的几个标签
<if> <where> <foreach> <sql>
-
mybatis中的多表操作
一对多
一对一
多对多
连接池
-
概念
我们实际开发中都会使用连接池,因为它可以减少我们获取连接所消耗的时间 -
mybatis中的连接池
mybatis连接池提供了3种方式配置:
配置的位置:
主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是采用哪种方式的连接
type属性:POOLED 采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现 UNPOOLED 采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的思想。 JNDI 采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样。 注意:如果不是web或者maven的war工程,是不能使用的。 我们课程中使用的是tomcat服务器,采用连接池就是dbcp连接池。
-
mybatis中的事务
- 什么是事务
- 事务4大特性
- 不考虑隔离性会产生的3个问题
- 解决办法:四种隔离级别
它是通过sqlsession对象的commit方法和rollback方法实现事务的提交和回滚
mybatis动态sql
- where if (普通的输入框)
<!-- 根据不确定参数条件查询 -->
<select id="findUserByCondition" parameterType="user" resultMap="userMap">
select * from user
<where>
<if test="username != null">
and username = #{username}
</if>
<if test="sex != null">
and sex = #{sex}
</if>
</where>
</select>
<!-- 测试方法 -->
测试方法
//测试 多条件查询 where if
@Test
public void testFindByCondition() {
User u = new User();
u.setUsername("老王");
u.setSex("女");
List<User> users = userDao.findUserByCondition(u);
for (User user : users) {
System.out.println(user);
}
}
- foreach (复选框)
<!--根据queryvo中的I的集合实现查询用户列表-->
<select id="findUserInIds" parameterType="queryvo" resultMap="userMap">
select * from user
<where>
<if test="ids != null and ids.size() > 0">
<foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
#{uid}
</foreach>
</if>
</where>
</select>
<!-- 测试方法 -->
测试方法
//测试子查询 方法 foreach
@Test
public void testfindUserInIds() {
QueryVo queryVo = new QueryVo();
List<Integer> list = new ArrayList<Integer>();
list.add(41);
list.add(42);
list.add(43);
queryVo.setIds(list);
List<User> users = userDao.findUserInIds(queryVo);
for (User user : users) {
System.out.println(user);
}
}
注意
1.抽离公共sql代码,主要针对查询的对应的实体类对应的列名,单独抽离出来,方便下面使用。
<!--抽离公共sql 主要针对 查询表的时候不要用*-->
<sql id="defaultUser">
select id, username, sex, birthday, sex, address from user
</sql>
<!-- 使用 -->
<!--根据queryvo中的I的集合实现查询用户列表-->
<select id="findUserInIds" parameterType="queryvo" resultMap="userMap">
<include refid="defaultUser"></include>
<where>
<if test="ids != null and ids.size() > 0">
<foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
#{uid}
</foreach>
</if>
</where>
</select>
mybatis多表查询
一对多
一对一
多对多
举例:
用户和订单就是一对多
订单和用户就是多对一
一个用户可以下多个订单
多个订单属于同一个用户
人和身份证号就是一对一
一个人只能有一个身份证号
一个身份证号只能属于一个人
老师和学生之间就是多对多
一个学生可以被多个老师教过
一个老师可以交多个学生
特例:
如果拿出每一个订单,他都只能属于一个用户。
所以Mybatis就把多对一看成了一对一。
- mybatis 一对多的查询 关联对象
一个用户有多个账户
实体类
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
// 体现 一对多的关系
//从表的实体类包含一个主表的实体的对象引用
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", uid=" + uid +
", money=" + money +
'}';
}
}
dao映射文件
<!--定义封装account和user的resultMap-->
<resultMap id="accountUserMap" type="account">
<id property="id" column="aid"></id>
<result property="uid" column="UID"></result>
<result property="money" column="MONEY"></result>
<!--一对一的关系映射 配置封装user内容-->
<association property="user" column="UID" javaType="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
</association>
</resultMap>
<!--配置查询所有-->
<select id="findAll" resultMap="accountUserMap">
select u.*,a.ID as aid,a.UID, a.MONEY from user u,account a where u.id = a.UID
</select>
<select id="findAllAccount" resultMap="accountUserMap">
select a.*,u.username,u.address from user u,account a where u.id = a.UID
</select>
- 一对多 关联集合
实体类
package com.itheima.domain;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
public class User implements Serializable {
//实体类属性和表中的列名保持一致
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
// 一对多
//主表实体类包含从表实体类的“集合”引用
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
dao的映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.dao.IUserDao">
<!--定义封装User的resultMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!--配置user对象 accounts集合映射-->
<collection property="accounts" ofType="account" >
<id property="id" column="aid"></id>
<result property="uid" column="UID"></result>
<result property="money" column="MONEY"></result>
</collection>
</resultMap>
<!--配置查询所有-->
<select id="findAll" resultMap="userAccountMap">
select u.*,a.ID as aid, a.UID, a.MONEY from user u left join account a on u.id = a.UID;
</select>
</mapper>
-
多表查询 多 对 多
- 以用户为主
用户实体类,体现 一对多
package com.itheima.domain; import java.io.Serializable; import java.util.Date; import java.util.List; public class User implements Serializable { //实体类属性和表中的列名保持一致 private Integer id; private String username; private Date birthday; private String sex; private String address; // 一对多 //主表实体类包含从表实体类的“集合”引用 private List<Account> accounts; //多对多 //一个用户对应多个角色 private List<Role> roles; public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; } public List<Account> getAccounts() { return accounts; } public void setAccounts(List<Account> accounts) { this.accounts = accounts; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + '}'; } }
用户的映射文件
<resultMap id="userMap" type="user"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="address" column="address"></result> <result property="sex" column="sex"></result> <result property="birthday" column="birthday"></result> <collection property="roles" ofType="role"> <id property="roleId" column="rid"></id> <result property="roleName" column="role_name"></result> <result property="roleDesc" column="role_desc"></result> </collection> </resultMap> <!--查询所有用户,同时获取用户的所赋予的角色--> <select id="findAll2" resultMap="userMap"> select u.*, r.id as rid,r.role_name, r.role_desc from user u left join user_role ur on u.id = ur.uid left join role r on r.id = ur.rid </select>
- 以角色为主
角色实体类
package com.itheima.domain; import java.io.Serializable; import java.util.List; public class Role implements Serializable { private Integer roleId; private String roleName; private String roleDesc; //多对多关系映射 //一个角色对应多个用户 private List<User> users; public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } public Integer getRoleId() { return roleId; } public void setRoleId(Integer roleId) { this.roleId = roleId; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } public String getRoleDesc() { return roleDesc; } public void setRoleDesc(String roleDesc) { this.roleDesc = roleDesc; } @Override public String toString() { return "Role{" + "roleId=" + roleId + ", roleName='" + roleName + '\'' + ", roleDesc='" + roleDesc + '\'' + '}'; } }
角色的映射文件
<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 property="id" column="id"></id> <result property="username" column="username"></result> <result property="address" column="address"></result> <result property="sex" column="sex"></result> <result property="birthday" column="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 join user_role ur on r.id = ur.rid left join user u on u.id = ur.uid </select>
注意
- mysql在window系统不区分大小写,在linux系统区分;
- 实体类的属性尽量使用驼峰,数据库的列名使用下划线;
- 当使用多表查询时,在navicat写好,复制到mapper文件,换行时多打几个空格;
- 以用户为主
网友评论