二、MyBaits XML实现

1.mybaits相关概念

  1. orm:object relation mapping
  2. 半自动:手写sql方便优化
  3. 实现方式:xml或注解

2.环境搭建

提供mybaits坐标(引入依赖)

创建表

创建实体

创建mapper.xml: 

  1. parameterType=自定义类,#{getMethodWithoutGet};parameterType=包装类或String,#{anyName}
  2. 动态sql

1.if标签,用多条件组合查询演示

  1.1  where 1=1 + if标签:id为整型if(test="id!=null") 字符型 if(test="id!=''")

  1.2 <where></where>+if标签(where标签会自动去除第一个and)

2.for_each标签,用多值查询演示

<select id="findByIds" parameterType="list" resultType="user">
select * from User
<where>
<foreach collection="list" open="id in(" close=")" item="id"
separator=",">
<!--如果要取id中的属性:#{id.propertyName}-->
#{id}
</foreach>
</where>
</select>

3.sql片段抽取

<sql id="selectUser" select * from User</sql>

<select id="findById" parameterType="int" resultType="user">
  <include refid="selectUser"></include> 
  where id=#{id}
</select>

创建sqlMapConfig.xml:

  1.          <environments>:(开发环境、测试环境、生产环境),环境包含事务管理器和数据源;
  2.          <mappers>:引入mapper.xml
  3.          <properties>:加载外部properties文件

    4.         <typeAliases>:给自定义类全限定名起别名,这样在mapper.xml就可以少写一点(jdk自带的数据类型已经起好了别名)

                       1.单独起别名:typeAliase;2.批量起别名,根据类名产生大小写不敏感的别名:package

 

     编写测试

//加载核心配置文件
InputStream resourceAsStream =
Resources.getResourceAsStream("SqlMapConfig.xml");
//获得sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(resourceAsStream);
//获得sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql语句
List<User> userList = sqlSession.selectList("userMapper.findAll");
//打印结果
System.out.println(userList);
//释放资源
sqlSession.close();

3.CRUD

3.1 xml实现

<mapper namespace="userMapper">
<insert id="add" parameterType="com.dck.domain.User">
insert into user values(#{id},#{username},#{password})
</insert>
</mapper>
InputStream resourceAsStream =
Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();//openSession(true)可以开启自动提交的事务
int insert = sqlSession.insert("userMapper.add", user);
System.out.println(insert);
//提交事务
sqlSession.commit();
sqlSession.close();

 

4.DAO层开发

4.1 传统型

将3.1中的测试方法移到DaoImpl;

4.2 代理型(目前主流)

只需要定义Dao接口,无需提供实现

private userMapper;
@Before
public void before() {
InputStream resourceAsStream =
Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//获得MyBatis框架生成的UserMapper接口的实现类
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void testProxyDao() throws IOException {
User user = userMapper.findById(1);
System.out.println(user);
sqlSession.close();
}

4.2.1 mapper.xml实现

因为要根据接口信息去找mapper.xml对应的statement,所以使用代理型要满足的条件是,namespace=接口的全类名,resultType=返回值(泛型)全类名,id=接口方法名,parameterType=参数全类名

5.复杂映射

public class Order {
private int id;
private Date ordertime;
private double total;
//代表当前订单从属于哪一个客户
private User user;
}
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//代表当前用户有多少订单
private List<Order> orders;
//代表当前用户有多少角色
private List<Role> roleList;
}
public class Role {
private int id;
private String rolename;
}

5.1 一对一映射

5.1.1 xml实现

<resultMap id="orderMap" type="com.dck.domain.Order">
<result property="id" column="id"></result>
<result property="ordertime" column="ordertime"></result>
<result property="total" column="total"></result>
<!--关键-->
<association property="user" javaType="com.dck.domain.User">
<result column="uid" property="id"></result>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="birthday" property="birthday"></result>
</association>
</resultMap>

 

5.2 一对多映射

5.2.1 xml实现

<mapper namespace="com.lagou.mapper.UserMapper">
<resultMap id="userMap" type="com.lagou.domain.User">
<result column="id" property="id"></result>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="birthday" property="birthday"></result>
<!--关键-->
<collection property="orderList" ofType="com.dck.domain.Order">
<result column="oid" property="id"></result>
<result column="ordertime" property="ordertime"></result>
<result column="total" property="total"></result>
</collection>
</resultMap>
<select id="findAll" resultMap="userMap">
select *,o.id oid from user u left join orders o on u.id=o.uid
</select>
</mapper>

 

5.3 多对多映射

5.3.1 xml实现

<resultMap id="userRoleMap" type="com.lagou.domain.User">
<result column="id" property="id"></result>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="birthday" property="birthday"></result>
<!--关键-->
<collection property="roleList" ofType="com.dck.domain.Role">
<result column="rid" property="id"></result>
<result column="rolename" property="rolename"></result>
</collection>

</resultMap>
<select id="findAllUserAndRole" resultMap="userRoleMap">
select u.*,r.*,r.id rid from user u left join user_role ur on
u.id=ur.user_id
inner join role r on ur.role_id=r.id
</select>

6.缓存

6.1 一级缓存(sqlSession级别,默认开启)

共用一个sqlSession的情况下才使用到了一级缓存,比如@Transational注解的方法内的所有数据库请求共用一个sqlSession、sqlSession是单例、静态域或者实例成员变量。

存放位置:SqlSession>Executor>PerpetualCache>Map<Object,Object>

使用:每次Executor执行数据库查询query之前,都会检查缓存中是否有完全相同SQL语句的缓存,有则直接返回对应value

  1. 第一次查询---》1.读取缓存,发现没有匹配key;2.从数据库读取,并插入缓存
  2. 第二次查询完全相同的SQL---》读取缓存,命中直接返回,且是同一个对象
  3. sqlSession.commit()或clearCache()或close()---》清空缓存

6.2 二级缓存(nameSpace级别,默认关闭)

6.2.1 默认二级缓存

XML开启:

<!--sqlMapConfig.xml文件中-->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<!--Mapper.xml文件中,可指定type参数选择自定义的缓存类-->
<cache></cache>

 

6.2.2 使用redis作为二级缓存

解决问题:当服务器集群或者多个实例访问同一个数据库时,无法实现数据库缓存 在多个服务器之间共享,故使用第三方内存数据库作为缓存----分布式缓存。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诗酒醉云长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值