JavaEE体系架构概述、MyBatis总结
2016-07-19 23:41
537 查看
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
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "/WEB-INF/dtd/mybatis-3-config.dtd"> <configuration> <!-- 开启缓存机制,要求所有的映射器都支持缓存 --> <settings> <setting name="cacheEnabled" value="true"></setting> </settings> <typeAliases> <!-- 一个一个给实体类型取类的别名 <typeAlias type="com.lovo.beans.UserBean" alias="UserBean"/>--> <package name="com.lovo.beans"/> </typeAliases> <environments default="first"> <!-- 一个数据源对应一个环境配置 --> <environment id="first"> <!-- 配置事务管理器,type="JDBC"表示使用JDBC事务处理机制来处理事务,MANAGED表示什么都不干,等待外部容器或者其他应用程序来处理事务 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置数据源,type="POOLED"表示使用JDBC连接池; UNPOOLED表示不使用JDBC连接池,也就是说每次请求就分别对应一个连接 ; JNDI表示需要依赖外部容器提供连接池--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="lovo"/> </dataSource> </environment> </environments> <mappers> <!-- <mapper resource="com/lovo/mapper/UserMapper.xml"/> --> <package name="com.lovo.mapper"/> </mappers> </configuration>
类配置文件
<?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.lovo.mapper.UserMapper"> <!-- 为该映射器配置缓存 --> <cache/> <!-- resultMap 与resultType 是指定的返回结果集与类中属性的关系,而不是返回类型 --> <resultMap type="UserBean" id="userMap"> <id property="id" column="id" javaType="java.lang.Long"/> <result property="userName" column="user_name" javaType="java.lang.String"/> </resultMap> <!-- id="saveUserInfo" 代表着实现的是哪个接口方法, parameterType="com.lovo.beans.UserBean" 代表着传入的参数,它的类型 useGeneratedKeys="true" 代表着获取数据库自增长的ID信息 keyProperty="u.id" 代表着将获取到的ID值赋值给哪个属性 --> <insert id="saveUserInfo" parameterType="UserBean" useGeneratedKeys="true" keyProperty="u.id"> insert into t_user(id,user_name,sex) values (null,#{u.userName},#{u.sex}) </insert> <insert id="batchSaveUser"> insert into t_user (user_name,sex) values <!-- 动态SQL之foreach的用法 --> <!-- collection="users" 用于指定循环集合的名称,如果接口中并未指定参数别名,那么默认就是list item="u" 用于指定每次循环后的对象的别名 separator="," 用于指定每次循环后之间的分割符--> <foreach collection="users" item="u" separator=","> (#{u.userName},#{u.sex}) </foreach> </insert> <update id="updateUserInfo"> <!-- update t_user set user_name = #{u.userName},sex = #{u.sex} where id = #{id} --> <!-- 动态SQL之set if的用法 --> update t_user <set> <if test="u.userName != null"> user_name = #{u.userName}, </if> <if test="u.sex != null"> sex = #{u.sex} </if> </set> <where> id = #{id} </where> </update> <delete id="deleteUserById"> delete from t_user where id = #{id} </delete> <delete id="batchDeleteUser"> delete from t_user where id in ( <foreach collection="ids" item="id" separator=","> #{id} </foreach> ) <!-- 第二种批量删除的写法 delete from t_user where id in <foreach collection="ids" item="id" separator="," open="(" close=")"> #{id} </foreach> --> </delete> <select id="getUserInfoById" resultMap="userMap" useCache="true"> select * from t_user where id = #{id} </select> <select id="queryUserInfoByName" resultType="UserBean"> <!-- CONCAT('%',#{name},'%')该数据库函数,主要用户拼接字符串 --> select u.user_name as userName,u.sex as sex from t_user as u where u.user_name like CONCAT('%',#{name},'%') </select> <select id="findUserInfoByDeptName" resultType="UserBean"> 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},'%') </select> <!-- mybatis取得复合对象内部值的方式是:对象.复合对象.复合对象的属性 --> <select id="findUserInfoByDept" resultType="UserBean"> 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},'%') </select> <!-- 分页统计 --> <select id="countUserInfoByParams" resultType="int"> select count(u.id) from t_user as u left join t_dept as d on u.fk_dept_id = d.id <where> <include refid="commonSQL"></include> </where> </select> <select id="queryUserInfoByParams" resultType="UserBean"> 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 <where> <include refid="commonSQL"></include> limit ${page.index},${page.rows} </where> </select> <!-- 公共的SQL语句可以提到一处,其他地方采用include获取 --> <sql id="commonSQL"> <if test="userName != null && userName != ''"> and u.user_name like CONCAT('%',#{userName},'%') </if> <if test="deptName != null && deptName != ''"> and d.dept_name like CONCAT('%',#{deptName},'%') </if> </sql> <!-- MAP作为参数传值时,直接通过#{key}去获取对应的值 --> <select id="countUserInfoByMapParams" parameterType="java.util.Map" resultType="int"> select count(u.id) from t_user as u left join t_dept as d on u.fk_dept_id = d.id <trim prefix="where" prefixOverrides="and|or"> <include refid="commonSQL"></include> </trim> </select> <select id="queryUserInfoByMapParams" resultType="UserBean"> 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 <trim prefix="where" prefixOverrides="and|or" suffix="order by" suffixOverrides="and|or"> <include refid="commonSQL"></include> </trim> <!--SQL语法: order by需要放置在limit之前 --> u.id desc limit ${index},${rows} </select> <select id="queryUserInfoByNameAndSex" resultType="UserBean"> select id as id,user_name as userName,sex as sex from t_user <where> <!-- choose when 等同于java中的switch case的组合, 只匹配一项,如果都不匹配,就执行otherwise中的内容,等同于default--> <choose> <when test="name != null"> user_name like CONCAT('%',#{name},'%') </when> <when test="sex != null"> and sex like CONCAT('%',#{sex},'%') </when> <otherwise>1=1</otherwise> </choose> </where> </select> </mapper>
注解配置
package com.lovo.mapper; import java.util.List; import java.util.Map; import org.apache.ibatis.annotations.CacheNamespace; import org.apache.ibatis.annotations.CacheNamespaceRef; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Options; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.ResultMap; import org.apache.ibatis.annotations.ResultType; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import com.lovo.beans.Page; import com.lovo.beans.UserBean; @CacheNamespace//为该Mapper映射文件开启一个二级缓存空间 @CacheNamespaceRef(value = UserMapper.class) public interface UserMapper { /** * 保存用户 * * @param user * @return */ @Insert(value = "insert into t_user(id,user_name,sex) values (null,#{u.userName},#{u.sex})") @Options(useGeneratedKeys = true, keyProperty = "u.id") public int saveUserInfo(@Param("u") UserBean user); /** * 根据ID修改用户 * * @param user * @param id * @return */ public int updateUserInfo(@Param("u") UserBean user, @Param("id") Long id); /** * 根据ID删除用户 * * @param id * @return */ @Delete(value = "delete from t_user where id = #{id}") public int deleteUserById(@Param("id") Long id); /** * 根据ID查询用户 * * @param id * @return */ @Select(value = "select * from t_user where id = #{id}") @Options(useCache = true) @ResultMap(value = "userMap") public UserBean getUserInfoById(@Param("id") Long id); /** * 根据用户名模糊查询所有的用户 * * @param name * @return */ @Select("select u.user_name as userName,u.sex as sex from t_user as u where u.user_name like CONCAT('%',#{name},'%')") @ResultType(UserBean.class) public List<UserBean> queryUserInfoByName(@Param("name") String name); /** * 批量的增加 * * @param users * @return */ public int batchSaveUser(@Param("users") List<UserBean> users); /** * 批量的删除 * * @param ids * @return */ public int batchDeleteUser(@Param("ids") Long[] ids); /** * 根据部门名称查询所有的用户 * * @param deptName * @return */ @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},'%')") @Results({ @Result(id = true, property = "id", column = "id", javaType = Long.class), @Result(property = "userName", column = "userName", javaType = String.class), @Result(property = "sex", column = "sex", javaType = String.class) }) public List<UserBean> findUserInfoByDeptName(@Param("name") String deptName); /** * 根据用户中的部分信息查询用户 * * @param user * @return */ @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},'%')") @ResultType(UserBean.class) public List<UserBean> findUserInfoByDept(@Param("u") UserBean user); /** * 根据条件统计查询总条数 * * @param userName * @param deptName * @return */ public int countUserInfoByParams(@Param("userName") String userName, @Param("deptName") String deptName); /** * 查询满足条件的分页数据 * * @param userName * @param deptName * @param page * @return */ public List<UserBean> queryUserInfoByParams( @Param("userName") String userName, @Param("deptName") String deptName, @Param("page") Page page); /** * 根据条件统计查询总条数 * * @param map * @return */ public int countUserInfoByMapParams(Map<String, Object> map); /** * 查询满足条件的分页数据 * * @param map * @return */ // Map作为多参数传值时,不能与其他类型参数结合。 public List<UserBean> queryUserInfoByMapParams(Map<String, Object> map); /** * 根据用户名与密码查询用户 * * @param name * @param sex * @return */ public List<UserBean> queryUserInfoByNameAndSex(@Param("name") String name, @Param("sex") String sex); }
相关文章推荐
- 架构师与网红
- 网站运营先考虑用户忠诚度,再去想产品知名度
- 网站运营先考虑用户忠诚度,再去想产品知名度
- 架构中的设计原则
- 大型网站架构演变和知识体系(转载)
- .NET基础架构方法—DataTableToList通用方法
- 最详细的整个Spark运行时的内核架构以及架构思考
- 一个不错的html素材网站
- 各资源下载网站
- 大型网站架构演化发展历程
- 大型网站架构演化发展历程
- 解密 Uber 数据团队的基础数据架构优化之路
- android MVP 架构思路
- 常用参考网站
- 网站开发进阶(四十二)巧用clear:both
- 网站开发进阶(四十二)巧用clear:both
- Codis的架构设计
- 比较好的开发博客和网站(更新中。。。)
- 收藏qt学习的网站
- 微服务架构的分布式事务问题