1. 程式人生 > 其它 >連線池、事務控制、標籤、多表操作

連線池、事務控制、標籤、多表操作

技術標籤:# Mybatis

連線池、事務控制、標籤、多表操作

一:mybatis中的連線池以及事務控制

(1)mybatis中連線池使用

1.mybatis連線池提供了三種方式的配置

  1. 配置的位置:
    1. 主配置檔案SqlMapConfig.xml中的dataSource標籤,type屬性就是表示採用何種連線池方式
  2. type屬性的取值:
    1. POOLED:採用傳統的javax.sql.DataSource規範中的連線池,mybatis中有針對規範的實現。
    2. UNPOOLED:採用傳統的獲取連線的方式,雖然也實現了avax.sql.DataSource介面,但是並沒有使用池的思想。
    3. JNDI:採用伺服器提供的JNDI技術實現,來獲取DataSource物件,不同的伺服器所能拿到的DataSource是不一樣的。
      1. 注意:如果不是web或者maven的war工程,是不能使用的。
      2. 課程中使用的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)表之間的關係有幾種

  1. 一對多
  2. 多對一
  3. 一對一
  4. 多對多

(2)多表查詢例項

A.表:使用者表和賬戶表

  1. 一個使用者可以有多個賬戶
  2. 一個賬戶只能屬於一個使用者

B.步驟

  1. 建立兩張表:使用者表和賬戶表
    1. 讓使用者表和賬戶表之間具備一對多的關係:需要使用外來鍵在賬戶表中新增
  2. 建立兩個實體類:使用者實體類和賬戶實體類
    1. 讓兩個實體類體現出一對多的關係
  3. 建立兩個配置檔案
    1. 使用者的配置檔案
    2. 賬戶的配置檔案
  4. 實現配置
    1. 當我們查詢使用者時,可以同時得到使用者下所包含的賬戶資訊。
    2. 當我們查詢使用者時,可以同時得到賬戶的所屬使用者資訊。

(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)多對多查詢

示例:使用者和角色

  1. 一個使用者可以有多個角色
  2. 一個角色可以賦予多個使用者

步驟:

  1. 建立兩張表:使用者表,角色表
    1. 讓使用者表和角色表具有多對多的關係,需要使用中間表,中間表中包含各自的主鍵
  2. 建立兩個實體類:使用者實體類和角色實體類
    1. 讓使用者和角色的實體類能體現出來多對多的關係
    2. 各自包含對方的一個集合引用
  3. 建立兩個配置檔案
//角色實體類
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>