JavaEE體系架構概述
java EE是sum公司發布的標准企業級應用規范集合,它提供了一個多層結構的分布式應程序模型,是開發基於網絡的企業級應用首選平台。Java EE技術平台的核心思想是“容器”加組件
事務:有明確邊界的一組序列,在應用程序中一個請求對應一個事務,當請求發送時,事務開始,當請求結束,事務也就結束。總的來說,事務有四個特性:1、原子性,一個請求要么成功,要么失敗,不會再有其他情況;2、一致性,事務處理需要的和得到的時相同的;3、持久性,事務處理的結果時確認的、持久的,如果需要修改就要開啟新的事務;4、隔離性,事務與事務之間是互不相擾的
傳統web應用缺陷:
傳統的web應用缺乏對分布式組件對象的訪問支持,也就是說,它不支持企業分布式應用;並且它對事務的處理控制在數據上,而不是在業務上,同樣,它也就沒有辦法處理業務級事務;而且傳統的web應用過於依賴servlet規范,在web應用中所有功能都要有一個servlet,而所有的servlet都運行在web容器中,這樣和不利於我們測試代碼。
企業級應用:
以服務器為中心,通過網絡把服務器和分散的用戶聯系在一起的應用。一般現代企業級應用具有的特點:1、支持並發;2、事務支持;3、交互支持;4、群集支持;5、安全支持;6、分布式支持;7、web支持
EJB組件:
EJB(Enterprise JavaBean)企業JavaBean,時一個運行在EJB容器當中的服務器端的組件。
JavaEE規范把EJB分為三類:
- 會話Bean,它封裝的是業務邏輯中的動作行為,根據是否保持會話可分為無狀態的Bean和有狀態的Bean
- 實體Bean,它表示的是持久層數據的對象視圖,通常代表的是業務中的名詞
- 消息驅動Bean,它是JMS(Java消息服務)與EJB集成的結果,可以監聽JMS消息服務中的消息
EJB容器:
為EJB組件提供一個運行環境,並對EJB組件提供分布式處理、事務等服務支持。
Java EE 標准結構的缺陷
EJB設計缺陷:EJB業務邏輯組織方式是采用過程式設計,在業務邏輯中,一旦需求改變,業務邏輯就必須實現新的個性,代碼會不斷增加;而且,實體Bean也被設計成僅僅通過getter和setter方法暴露的持久化數據對象,但是一個真正的對象應該把針對自己狀態的行為封裝起來。
EJB開發問題:它的開發和測試非常麻煩和冗長。導致這樣的原因有三點;第一,編輯、編譯、調試周期長;第二,編碼冗長、繁瑣;第三,必須編寫數據傳送對象(DTO)
POJO(plain old java object)基於面向對象編程可以作為EJB的替代品,它的持久化可以采用大量的持久化框架,如:MyBatis等,同樣,Spring可以對POJO提供事務處理,以及通過依賴注入來配置應用程序
MyBatis
基於持久層封裝有兩種方式:第一是對JDBC連接進行封裝,第二是對sql語句進行封裝;只要滿足其中之一的為半自動框架,二者都滿足的為全自動框架。
mybatis是一種持久層框架,也屬於ORM映射。前身是ibatis。mybiatis缺點與缺點:為半自動化,需要自已寫SQL語句,需要自己定義映射。增加了程序員的一些操作,但帶來了設計上的靈活;對數據庫的兼容性比較差差。移植性不好,但可編寫靈活和高性能的SQL語句。
mybatis組成
- 核心對象:SqlSessionFactory SqlSession;SqlSessionFactory 用於生產SqlSession對象的工廠類
- 配置文件:mybatis.cfg.xml 全局配置文件,配置數據連接信息
- 多個類配置文件:user.xml相當於接口的實現類,執行SQL語句
- 支持注解配置
配置文件:mybatis.cfg.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "/WEB-INF/dtd/mybatis-3-config.dtd"> 3 <configuration> 4 5 <!-- 開啟緩存機制,要求所有的映射器都支持緩存 --> 6 <settings> 7 <setting name="cacheEnabled" value="true"></setting> 8 </settings> 9 10 11 <typeAliases> 12 <!-- 一個一個給實體類型取類的別名 13 <typeAlias type="com.lovo.beans.UserBean" alias="UserBean"/>--> 14 15 <package name="com.lovo.beans"/> 16 </typeAliases> 17 18 19 <environments default="first"> 20 <!-- 一個數據源對應一個環境配置 --> 21 <environment id="first"> 22 23 <!-- 配置事務管理器,type="JDBC"表示使用JDBC事務處理機制來處理事務,MANAGED表示什么都不干,等待外部容器或者其他應用程序來處理事務 --> 24 <transactionManager type="JDBC"></transactionManager> 25 26 <!-- 配置數據源,type="POOLED"表示使用JDBC連接池; 27 UNPOOLED表示不使用JDBC連接池,也就是說每次請求就分別對應一個連接 ; 28 JNDI表示需要依賴外部容器提供連接池--> 29 30 <dataSource type="POOLED"> 31 <property name="driver" value="com.mysql.jdbc.Driver"/> 32 <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8"/> 33 <property name="username" value="root"/> 34 <property name="password" value="lovo"/> 35 </dataSource> 36 </environment> 37 </environments> 38 39 <mappers> 40 <!-- 41 <mapper resource="com/lovo/mapper/UserMapper.xml"/> --> 42 <package name="com.lovo.mapper"/> 43 </mappers> 44 45 46 47 </configuration>
類配置文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper PUBLIC "-mybatis.org/DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3 <mapper namespace="com.lovo.mapper.UserMapper"> 4 <!-- 為該映射器配置緩存 --> 5 <cache/> 6 7 <!-- resultMap 與resultType 是指定的返回結果集與類中屬性的關系,而不是返回類型 --> 8 <resultMap type="UserBean" id="userMap"> 9 <id property="id" column="id" javaType="java.lang.Long"/> 10 <result property="userName" column="user_name" javaType="java.lang.String"/> 11 </resultMap> 12 13 <!-- id="saveUserInfo" 代表着實現的是哪個接口方法, 14 parameterType="com.lovo.beans.UserBean" 代表着傳入的參數,它的類型 15 useGeneratedKeys="true" 代表着獲取數據庫自增長的ID信息 16 keyProperty="u.id" 代表着將獲取到的ID值賦值給哪個屬性 --> 17 <insert id="saveUserInfo" parameterType="UserBean" useGeneratedKeys="true" keyProperty="u.id"> 18 insert into t_user(id,user_name,sex) values (null,#{u.userName},#{u.sex}) 19 </insert> 20 21 <insert id="batchSaveUser"> 22 insert into t_user (user_name,sex) values 23 24 25 <!-- 動態SQL之foreach的用法 --> 26 <!-- collection="users" 用於指定循環集合的名稱,如果接口中並未指定參數別名,那么默認就是list 27 item="u" 用於指定每次循環后的對象的別名 28 separator="," 用於指定每次循環后之間的分割符--> 29 <foreach collection="users" item="u" separator=","> 30 (#{u.userName},#{u.sex}) 31 </foreach> 32 </insert> 33 34 <update id="updateUserInfo"> 35 <!-- 36 update t_user set user_name = #{u.userName},sex = #{u.sex} where id = #{id} 37 --> 38 <!-- 動態SQL之set if的用法 --> 39 update t_user 40 <set> 41 <if test="u.userName != null"> 42 user_name = #{u.userName}, 43 </if> 44 45 <if test="u.sex != null"> 46 sex = #{u.sex} 47 </if> 48 49 </set> 50 51 <where> 52 id = #{id} 53 </where> 54 </update> 55 56 <delete id="deleteUserById"> 57 delete from t_user where id = #{id} 58 </delete> 59 60 <delete id="batchDeleteUser"> 61 delete from t_user where id in ( 62 <foreach collection="ids" item="id" separator=","> 63 #{id} 64 </foreach> 65 ) 66 67 <!-- 第二種批量刪除的寫法 68 delete from t_user where id in 69 <foreach collection="ids" item="id" separator="," open="(" close=")"> 70 #{id} 71 </foreach> --> 72 </delete> 73 74 <select id="getUserInfoById" resultMap="userMap" useCache="true"> 75 select * from t_user where id = #{id} 76 </select> 77 78 <select id="queryUserInfoByName" resultType="UserBean"> 79 <!-- CONCAT('%',#{name},'%')該數據庫函數,主要用戶拼接字符串 --> 80 select u.user_name as userName,u.sex as sex from t_user as u where u.user_name like CONCAT('%',#{name},'%') 81 </select> 82 83 <select id="findUserInfoByDeptName" resultType="UserBean"> 84 select u.user_name as userName,u.sex as sex from t_user as u left join t_dept as d on u.fk_dept_id = d.id where d.dept_name like CONCAT('%',#{name},'%') 85 </select> 86 87 <!-- mybatis取得復合對象內部值的方式是:對象.復合對象.復合對象的屬性 --> 88 <select id="findUserInfoByDept" resultType="UserBean"> 89 select u.user_name as userName,u.sex as sex from t_user as u left join t_dept as d on u.fk_dept_id = d.id where d.dept_name like CONCAT('%',#{u.dept.deptName},'%') 90 </select> 91 92 <!-- 分頁統計 --> 93 <select id="countUserInfoByParams" resultType="int"> 94 select count(u.id) from t_user as u left join t_dept as d on u.fk_dept_id = d.id 95 <where> 96 <include refid="commonSQL"></include> 97 </where> 98 </select> 99 100 <select id="queryUserInfoByParams" resultType="UserBean"> 101 select u.id as id,u.user_name as userName,u.sex as sex from t_user as u left join t_dept as d on u.fk_dept_id = d.id 102 <where> 103 <include refid="commonSQL"></include> 104 limit ${page.index},${page.rows} 105 </where> 106 </select> 107 108 109 <!-- 公共的SQL語句可以提到一處,其他地方采用include獲取 --> 110 <sql id="commonSQL"> 111 <if test="userName != null && userName != ''"> 112 and u.user_name like CONCAT('%',#{userName},'%') 113 </if> 114 115 <if test="deptName != null && deptName != ''"> 116 and d.dept_name like CONCAT('%',#{deptName},'%') 117 </if> 118 </sql> 119 120 <!-- MAP作為參數傳值時,直接通過#{key}去獲取對應的值 --> 121 122 <select id="countUserInfoByMapParams" parameterType="java.util.Map" resultType="int"> 123 select count(u.id) from t_user as u left join t_dept as d on u.fk_dept_id = d.id 124 <trim prefix="where" prefixOverrides="and|or"> 125 <include refid="commonSQL"></include> 126 </trim> 127 </select> 128 129 <select id="queryUserInfoByMapParams" resultType="UserBean"> 130 select u.id as id,u.user_name as userName,u.sex as sex from t_user as u left join t_dept as d on u.fk_dept_id = d.id 131 <trim prefix="where" prefixOverrides="and|or" suffix="order by" suffixOverrides="and|or"> 132 <include refid="commonSQL"></include> 133 </trim> 134 <!--SQL語法: order by需要放置在limit之前 --> 135 u.id desc limit ${index},${rows} 136 </select> 137 138 <select id="queryUserInfoByNameAndSex" resultType="UserBean"> 139 select id as id,user_name as userName,sex as sex from t_user 140 <where> 141 142 <!-- choose when 等同於java中的switch case的組合, 143 只匹配一項,如果都不匹配,就執行otherwise中的內容,等同於default--> 144 <choose> 145 <when test="name != null"> 146 user_name like CONCAT('%',#{name},'%') 147 </when> 148 <when test="sex != null"> 149 and sex like CONCAT('%',#{sex},'%') 150 </when> 151 <otherwise>1=1</otherwise> 152 </choose> 153 </where> 154 </select> 155 156 </mapper>
注解配置
1 package com.lovo.mapper; 2 3 import java.util.List; 4 import java.util.Map; 5 6 import org.apache.ibatis.annotations.CacheNamespace; 7 import org.apache.ibatis.annotations.CacheNamespaceRef; 8 import org.apache.ibatis.annotations.Delete; 9 import org.apache.ibatis.annotations.Insert; 10 import org.apache.ibatis.annotations.Options; 11 import org.apache.ibatis.annotations.Param; 12 import org.apache.ibatis.annotations.Result; 13 import org.apache.ibatis.annotations.ResultMap; 14 import org.apache.ibatis.annotations.ResultType; 15 import org.apache.ibatis.annotations.Results; 16 import org.apache.ibatis.annotations.Select; 17 18 import com.lovo.beans.Page; 19 import com.lovo.beans.UserBean; 20 21 22 @CacheNamespace//為該Mapper映射文件開啟一個二級緩存空間 23 @CacheNamespaceRef(value = UserMapper.class) 24 public interface UserMapper { 25 26 /** 27 * 保存用戶 28 * 29 * @param user 30 * @return 31 */ 32 @Insert(value = "insert into t_user(id,user_name,sex) values (null,#{u.userName},#{u.sex})") 33 @Options(useGeneratedKeys = true, keyProperty = "u.id") 34 public int saveUserInfo(@Param("u") UserBean user); 35 36 /** 37 * 根據ID修改用戶 38 * 39 * @param user 40 * @param id 41 * @return 42 */ 43 44 public int updateUserInfo(@Param("u") UserBean user, @Param("id") Long id); 45 46 /** 47 * 根據ID刪除用戶 48 * 49 * @param id 50 * @return 51 */ 52 @Delete(value = "delete from t_user where id = #{id}") 53 public int deleteUserById(@Param("id") Long id); 54 55 /** 56 * 根據ID查詢用戶 57 * 58 * @param id 59 * @return 60 */ 61 @Select(value = "select * from t_user where id = #{id}") 62 @Options(useCache = true) 63 @ResultMap(value = "userMap") 64 public UserBean getUserInfoById(@Param("id") Long id); 65 66 /** 67 * 根據用戶名模糊查詢所有的用戶 68 * 69 * @param name 70 * @return 71 */ 72 @Select("select u.user_name as userName,u.sex as sex from t_user as u where u.user_name like CONCAT('%',#{name},'%')") 73 @ResultType(UserBean.class) 74 public List<UserBean> queryUserInfoByName(@Param("name") String name); 75 76 /** 77 * 批量的增加 78 * 79 * @param users 80 * @return 81 */ 82 public int batchSaveUser(@Param("users") List<UserBean> users); 83 84 /** 85 * 批量的刪除 86 * 87 * @param ids 88 * @return 89 */ 90 public int batchDeleteUser(@Param("ids") Long[] ids); 91 92 /** 93 * 根據部門名稱查詢所有的用戶 94 * 95 * @param deptName 96 * @return 97 */ 98 @Select("select u.user_name as userName,u.sex as sex from t_user as u left join t_dept as d on u.fk_dept_id = d.id where d.dept_name like CONCAT('%',#{name},'%')") 99 @Results({ 100 @Result(id = true, property = "id", column = "id", javaType = Long.class), 101 @Result(property = "userName", column = "userName", javaType = String.class), 102 @Result(property = "sex", column = "sex", javaType = String.class) 103 }) 104 public List<UserBean> findUserInfoByDeptName(@Param("name") String deptName); 105 106 /** 107 * 根據用戶中的部分信息查詢用戶 108 * 109 * @param user 110 * @return 111 */ 112 @Select("select u.user_name as userName,u.sex as sex from t_user as u left join t_dept as d on u.fk_dept_id = d.id where d.dept_name like CONCAT('%',#{u.dept.deptName},'%')") 113 @ResultType(UserBean.class) 114 public List<UserBean> findUserInfoByDept(@Param("u") UserBean user); 115 116 /** 117 * 根據條件統計查詢總條數 118 * 119 * @param userName 120 * @param deptName 121 * @return 122 */ 123 public int countUserInfoByParams(@Param("userName") String userName, 124 @Param("deptName") String deptName); 125 126 /** 127 * 查詢滿足條件的分頁數據 128 * 129 * @param userName 130 * @param deptName 131 * @param page 132 * @return 133 */ 134 public List<UserBean> queryUserInfoByParams( 135 @Param("userName") String userName, 136 @Param("deptName") String deptName, @Param("page") Page page); 137 138 /** 139 * 根據條件統計查詢總條數 140 * 141 * @param map 142 * @return 143 */ 144 public int countUserInfoByMapParams(Map<String, Object> map); 145 146 /** 147 * 查詢滿足條件的分頁數據 148 * 149 * @param map 150 * @return 151 */ 152 // Map作為多參數傳值時,不能與其他類型參數結合。 153 public List<UserBean> queryUserInfoByMapParams(Map<String, Object> map); 154 155 /** 156 * 根據用戶名與密碼查詢用戶 157 * 158 * @param name 159 * @param sex 160 * @return 161 */ 162 public List<UserBean> queryUserInfoByNameAndSex(@Param("name") String name, 163 @Param("sex") String sex); 164 165 }