JDBC不要用的地方?
- 处理结果集麻烦
- sql语句全部写在类里面,动态sql语句处理也麻烦
- 连接池(数据源)放在tomcat里面
- 不管怎么处理dao层里面总是存在大量的重复代码
- …
mybatis开发步骤:
- 导包
- 编写mybatis主配置文件(放在src目录下)
- 编写单利的工具类用于获取数据库连接
public class MybatisUtil {
private static MybatisUtil mu=new MybatisUtil();
private SqlSessionFactory sf;
private MybatisUtil() {
InputStream is=MybatisUtil.class.getClassLoader().getResourceAsStream("mybatis.xml");
sf=new SqlSessionFactoryBuilder().build(is);
}
public static MybatisUtil init() {
return mu;
}
public SqlSession getSession() {
return sf.openSession();
}
}
- 编写mapper映射文件(放在和dao层接口一致的位置)
- 在dao层中操作数据库
具体调用在service的实现类中
public class BookServiceImpl implements BookService {
@Override
public Book queryBookById(Integer id) {
SqlSession ss = MybatisUtil.init().getSession();
BookDao bd = ss.getMapper(BookDao.class);
Book book = bd.queryBookById(id);
ss.close();
return book;
}
mybatis优化的部分:
- 设置允许mybatis插入null:
- 提供动态sql语句
- 提供log4j.properties配置文件(放在src下面)
- 提供jdbc.propertis配置文件(放在src下面)
- 给实体类全路径取别名
一级二级缓存:redis
一级缓存:mybatis默认会给每个sqlsession默认提供一个一级缓存空间,当我们第一次使用该sqlsession执行查询的时候,mybatis会把查询结果放置在一级缓存中,第二次使用该sqlsession执行相同的sql语句的时候现从一级缓存中取,如果期间该sqlsession提交那么一级缓存中的数据清空
二级缓存:mybatis会给每个命名空间提供二级缓存空间,多个sqlsession操作相同命名空间里面的相同sql语句二级缓存空间是共享的
二级缓存步骤:
- 在主配置文件中允许二级缓存
<setting name = "cacheEnabled" value = "true"></setting>
- 在需要二级缓存的命名空间中允许二级缓存
<cache></cache>
- 第一个sqlsession执行完查询以后必须提交(只查询的话调用close方法也可以)才会把数据放到二级缓存中
- 对实体类进行序列化
mybatis.xml——配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 引入外部资源文件 -->
<properties resource="jdbc.properties"></properties>
<!-- 对mybatis框架的整体配置 -->
<settings>
<!-- 允许mybatis插入null -->
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<!-- 取别名:主要针对于杂牌映射文件中实体类全路径太长的问题 -->
<typeAliases>
<typeAlias type="com.zl.pojo.FenYe" alias="fy"/>
<typeAlias type="com.zl.pojo.Car" alias="car"/>
<typeAlias type="com.zl.pojo.Query" alias="query"/>
<typeAlias type="com.zl.pojo.User" alias="user"/>
<typeAlias type="com.zl.pojo.Brand" alias="brand"/>
<typeAlias type="com.zl.pojo.Power" alias="power"/>
<typeAlias type="com.zl.pojo.Role" alias="role"/>
</typeAliases>
<!-- 配置连接池 -->
<environments default="development">
<environment id="development">
<!-- 使用JDBC的事务管理方式 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 使用mybatis自己的连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 引入mapper映射文件 -->
<mapper resource="com/zl/dao/carDaoMapper.xml"/>
<mapper resource="com/zl/dao/userDaoMapper.xml"/>
<mapper resource="com/zl/dao/brandDaoMapper.xml"/>
<mapper resource="com/zl/dao/powerDaoMapper.xml"/>
<mapper resource="com/zl/dao/roleDaoMapper.xml"/>
</mappers>
</configuration>
userDaoMapper.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">
<!--
namespace:必须是对应接口的全路径
-->
<mapper namespace="com.zl.dao.CarDao">
<!--
自定义结果集和实体类的映射关系
1. 表字段和实体类属性不一致()
2. 级联查询
type:该resultMap是什么类型(对应的实体类类型)
id:唯一标识
-->
<resultMap type="car" id="carAndBrand">
<!-- 专门用来指定主键的映射关系 -->
<id column="id" property="id"/>
<!-- 用来指定普通字段的映射关系 -->
<result column="carId" property="carId"/>
<result column="color" property="color"/>
<result column="seat" property="seat"/>
<result column="youHao" property="youHao"/>
<result column="birDate" property="birDate"/>
<result column="riZhu" property="riZhu"/>
<result column="addDate" property="addDate"/>
<result column="img" property="img"/>
<!-- 级联查询
association:用来级联查询对象中的对象类型属性
property:查询出来的结果赋值个那个属性
column:根据结果集中发那个字段查询(外键)
javaType:查询出来的结果是什么的类型
select:引用那条sql语句
-->
<association property="brand" column="brandId" javaType="brand" select="com.zl.dao.BrandDao.queryBrandById"></association>
<association property="user" column="userId" javaType="user" select="com.zl.dao.UserDao.queryUserById"></association>
</resultMap>
<!--
查询:
id:必须是对应方法的名称
parameterType:该方法执行中用到的参数类型
resultType:结果集类型,告诉mybatis你自动的把结果集里面的数据封装到那个实体类中
-->
<select id="queryCarById" parameterType="int" resultType="car">
select * from car where id=#{id}
</select>
<delete id="deleteCar" parameterType="int">
delete from car where id=#{id}
</delete>
<insert id="addCar" parameterType="car">
insert into car (carId,brandId,color,seat,youHao,birDate,riZhu,addDate,userId,img)
values(#{carId},#{brandId},#{color},#{seat},#{youHao},#{birDate},#{riZhu},#{addDate},#{userId},#{img})
</insert>
<update id="updateCar" parameterType="car">
update car set
carId=#{carId},
brandId=#{brandId},
color=#{color},
seat=#{seat},
youHao=#{youHao},
birDate=#{birDate},
riZhu=#{riZhu},
addDate=#{addDate},
userId=#{userId},
img=#{img}
where id=#{id}
</update>
<select id="queryCarByFy" parameterType="fy" resultMap="carAndBrand">
select * from (select c.*,rownum r from(select * from car
<!-- 帮我们拼一个where,去掉多余的and -->
<where>
<if test="query!=null">
<if test="query.qColor!=null and query.qColor!=''">
and color like concat('%',concat(#{query.qColor},'%'))
</if>
<if test="query.brandId!=null and query.brandId!=0">
and brandid=#{query.brandId}
</if>
<if test="query.qStartBirDate!=null">
and birDate>#{query.qStartBirDate}
</if>
<if test="query.qEndBirDate!=null">
and birDate<![CDATA[<]]>#{query.qEndBirDate}
</if>
</if>
</where>
) c) where r>#{startRow} and r<![CDATA[<=]]>#{endRow}
</select>
<select id="queryRowCount" parameterType="query" resultType="int">
select count(*) from car
<where>
<if test="qColor!=null and qColor!=''">
and color like concat('%',concat(#{qColor},'%'))
</if>
<if test="brandId!=null and brandId!=0">
and brandid=#{brandId}
</if>
<if test="qStartBirDate!=null">
and birDate>#{qStartBirDate}
</if>
<if test="qEndBirDate!=null">
and birDate<![CDATA[<]]>#{qEndBirDate}
</if>
</where>
</select>
</mapper>
级联查询——集合属性
<resultMap type="role" id="roleAndPower">
<id column="id" property="id"/>
<result column="r_id" property="rId"/>
<result column="name" property="name"/>
<collection property="powers" column="id" ofType="power" select="com.zl.dao.PowerDao.queryPowerByRoleId"></collection>
<!--
select p.* from role_power rp,power p where rp.p_id=p.id and rp.r_id=1
-->
</resultMap>