导图社区 JavaEE技能树
Java EE 是 J2EE的一个新的名称,之所以改名,目的还是让大家清楚J2EE只是Java企业应用。在2004年底中国软件技术大会Ioc微容器(也就是Jdon框架的实现原理)演讲中指出:我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。本思维导图维spring,springmvc和mybatis框架思维导图笔记,快速浏览和记忆,快速入门!
编辑于2019-06-14 02:40:31HTML5,CSS3,JavaScript以及JQuery基础,作为前端入门基础,主要列举了其基础内容。
Java EE 是 J2EE的一个新的名称,之所以改名,目的还是让大家清楚J2EE只是Java企业应用。在2004年底中国软件技术大会Ioc微容器(也就是Jdon框架的实现原理)演讲中指出:我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。本思维导图维spring,springmvc和mybatis框架思维导图笔记,快速浏览和记忆,快速入门!
Git代码管理工具,版本管理,十分钟入门。
社区模板帮助中心,点此进入>>
HTML5,CSS3,JavaScript以及JQuery基础,作为前端入门基础,主要列举了其基础内容。
Java EE 是 J2EE的一个新的名称,之所以改名,目的还是让大家清楚J2EE只是Java企业应用。在2004年底中国软件技术大会Ioc微容器(也就是Jdon框架的实现原理)演讲中指出:我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。本思维导图维spring,springmvc和mybatis框架思维导图笔记,快速浏览和记忆,快速入门!
Git代码管理工具,版本管理,十分钟入门。
JavaEE技能树
视图层
SpringMVC
JavaEE应用架构
SpringMVC的运行流程
SpringMVC运行流程
SpringMVC的web.xml
<!-- 配置监听,监听配置文件--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 将springmvc 的配置文件引入 ,这里有多中配置方式--> <context-param> <param-name>contextConfigLocation</param-name> <!--方式1--> <param-value>/WEB-INF/app-context.xml</param-value> <!--方式2-> <!-- <param-value>classpath:*-context.xml</param-value> --> </context-param> <!-- 将前端控制器加载进来--> <servlet> <servlet-name>app</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:spring-mvc.xml </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- 配置过滤的请求--> <servlet-mapping> <servlet-name>app</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
spring-context.xml
启动自动扫描包
<context:compontent-scan base-package="" />
配置视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <!-- 前缀 --> <property name="prefix" value="/WEB-INF/jsp/" /> <!-- 后缀 --> <property name="suffix" value=".jsp" /> </bean>
配置注解处理器
<mvc:annotation-driven />
SpringMVC的常用注解
控制器注解
@Controller
@RestController
Restful
JSON
@RequstMapping
注解在类上
注解在方法上
具体方法参数 Spring会正确的将对象传递给方法
HttpServletRequesst
HttpSession
数据绑定
@RequestParam
public ModelAndView login( @RequestParam("name") String username, @RequestParam("passwd") String password ){ ..... }
@RequestBody
将JSON数据绑定到对象中
@RequestBody Book book;
@PathVariable
@RequestMapping(value="/login/{name}/{passwd}") public ModelAndView login( @PathVariable String name, @PathVariable String passwd ){ ... }
url模板中的参数,会绑定到@PathVariable注解的同名参数上
session绑定
@SessionAttributes
@SessionAttribute注解指定哪些属性绑定到HttpSession中
@SessionAttribute只能注解到类上
将Model/ModelMap/ModelAndView中的属性绑定到HttpSession中
@SessionAttribute("user")
cookie绑定
@CookieValue
@CookieValue注解的参数,会将Cookie中的值绑定到该参数上
@CookieValue(value="JSESSIONID", defaultValue="") String sessionId
数据绑定
简单类型绑定
绑定简单数据类型
HttpServletRequest
HttpServletResponse
HttpSession
Model/ModelMap
绑定POJO
直接传入
复杂类型绑定
绑定数组
直接传入
绑定集合
建立用户包装类
SpringMVC模型绑定
ModelAndView
定义数据
指定视图
两种实现方式
第一种方式
ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("user",user); modelAndView.setViewName("xxx.jsp")
第二种方式
结合@ModelAttribute注解
首先定义ModelAndView中的Model
然后在具体方法中指定视图
Model/ModelMap
定义数据
返回视图
两种实现方式
第一种方式
Model/ModelMap需要作为方法参数
model.addAttribute("user",user); return "xxx.jsp"
第二种方式
结合@ModelAttribute注解实现
@ModelAttribute
@ModelAttribute注解将请求的参数绑定到Model/ModelMap/ModelAndView中
ModelAndView/Model/ModelMap的第二种方式实现
SpringMVC静态资源处理
由于url-pattern使用/进行过滤,导致过滤所有的文件都是请求,无法访问静态资源
具体静态资源处理方案三种方式
web.xml中进行具体过滤
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.jpg</url-pattern> </servlet-mapping>
spring-context.xml中配置静态资源
<!--配置静态资源访问 **表示的包含自身包和子包的所有文件--> <mvc:resources mapping="/statics/**" location="/statics/" ></mvc:resources>
在spring-context.xml中配置
<mvc:default-servlet-handler/>
Spring EL标签库
<%@ taglib prefix="s" uri="http://www.springframework.org/tags/form"%>
SpringMVC的JSON与Restful
信息转换
将请求信息,转换为一个对象,并将对象绑定到参数或者Model中
JSON处理包
jackson-annoations-xxx.jar
jackson-core-xxx.jar
jackson-databind-xxx.jar
JSON数据交互注解
@RequestBody
如果参数是JSON,需要注解参数,将JSON转换为对象
@ResponseBody
如果方法返回JSON,需要在方法上注解
Restful
使用@PathVariable实现Restful的URL参数传入
使用@ResponseBody实现返回参数为JSON
或者使用RestController,整个类的方法都返回JSON
拦截器
拦截器的定义
通过实现HandlerInterceptor接口, 或者继承其实现类(HandlerInterceptorAdapter)
其实现方法有三个
preHandler:控制器方法前执行
postHandler:控制器方法后,视图渲染前执行
afterHandler:视图渲染后执行
拦截器配置
指定拦截器的Bean
指定拦截路径
多拦截器顺序执行
<mvc:interceptors> <!--定义第一个拦截器--> <mvc:interceptor> <bean class="com.bybo.aca.web.interceptor.Login"/> <!-- 进行拦截:/**表示拦截所有controller --> <mvc:mapping path="/**" /> <!-- 不进行拦截 --> <mvc:exclude-mapping path="/index.html"/> </mvc:interceptor> </mvc:interceptors>
通过实现WebRequestInterceptor接口, 或者继承其实现类来实现。
文件上传和下载
文件上传
文件上传包
commons-fileupload-xxx.jar
commons-io-xx.jar
文件上传表单
<form action="" method="POST" enctype="multipart/form-data"> <input type="file" name="filename" multiple="multiple"/> <input type="submit" value="文件上传"/> </form>
文件上传控制器
@RequestMapping("/fileUpload") public String handlerFormUpload( @RequestParam("filename") MultipartFile file ){ if(file.isEmpty()){ //code... return "xxx"; } return "xxx"; }
文件下载
文件下载控制器
@RequestMapping("/download") public ResponseEntity<byte[]> fileDownload( HttpServletRequest request, String filename) throws Exception{ //指定要下载文件路径 String path = request.getServletContext().getRealPath("/upload/"); //a创建文件对象 File file = new File(path+File.separator+filename); //设置ag响应头 HttpHeaders headers = new HttpHeaders(); //通知浏览器以下载的方式打开文件 headers.setContentDispositionFormData("attachment",filename); //定义以流的形式返回文件数据 headers.setContextType(MediaType.APPLICATION_OCTET_STREAM); //使用springmvc框架的ResponseEntity对象封装返回下载数据 return new ResponseEntity<byte[]> (FileUtils.readFileToByteArray(file),headers,HTTPStatus.OK); }
文件下载连接
<a href="${pageContext.request.contextPath}/download?filename=xxx.jpg">文件下载</a>
SpringMVC国际化
实现步骤
给系统加载国际化资源文件
输出国际化
在视图页面上输出国际化消息,使用springMVC标签库
在Controller处理方法中输出国际化消息 使用org.springframework.web.servlet.support.RequestContext.getMessage()实现
具体实现
控制层
Spring
控制反转IOC
控制反转与依赖注入
Spring通过容器管理Bean 容器通过加载配置文件获取Bean
容器
BeanFactory接口
ApplicationFactory接口
实例化容器方式
通过ClassPathXmlApplicationContext(resource)创建
通过FileSystemXmlApplicationContext创建
通过监听器自动创建 web.xml org.springframework.web.context.ContextLoaderListener
配置文件 applicationContext.xml
Bean的定义
id——单一Bean管理
name——多Bean批量管理
class——全类名,具体实现类
scope——指定Bean的作用域
Sigleton单例模式
常用
prototype原型模式
request,一次Http请求中
session,一次会话中
globalSession,protlet上下文中有效
application,为每个ServletContext创建一个实例,在web中有效
websocket,为每一个websocket创建一个实例
Bean的注入方法
XML方式注入
构造器注入
constructor-arg
index
type
ref/value
具体类型注入
普通类型注入
value
集合类型注入
list-value/ref
set-value/ref
map-entry(key-value/value-ref)
props-prop
<props> <prop key="one">INDIA</prop> </props>
Bean注入
ref
setter方法注入
property
name
ref/value
具体类型注入
普通类型注入
value
集合类型注入
list-value/ref
set-value/ref
map-entry(key-value/value-ref)
props-prop
<props> <prop key="one">INDIA</prop> </props>
Bean注入
ref
自动装配
具体类型注入
普通类型注入
value
集合类型注入
list-value/ref
set-value/ref
map-entry(key-value/value-ref)
props-prop
<props> <prop key="one">INDIA</prop> </props>
Bean注入
ref
注解方式注入
创建Bean
@Component(id)
全功能
@Repository(id)
Dao层
@Service(id)
Service层
@Controller(id)
Controller层
标注更清晰 开发时常用
注入Bean
@Autowired
默认按照Bean类型注入
@Qualifier
配合Autowired,实现按照名称注入
@Resource(name="id")
默认按照Bean的名称注入
可以指定按照名称/类型注入
ref="id"
开启注解处理器
<context:annotation-config />
通过扫描自动生成Bean
<context:component-scan base-package="" />
需要spring-aop.jar包
如何实例化Bean?
构造器实例化
Bean(id,name,class,scope)
application.getBean(id|name);
静态工厂实例化
Bean(id,name,class,scope,factory-method)——指定静态方法名
实例工厂实例化
Bean(id,name,class,scope,fatory-bean,fatory-method)——指定工厂Bean,和工厂方法
Bean的生命周期
singleton的Bean,spring容器负责整个生命周期
prototype的Bean,spring容器只负责创建
面向切面编程AOP
什么是AOP?
AOP——面向切面编程
主要实现过滤功能,例如,日志,事务等
springAOP只实现对方法的过滤
代理模式
动态代理设计模式
普通代理
强制代理
强制代理使用自己New的代理类不能访问
强制代理使用new的真实角色类,也不能访问
强制代理只能使用new真实角色,调用它的getProxy()方法获得代理类才能使用
动态代理
动态代理的特点
动态代理是在实现的时候不关心代理谁,而在运行阶段才指定代理哪一个对象。
动态代理不确定代理哪一个对象,所以使用invoke方法完成对真实方法的调用
动态代理类
其中invoke方法是接口InvocationHandler定义必须实现的, 主要完成对真实方法的调用
基于JDK的代理模式
基于CGLib的代理模式
Spring中的AOP
需要的额外包
aspectjrt.jar
aspectjweaver.jar
aspectj.jar
aopalliance.jar
AOP术语
切面Aspect
要过滤的类
连接点Joinpoint
动态指定过滤的方法
切入点
要过滤的方法
通知Advice
前置通知 ——在一个方法执行之前,执行通知。
后置通知 ——在一个方法执行之后,不考虑其结果,执行通知。
返回通知 ——在一个方法执行之后,只有在方法成功完成时,才能执行通知。
异常通知 ——在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。
环绕通知 ——在建议方法调用之前和之后,执行通知。
子主题
基于XML的实现
具体实现步骤
要过滤哪个类?——配置切面
要过滤类中的哪些方法?——配置切入点
要对方法进行什么类型的过滤?——配置通知
通知是顺序执行的。
代码实现
<aop:config> <aop:aspect id="log" ref="logging"> <aop:pointcut id="selectAll" expression="execution(* com.tutorialspoint.Student.getName(..))"/> <aop:before pointcut-ref="selectAll" method="beforeAdvice"/> <aop:after pointcut-ref="selectAll" method="afterAdvice"/> </aop:aspect> </aop:config>
基于@AspectJ的实现
具体步骤
@Aspect——指定切面
@Pointcut——指定切入点
@Before/@After/@AfterReturning/@AfterThrowing/@Around——指定通知
开启@AspectJ注解
<aop:aspectj-autoproxy/>
具体代码
@Aspect public class Logging { //定义一个空方法,作为切入点 @Pointcut("execution(* com.tutorialspoint.*.*(..))") private void selectAll(){} @Before("selectAll()") public void beforeAdvice(){ System.out.println("Going to setup student profile."); } @After("selectAll()") public void afterAdvice(){ System.out.println("Student profile has been setup."); } @AfterReturning(pointcut = "selectAll()", returning="retVal") public void afterReturningAdvice(Object retVal){ System.out.println("Returning:" + retVal.toString() ); } @AfterThrowing(pointcut = "selectAll()", throwing = "ex") public void AfterThrowingAdvice(IllegalArgumentException ex){ System.out.println("There has been an exception: " + ex.toString()); } }
Spring的事务管理
Spring数据库操作
使用jdbcTemplate实现数据库操作
定义数据源Bean
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverCLassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/spring"/> <property name="username" value="root" /> <property name="password" value="123456"/> </bean>
定义jdbcTemplate的Bean,并注入数据源Bean
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref ="dataSource" /> </bean>
自定义xxxDao的Bean,并注入jdbcTemplate
<bean id="userDao" class="xxx.UserDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate" /> </bean>
常用数据库操作方法
execute(String sql)
执行SQL,例如创建数据表等
update(String sql)
插入,更新,删除
query(String sql)
数据表的查询
spring事务管理方式
事务的传播行为
传播行为指定了是否创建事务,以及如何创建事务
* 保证同一个事务中 PROPAGATION_REQUIRED 支持当前事务,如果不存在 就新建一个(默认) PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务 PROPAGATION_MANDATORY 支持当前事务,如果不存在,抛出异常 * 保证没有在同一个事务中 PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务 PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务 PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常 PROPAGATION_NESTED 如果当前事务存在,则嵌套事务执行
事务的隔离级别
Spring中的事务
Spring是基于AOP实现事务控制的
基于AOP的事务控制,需要编写事务通知
基于AOP的事务控制,可以通过声明式控制
声明式事务管理
基于XML方式
定义数据源
<bean id="dataSource" class="xx">.... </bean>
定义事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean>
定义事务通知,指定需要事务控制的方法
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="create" propagation="required" isslation="default" read-only="false"/> </tx:attributes> </tx:advice>
配置事务的AOP
<aop:config> <aop:pointcut id="createOperation" expression="execution(* com.tutorialspoint.StudentJDBCTemplate.create(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="createOperation"/> </aop:config>
基于注解的方式
xml中定义事务管理器
开启事务注解驱动
<tx:annotation-driven transaction-manager="transactionManager" />
注解使用事务的方法
@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT,readOnly=false)
模型层
MyBatis
MyBaits运行原理
MyBatis与Hibernate区别
MyBatis:POJO-->SQL--->表
Hibernate:POJO-->表
MyBatis的核心对象
SqlSessionFactory
InputStream inputStream = Resource.getResourceAsStream("配置文件"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession(); try{ }finally{ sqlSession.close(); }
SqlSession工具类
public class MyBaitsUtil{ private static SqlSessionFactory sqlSessionFactory = null; static{ try{ Reader reader = Resource.getResourceAsStream("mybatis-config.xml"); sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); }catch(Exception e){ e.printStackTrace(); } } public static SqlSession getSession(){ return sqlSessionFactory.openSession(); } }
MyBatis的文件
配置文件
配置文件层次结构
配置环境
<environments default="development"> <environment id="development"> <transactionManager type="JDBC"> <property name="..." value="..."/> </transactionManager> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments>
数据源
事务管理器
配置参数
<settings> <setting name="cacheEnabled" value="true"/> <setting name="lazyLoadingEnabled" value="true"/> <setting name="multipleResultSetsEnabled" value="true"/> <setting name="useColumnLabel" value="true"/> <setting name="useGeneratedKeys" value="false"/> <setting name="autoMappingBehavior" value="PARTIAL"/> <setting name="defaultExecutorType" value="SIMPLE"/> <setting name="defaultStatementTimeout" value="25"/> <setting name="safeRowBoundsEnabled" value="false"/> <setting name="mapUnderscoreToCamelCase" value="false"/> <setting name="localCacheScope" value="SESSION"/> <setting name="jdbcTypeForNull" value="OTHER"/> <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/> </settings>
配置属性文件
<properties resource="db.properties" />
配置别名
<typeAliases> <typeAlias alias="Author" type="domain.blog.Author"/> </typeAliases>
配置映射文件
资源路径
文件路径
类名
包
<mappers> <mapper resource="org/mybatis/builder/AuthorMapper.xml"/> <mapper url="file:///var/mappers/AuthorMapper.xml"/> <mapper class="org.mybatis.builder.AuthorMapper"/> <package name="org.mybatis.builder"/> </mappers>
配置类型处理器
<typeHandlers> <typeHandler handler="org.mybatis.example.ExampleTypeHandler"/> </typeHandlers>
映射文件
需要指定SQL的ID
需要指定参数类型parameterType
需要指定返回值类型resultType或者结果集映射resultMap
resultMap映射
<resultMap id="userResultMap" type="User"> <id property="id" column="user_id" /> <result property="username" column="username"/> <result property="password" column="password"/> </resultMap>
Dao 层
mybatis 他的dao层是不需要实现的,主要它使用的是代理模式
只需要定义命名空间指定类,并保证语句id与类中方法名一致就可实现代理
基本语句
insert插入语句
普通插入
数据库自增插入
数据库非自增插入
update更新语句
delete删除语句
select查询语句
<!-- 数据库自增插入 --> <insert id="insertUser" useGeneratedKeys="true" keyProperty="id"> insert into t_user (username,password,account) values (#{username},#{password},#{account}) </insert> <!-- 对于数据库不支持自增,mybatis可以自生成id --> <insert id="insertAuthor"> <selectKey keyProperty="id" resultType="int" order="BEFORE"> select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1 </selectKey> insert into Author (id, username, password) values (#{id}, #{username}, #{password}) </insert> <update id="updateUser" > update t_user set username=#{username} where id=#{id} </update> <delete id="deleteUser" parameterType="int"> delete from t_user where id=#{id} </delete> <select id="selectUserById" parameterType="int" resultMap="userMap"> select * from t_user where id=#{id} </select>
注解方式
public interface UserMapper { @Insert("insert into users(name,age) values(#{name},#{age})") public void insertT(User user); @Delete("delete from users where id=#{id}") public void deleteById(int id); @Update("update users set name=#{name},age=#{age} where id=#{id}") public void updateT(User user); @Select("select * from users where id=#{id}") public User getUser(int id); @Select("select * from users") public List<User> getAllUsers(); }
不方便使用动态SQL
MyBatis的关联映射
一对一映射
使用resultMap中的association元素
嵌套查询
<resultMap type="com.mybatis.domain.Employee" id="myEmp"> <id column="id" property="id"/> <result column="last_name" property="lastName"/> <!-- 关联对象 --> <association property="dept" javaType="com.mybatis.domain.Department" select="com.mybatis.mapper.DepartmentMapper.findDeptById" column="dept_id"> </association> </resultMap>
嵌套结果
<resultMap type="com.mybatis.domain.Employee" id="myEmp"> <id column="id" property="id"/> <result column="last_name" property="lastName"/> <!-- 关联对象 --> <association property="dept" javaType="com.mybatis.domain.Department"> <!-- 关联条件Employee的dept_id对应着Department的id --> <id column="dept_id" property="id"/> <result column="department_name" property="departmentName"/> </association> </resultMap>
一对多映射
使用resultMap中的collection元素
嵌套查询
<resultMap type="Teacher" id="teacherMap"> <id column="id" property="id"/> <result column="name" property="name"/> <collection property="students" ofType="Student" select="com.mybatis.mapper.OrderMapper.findStudentsByT_id" column="id"> </collection> </resultMap>
嵌套结果
<resultMap type="Teacher" id="teacherMap"> <id column="id" property="id"/> <result column="name" property="name"/> <collection property="students" ofType="Student"> <id column="sid" property="id"/> <!-- 这里的column对应的是下面查询的别名,而不是表字段名 --> <result column="sname" property="name"/> <!-- property对应JavaBean中的属性名 --> <result column="className" property="className"/> </collection> </resultMap>
多对多映射
实现方式同一对多
使用中间表实现多对多
动态SQL
动态SQL的作用
拼装SQL语句
基于OGNL表达式
条件元素
<if>
<select id="findActiveBlogWithTitleLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <if test="title != null"> AND title like #{title} </if> </select>
<choose> <when> <otherwise>
<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <choose> <when test="title != null"> AND title like #{title} </when> <when test="author != null and author.name != null"> AND author_name like #{author.name} </when> <otherwise> AND featured = 1 </otherwise> </choose> </select>
循环元素
<foreach>
<select id="selectPostIn" resultType="domain.blog.Post"> SELECT * FROM POST P WHERE ID in <foreach item="item" index="index" collection="list" open="(" separator="," close=")"> #{item} </foreach> </select>
多条件元素<set>实现只更新部分元素
<update id="updateAuthorIfNecessary"> update Author <set> <if test="username != null">username=#{username},</if> <if test="password != null">password=#{password},</if> <if test="email != null">email=#{email},</if> <if test="bio != null">bio=#{bio}</if> </set> where id=#{id} </update>
连接元素<set>
<select id="selectBlogsLike" resultType="Blog"> <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" /> SELECT * FROM BLOG WHERE title LIKE #{pattern} </select>
MyBatis的日志
#Global logging configuration log4j.rootLogger=debug,stdout #MyBatis logging configuration log4j.logger.com.itheima=DEBUG #console log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
MyBatis的缓存
MyBatis默认开启一级缓存
一级缓存在同一个SqlSession中有效
二级缓存需要手动开启,可以指定使用缓存
Memcache
Redis
二级缓存在整个Mapper中有效,以namespace为单位创建的
二级缓存是系统级缓存
MyBatis开发
传统Dao方式
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao{ public void queryUserById(){ this.getSqlSession().selectOne("queryUserById", 1) }
基于Mapper方式
Mapper接口名称和mapper.xml名称一致
Mapper.xml的namespace和Mapper接口路径相同
Mapper接口中方法名和xml中id一致
Mapper接口中方法返回值类型和xml中的resultType一致
Mapper接口中方法参数类型和xml中parameterType一致
SqlSession session=MyBatisUtil.getSession(); UserMapper mapper=session.getMapper(UserMapper.class); try { mapper.deleteUser(1); session.commit(); } catch (Exception e) { e.printStackTrace(); session.rollback(); }