初入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>
阅读全文
0 0
- 初入MyBatis框架<三>
- 初入MyBatis框架<一>
- 初入MyBatis框架<二>
- 初入Hibernate框架<三>
- 三构框架,mybatis
- 初入MVP框架
- 【框架整合】三、整合mybatis
- 初入Hibernate框架<一>
- 初入Hibernate框架<二>
- 框架设计之菜鸟漫漫江湖路系列 三:初入江湖
- 框架设计之菜鸟漫漫江湖路系列 三:初入江湖
- 初入mybatis的几个坑
- Mybatis框架基础学习(三)
- ssm框架搭建三---mybatis打印sql
- Struts2,mybatis,spring三大框架整合
- 三大框架Spring+Mybatis+springMVC整合
- 三大框架整合struts+spring+mybatis
- 初入spring源码--整体框架
- Redis 安装
- EventBus系列(一):初探
- hdu4704 && FZU1759 && HYSBZ3884 &&POJ3090 欧拉函数 || 欧拉降幂 ||费马小定理
- Java中ReentrantLock的公平锁和非公平锁
- 百威软件暗桩 清除“请使用正版软件”提示解决方法
- 初入MyBatis框架<三>
- angularJS动态生成的页面中,ng-click无效解决办法
- IO-内存操作流
- Linux 线程
- Android Fragment(2)
- AI开发实战8-Web浏览框(WebView)的定制1
- pharse 精灵图的截取
- linux文件系统
- sas统计分析学习笔记(六)