mybatis ORM框架-对象映射关系
初始使用配置
- 创建数据源(不同数据连接池,数据源类有不同)
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" > <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="maxActive" value="100"/> <property name="maxIdle" value="30"/> <property name="maxWait" value="500"/> <property name="defaultAutoCommit" value="true"/> <property name="connectionProperties"> <value>charSet=utf-8</value> </property> </bean>
- 创建sqlSessionFactory(创建连接会话工厂)
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 自动扫描mapping.xml文件 <property name="mapperLocations" value="classpath:com/situ/mapper/**.xml"></property> --> </bean>
- 扫描生成实现类(dao接口通过clib代理生成实现类)
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="dao" /> //包名 <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> </bean>
- 数据库事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <tx:annotation-driven transaction-manager="transactionManager"/>
用法
- ${} 符号的作用是直接进行字符串拼接(小心sql注入)
select * from book ${where}
- #{}替换预编译语句(PrepareStatement)中的占位符?
select * from book where name=#{name}
注解模式
- @select
- @insert
- @update
- @delete
- @option(设置缓存时间,生成自增的主键值)
@Options(useGeneratedKeys = true, keyProperty = “id”) //新增时有效 public void insert(Type t); //将自动编号列返回到源对象的指定属性中 useGeneratedKeys 设置为"true"表明要 MyBatis 获取由数据库自动生成的主键; keyProperty="id"指定把获取到的主键值注入到 XXX(实体类) 的 id 属性。 @Options(useCache=true,flushCache=false,timeout=100000) useCache = true表示本次查询结果被缓存以提高下次查询速度, flushCache = false表示下次查询时不刷新缓存, timeout = 10000表示查询结果缓存10000秒。
- @result 列指定映射
@Results( id="userMap", value={ @Result(column="id", property="id", id=true), @Result(column="user_name", property="userName"), @Result(column="user_password ", property="userPassword"), @Result(column="user_email", property="userEmail"), @Result(column="user_info", property="userInfo"), @Result(column="head_img", property="headImg", jdbcType=JdbcType.BLOB), @Result(column="create_time", property="createTime",jdbcType=JdbcType.TIMESTAMP) })
- @resultMap(上述result的使用)
@resultMap("userMap")
<resultMap type="Comment" id="CommentResult"> <association property="blog" select="selectBlog" column="blog" javaType="Blog"/> </resultMap> <select id="selectComment" parameterType="int" resultMap="CommentResult"> select * from t_Comment where id = #{id} </select> <select id="selectBlog" parameterType="int" resultType="Blog"> select * from t_Blog where id = #{id} </select>
- @MapKey 指定map集合结果的key列
@MapKey("id") @Select("select * from user where hotel_address = #{address};") Map<Long, User> getUserByAddress(@Param("address") String address);
- @Param 方法参数指定sql字段
@Select("select * from user where hotel_address = #{address};") List<User> getUserByAddress(@Param("address") String address); `
xml模式(可与注解共用)
- 设置改变
<!-- sqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 自动扫描mapping.xml文件 --> <property name="mapperLocations" value="classpath:com/situ/mapper/**.xml"></property> </bean>
- 基本使用
<?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="dao.Type1_Dao"> <!-- xml与接口dao关联 --> <select id="select" resultType="model.Type" parameterType="java.lang.String"> select * from type ${_parameter} </select> <select id="selectById" resultType="model.Type" parameterType="int" > select * from type where id=#{id} </select> <insert id="insert" parameterType="model.Type"> insert into type(name) values(#{name}) </insert> </mapper>
- 动态sql语句
- < if >
<select id="select" resultType="model.Type" parameterType="java.lang.String"> select * from type <if test="_parameter!=null"> where id=9 </if> </select>
- choose,when,otherwise(switch分支处理)
- foreach 循环
<foreach collection="" item="" index=""></foreach>
- trim(去除两边空格,规格化sql),where(查询后置是否添加and或or),set(前置是否添加修改时的set)
- < if >
数据库事务
- 数据库事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <tx:annotation-driven transaction-manager="transactionManager"/>
- @Transactional 使用注解
- 事务处理类型
事物传播行为介绍: @Transactional(propagation=Propagation.REQUIRED) 如果有事务, 那么加入事务, 没有的话新建一个(默认情况下) @Transactional(propagation=Propagation.NOT_SUPPORTED) 容器不为这个方法开启事务 @Transactional(propagation=Propagation.REQUIRES_NEW) 不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务 @Transactional(propagation=Propagation.MANDATORY) 必须在一个已有的事务中执行,否则抛出异常 @Transactional(propagation=Propagation.NEVER) 必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反) @Transactional(propagation=Propagation.SUPPORTS) 如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务. 事物超时设置: @Transactional(timeout=30) //默认是30秒 事务隔离级别: @Transactional(isolation = Isolation.READ_UNCOMMITTED) 读取未提交数据(会出现脏读, 不可重复读) 基本不使用 @Transactional(isolation = Isolation.READ_COMMITTED) 读取已提交数据(会出现不可重复读和幻读) @Transactional(isolation = Isolation.REPEATABLE_READ) 可重复读(会出现幻读) @Transactional(isolation = Isolation.SERIALIZABLE) 串行化
- 使用
方法中多条sql执行,其中一条失败,全部事务回滚 @Transactional(propagation=Propagation.REQUIRED) public void insert(Type t) { dao.insert(new Type(12, "1212")); dao.insert(new Type(12, "133")); }
- 事务处理类型
spring缓存
- 设置
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="myselect" /> </set> </property> </bean> <cache:annotation-driven mode="proxy" />
- @Cacheable 如果有缓存就取缓存,否则查询数据库
@Select("select * from type ${txt} ${limit}") @Cacheable("myselect") public List<Type> select(@Param("txt") String txt,@Param("limit") String limit);
- @CacheEvict 清除指定缓存
@Insert("insert into type(id,name) values(#{id},#{name})") @CacheEvict(value="myselect",allEntries=true) public int insert(Type t);
- @CachePut 每次都查数据库,放入缓存(不检验之前的缓存状况)