初入MyBatis框架<三>

来源:互联网 发布:网络机柜走线图 编辑:程序博客网 时间:2024/05/17 23:47

初入MyBatis框架<三>

主要内容:
1、多表之间的关系
2、缓存技术

多表之间的关系操作:

这里写图片描述

oneToMany:

首先还是数据库中表的创建,以及值对象的编写,要注意,ToString()中不能有包含,否则会循环。
SQL语句

CREATE TABLE persons(   pid VARCHAR(32) PRIMARY KEY,   pname VARCHAR(30));CREATE TABLE cars(   id VARCHAR(32) PRIMARY KEY,   NAME VARCHAR(30),   price NUMERIC(10,2),   pid VARCHAR(32),   CONSTRAINT car_fk FOREIGN KEY(pid) REFERENCES persons(pid));INSERT INTO persons VALUES('P001','Jack');INSERT INTO persons VALUES('P002','Rose');INSERT INTO persons VALUES('P003','张三');INSERT INTO cars VALUES('C001','BMW',100,'P001');INSERT INTO cars VALUES('C002','BenZ',80,'P001');INSERT INTO cars VALUES('C003','Jeep',50,'P003');

值对象:
Car
这里写图片描述
Person
这里写图片描述

演示代码:

@Test//需求:查询哪些人有什么车(内联)    public void oneToMany(){        SqlSession s= SqlSessionUtils.getSqlSession();        List<Person> persons=s.selectList("oneToMany");        System.out.println(persons);        s.close();    }    @Test//需求:查询哪些人有什么车,采用嵌套子查询(了解)    public void oneToMany2(){        SqlSession s= SqlSessionUtils.getSqlSession();        List<Person> persons=s.selectList("oneToMany2");        System.out.println(persons);        s.close();    }

写一个Person.xml核心配置文件:

<mapper namespace="persons"><!-- 数据库的表名字 -->    <!-- 一对多 内联 -->    <select id="oneToMany" resultMap="ps"><!-- 在下面定义PS -->        <!-- 如果返回类型是简单类型,就用resultType,如果是复杂类型(一般是多表), 就要用resultMap进行自定义封装。 -->        select p.pid as pid , p.pname as pname ,            c.id as cid , c.name as cname , c.price as cprice        from persons p inner join cars c        on p.pid=c.pid    </select>    <!-- 定义复杂的数据类型(自定义封装), -->    <resultMap type="cn.hncu.domain.oneToMany.Person" id="ps">        <!-- 最好主键用ID column表中的哪一列jdbcType是类型 ;             property值对象哪一个变量 javaType值对象类型 -->        <!--**每个数据封装,column是来自上面查询结果表的列或者字段,有别名用别名** -->        <id column="pid" jdbcType="VARCHAR" property="id" javaType="string" />        <!-- 普通字段 -->        <result property="name" column="pname" />        <!-- 一对多,多对多 用collection,已经是个集合了javaType里面直接给 元素-->        <collection property="cars" javaType="cn.hncu.domain.oneToMany.Car">            <id column="cid" jdbcType="VARCHAR" property="id" javaType="string"/>            <!-- 省略会自己去找类型,除了特殊的别名 -->            <result property="name" column="cname"/>            <result property="price"  javaType="_double" column="cprice" jdbcType="NUMERIC"/>        </collection>    </resultMap>    <!-- 演示采用嵌套子查询 实现一对多,需求同上 -->    <select id="oneToMany2" resultMap="ps2">        select pid,pname from persons    </select>    <resultMap type="cn.hncu.domain.oneToMany.Person" id="ps2">        <id property="id" column="pid"/>        <result property="name" column="pname"/>        <!-- 结果集,嵌套另一个查询 selCars,用pid查-->        <collection property="cars" select="selCars" column="pid"/>    </resultMap>    <!-- 用子查询的结果 返回给结果集-->    <select id="selCars" resultType="cn.hncu.domain.oneToMany.Car" parameterType="string"><!-- 接pid -->        select * from cars where pid=#{pid}    </select></mapper>

OneToOne:

在Person的基础上加入了Card:
SQL语句

CREATE TABLE card(   card_id VARCHAR(32) PRIMARY KEY,   card_gov VARCHAR(30),   pid VARCHAR(32) unique,   CONSTRAINT card_fk FOREIGN KEY(pid) REFERENCES persons(pid));INSERT INTO card VALUES('C001','北京市公安局','P001');INSERT INTO card VALUES('C002','长沙市公安局','P002');

值对象
Person
这里写图片描述
Car
这里写图片描述
Card
这里写图片描述

演示代码:

@Test//查询每个人的身份证信息    public void oneToOne(){        SqlSession s= SqlSessionUtils.getSqlSession();        List<Card> cards=s.selectList("oneToOne");        System.out.println(cards);        s.close();    }

核心配置文件:
Card.xml

<mapper namespace="cards"><!-- 数据库的表名字 -->    <!-- 演示一对一 ,内联-->    <select id="oneToOne" resultMap="c1">        select c.card_id as id , c.card_gov as gov,               p.pid as pid , p.pname as pname        from card c inner join persons p         on c.pid=p.pid    </select>    <resultMap type="cn.hncu.domain.OneToOne.Card" id="c1">    <!-- 配置用哪个构造函数,封装了ID -->    <constructor>        <idArg column="id" jdbcType="VARCHAR"  javaType="string" />    </constructor>        <result property="gov" column="gov"/>        <!-- 一对一 -->        <association property="person" javaType="cn.hncu.domain.OneToOne.Person">            <id column="pid" jdbcType="VARCHAR" property="id" javaType="string"/>            <result column="pname" property="name"/>            <collection property="cars" select="selCars" column="pid"/>        </association>    </resultMap>    <!-- 用子查询的结果 返回给结果集-->    <select id="selCars" resultType="cn.hncu.domain.OneToOne.Car" parameterType="string"><!-- 接pid -->        select * from cars where pid=#{pid}    </select></mapper>

ManyToMany:

在User上加了人物角色:
SQL语句:

CREATE TABLE roles(   id VARCHAR(32) PRIMARY KEY,   name VARCHAR(30));CREATE TABLE roleuser(   roleid VARCHAR(32),   userid VARCHAR(32),   CONSTRAINT ru_pk PRIMARY KEY(roleid,userid),   CONSTRAINT ru_fk1 FOREIGN KEY(roleid)                                    REFERENCES roles(id),   CONSTRAINT ru_fk2 FOREIGN KEY(userid)                                    REFERENCES users(id));INSERT INTO roles VALUES('R001','教师');INSERT INTO roles VALUES('R002','老板');INSERT INTO roles VALUES('R003','学生');INSERT INTO roleuser VALUES('R001','U001');INSERT INTO roleuser VALUES('R002','U001');INSERT INTO roleuser VALUES('R003','U001');INSERT INTO roleuser VALUES('R001','U010');INSERT INTO roleuser VALUES('R001','U002');INSERT INTO roleuser VALUES('R002','U003');INSERT INTO roleuser VALUES('R003','U003');

值对象也加了关系:
User.java
这里写图片描述
Role.java
这里序列化是为了等下,演示缓存技术而加的

这里写图片描述

演示代码:

////////多对多////////    @Test//查询每个人有哪些角色    public void manyToMany(){        SqlSession s= SqlSessionUtils.getSqlSession();        List<User> users=s.selectList("manyToMany");        System.out.println(users);        s.close();    }

核心配置文件Role.xml

<mapper namespace="roles"><!-- 数据库的表名字 -->    <!-- 演示多对多 -->    <select id="manyToMany" resultMap="u1">        select u.id as id , u.name as name, u.pwd as pwd,               r.id as rid, r.name as rname from  users u         inner join roleuser ru on u.id=ru.userid            inner join roles r on ru.roleid=r.id    </select>    <resultMap type="cn.hncu.domain.manyToMany.User" id="u1">        <id column="id" property="id"/>        <result column="name" property="name"/>        <result column="pwd" property="pwd"/>        <collection property="roles" javaType="cn.hncu.domain.manyToMany.Role">            <id column="rid" property="id"/>            <result column="rname" property="name"/>        </collection>    </resultMap></mapper>

演示mybatis中的缓存技术:

演示代码:

使用的是Role.xml

/////////mybatis中的缓存//////////    @Test//查某个人的角色(单表查询)------学习缓存技术(只控制第二级缓存)    public void queryOneRole(){        SqlSession s= SqlSessionUtils.getSqlSession();        //查单        Object obj1=s.selectOne("queryOneRole","R002");        //System.out.println(obj1);        System.out.println(obj1.hashCode());        //再查  1级缓存没有,去2级看,克隆一份2级有的        Object obj2=s.selectOne("queryOneRole","R002");        //System.out.println(obj2);        System.out.println(obj2.hashCode());        s.close();//关了session,下面一个可能会拿到一样的,一个session一个连接CON        /*         *缓存原理:         *  一级缓存:         *      看session有没有,没有去看二级,再没有去数据库查,         *          然后查了回来,给二级(克隆)、一级缓存放一份         * 自己去数据库拿的,自己的1级缓存会留         * 直接2级缓存拿的,不留         */        System.out.println("------------------------");        //再开一个session        SqlSession s2= SqlSessionUtils.getSqlSession();        Object obj21=s2.selectOne("queryOneRole","R002");        System.out.println(obj21.hashCode());        Object obj22=s2.selectOne("queryOneRole","R002");        System.out.println(obj22.hashCode());        s.close();        /*加缓存:         *  1、在xml中加了<cache></cache>,         *  2、Role.java实现序列化         * 这样会使得s2,直接从2级里面克隆出来,直接拿走,不会再1级缓存中保留,而且地址不一样         * 可以用DEBUG看出来         */    }

需要在Role.xml配置文件中加入控制缓存的标签:

Role.xml

<!-- Role.java实现序列化(implements Serializable) -->    <cache></cache><!-- 单独开这一个的缓存 -->    <!-- 如果想关闭所有2级缓存 ,mybatis-config.xml中settiings--><!-- 还可以单独控制一个标签开不开缓存--><!-- 演示缓存技术, 单独标签的缓存开关useCache="true" -->    <select id="queryOneRole" resultType="cn.hncu.domain.manyToMany.Role" parameterType="string">        select * from roles where id=#{id}    </select>

在Mybatis.xml中,有一个缓存总开关

<!-- 顺序settings在typeAliases前 -->    <!-- 关闭缓存后,地址都一样了,在1级中保存了一份 -->    <settings>        <setting name="cacheEnabled" value="true"/><!-- 这里是总开关,开关所有的,默认是开 -->    </settings>
原创粉丝点击