連線池、事務控制、標籤、多表操作
阿新 • • 發佈:2021-01-24
技術標籤:# Mybatis
連線池、事務控制、標籤、多表操作
一:mybatis中的連線池以及事務控制
(1)mybatis中連線池使用
1.mybatis連線池提供了三種方式的配置
- 配置的位置:
- 主配置檔案SqlMapConfig.xml中的dataSource標籤,type屬性就是表示採用何種連線池方式
- type屬性的取值:
- POOLED:採用傳統的javax.sql.DataSource規範中的連線池,mybatis中有針對規範的實現。
- UNPOOLED:採用傳統的獲取連線的方式,雖然也實現了avax.sql.DataSource介面,但是並沒有使用池的思想。
- JNDI:採用伺服器提供的JNDI技術實現,來獲取DataSource物件,不同的伺服器所能拿到的DataSource是不一樣的。
- 注意:如果不是web或者maven的war工程,是不能使用的。
- 課程中使用的tomcat伺服器,採用的連線池就是dbcp連線池
(2)mybatis中事務控制
二:mybatis基於XML配置的動態SQL語句使用
mappers配置檔案中的幾個標籤:
標籤
//UserDao.java中的方法
/**
* 根據傳入引數條件
* @param user 查詢的條件:有可能是使用者名稱,也有可能是性別。。。
* @return
*/
List<User> findUserByCondition(User user);
//UserDao.xml中的部分語句
<!--根據條件查詢-->
<select id="findUserByCondition" resultType="user" parameterType="user">
select * from user where 1=1
<!--if標籤-->
<if test="username != null">
and username = #{username}
</if>
< if test="sex != null">
and sex = #{sex}
</if>
</select>
//測試方法
//測試查詢條件
@Test
public void testFindUserByCondition(){
User user = new User();
user.setUsername("老王");
user.setSex("女");
List<User> users1 = userDao.findUserByCondition(user);
for (User user1 : users1) {
System.out.println(user1);
}
}
標籤
//UserDao.xml中的部分語句
<!--根據條件查詢-->
<select id="findUserByCondition" resultType="user" parameterType="user">
select * from user
<!--where標籤-->
<where>
<!--if標籤-->
<if test="username != null">
and username = #{username}
</if>
<if test="sex != null">
and sex = #{sex}
</if>
</where>
</select>
標籤
//QueryVo.java
public class QueryVo {
private User user;
private List<Integer> ids;
public void setUser(User user) {
this.user = user;
}
public User getUser() {
return user;
}
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
}
//UserDao介面的方法
/**
* 根據QueryVo提供的id集合查詢使用者資訊
* @param vo
* @return
*/
List<User> findUserInIds(QueryVo vo);
//UserDao.xml
<!--根據QueryVo提供的id集合查詢使用者資訊列表-->
<select id="findUserInIds" resultType="user" parameterType="queryVo">
select * from user
<where>
<if test="ids != null and ids.size() > 0">
<foreach collection="ids" open="and id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</if>
</where>
</select>
//測試方法
//測試子查詢foreach標籤的使用
@Test
public void testFindUserInIds(){
QueryVo vo = new QueryVo();
List<Integer> list = new ArrayList<>();
list.add(44);
list.add(45);
list.add(46);
vo.setIds(list);
List<User> userInIds = userDao.findUserInIds(vo);
for (User userInId : userInIds) {
System.out.println(userInId);
}
}
標籤
//UserDao.xml中的部分內容
<!--瞭解的內容,抽取重複的sql語句-->
<sql id="defaultUser">
select * from user
</sql>
<!--抽取重複的SQL語句的使用-->
<select id="findAll" resultType="user" >
<include refid="defaultUser"></include>
</select>
三:mybatis中的多表操作(重點)
(1)表之間的關係有幾種
- 一對多
- 多對一
- 一對一
- 多對多
(2)多表查詢例項
A.表:使用者表和賬戶表
- 一個使用者可以有多個賬戶
- 一個賬戶只能屬於一個使用者
B.步驟
- 建立兩張表:使用者表和賬戶表
- 讓使用者表和賬戶表之間具備一對多的關係:需要使用外來鍵在賬戶表中新增
- 建立兩個實體類:使用者實體類和賬戶實體類
- 讓兩個實體類體現出一對多的關係
- 建立兩個配置檔案
- 使用者的配置檔案
- 賬戶的配置檔案
- 實現配置
- 當我們查詢使用者時,可以同時得到使用者下所包含的賬戶資訊。
- 當我們查詢使用者時,可以同時得到賬戶的所屬使用者資訊。
(3)一對一查詢
//Account.class
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//從表實體應該包含一個主表實體的物件引用
private 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;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", uid=" + uid +
", money=" + money +
", user=" + user +
'}';
}
}
public class AccountUser extends Account{
private String username;
private String address;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
//先呼叫父類的toString()
@Override
public String toString() {
return super.toString()+"AccountUser{" +
"username='" + username + '\'' +
", address='" + address + '\'' +
'}';
}
}
public interface AccountDao {
/**
* 查詢所有賬戶,同時還要獲取到當前賬戶的所屬使用者資訊
* @return
*/
List<Account> findAll();
/**
* 查詢所有賬戶,並且帶有使用者名稱稱和地址資訊
* @return
*/
List<AccountUser> findAllAccount();
}
//AccountDao.xml
<?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.hgk.dao.AccountDao">
<!--定義封裝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的內容
javaType屬性:用於提示封裝哪個物件
-->
<association property="user" column="uid" javaType="user">
<result column="username" property="username"></result>
<result column="address" property="address"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></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" resultType="accountUser">
SELECT a.*,u.username,u.address FROM `user` u,`account` a WHERE u.id=a.uid
</select>
</mapper>
//測試類
public class AccountTest {
private InputStream in = null;
private SqlSession session = null;
private AccountDao accountDao = null;
@Before //在測試方法之前執行
public void init() throws IOException {
//1.讀取配置檔案
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.建立SqlSessionFactory工廠
//建立工廠:mybatis使用了構建者模式,build就是構建者
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.使用工廠生產SqlSession物件
//生產SqlSession使用了工廠模式
session = factory.openSession();
//4.使用SqlSession建立Dao介面的代理物件
//建立dao介面實現類使用了代理模式
accountDao = session.getMapper(AccountDao.class);
}
@After //在測試方法之後執行
public void destory() throws Exception{
//提交事務
session.commit();
//6.釋放資源
session.close();
in.close();
}
//執行AccountDao中的查詢所有的方法,查詢所有賬戶,同時還要獲取到當前賬戶的所屬使用者資訊
@Test
public void testFindAll(){
List<Account> list = accountDao.findAll();
for (Account account : list) {
System.out.println(account);
System.out.println(account.getUser());
}
}
//查詢所有賬戶,並且帶有使用者名稱稱和地址資訊
@Test
public void testFindAllAccount(){
List<AccountUser> allAccount = accountDao.findAllAccount();
for (AccountUser accountUser : allAccount) {
System.out.println(accountUser);
}
}
}
(4)一對多查詢
//User.java中新加屬性
//一對多關係對映,主表實體類應該包含從表實體類的集合引用
private List<Account> accounts;
/*使用者的持久層介面*/
public interface UserDao {
/**
* 查詢所有操作,同時獲取使用者下所有賬戶的資訊
* @return
*/
List<User> findAll();
}
//UserDao.xml配置檔案
<?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.hgk.dao.UserDao">
<!--定義封裝user的resultMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="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>
<!--一對多的關係對映,配置user物件中的account集合的對映
ofType屬性:用於提示封裝哪個物件
-->
<collection property="accounts" column="aid" ofType="account">
<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 OUTER JOIN ACCOUNT a ON u.id = a.uid;
</select>
</mapper>
//測試類
public class UserTest {
private InputStream in = null;
private SqlSession session = null;
private UserDao userDao = null;
@Before //在測試方法之前執行
public void init() throws IOException {
//1.讀取配置檔案
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.建立SqlSessionFactory工廠
//建立工廠:mybatis使用了構建者模式,build就是構建者
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.使用工廠生產SqlSession物件
//生產SqlSession使用了工廠模式
session = factory.openSession();
//4.使用SqlSession建立Dao介面的代理物件
//建立dao介面實現類使用了代理模式
userDao = session.getMapper(UserDao.class);
}
@After //在測試方法之後執行
public void destory() throws Exception{
//提交事務
session.commit();
//6.釋放資源
session.close();
in.close();
}
//執行AccountDao中的查詢所有的方法,查詢所有賬戶,同時還要獲取到當前賬戶的所屬使用者資訊
@Test
public void testFindAll(){
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
System.out.println(user.getAccounts());
}
}
}
(5)多對多查詢
示例:使用者和角色
- 一個使用者可以有多個角色
- 一個角色可以賦予多個使用者
步驟:
- 建立兩張表:使用者表,角色表
- 讓使用者表和角色表具有多對多的關係,需要使用中間表,中間表中包含各自的主鍵
- 建立兩個實體類:使用者實體類和角色實體類
- 讓使用者和角色的實體類能體現出來多對多的關係
- 各自包含對方的一個集合引用
- 建立兩個配置檔案
//角色實體類
public class Role {
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 + '\'' +
", users=" + users +
'}';
}
}
public interface RoleDao {
/**
* 查詢所有角色,同時獲取使用者的資訊
* @return
*/
List<Role> findAll();
}
<?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.hgk.dao.RoleDao">
<!--定義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>
</mapper>