1:使用mybatis进行连接(嵌套)查询(也就是many-to-one 或者是one-to-one)
比如说有个用户表(users),和文章表(titles)一个用户可以发表多个文章,而一个文章只能有一个用户能发表
<select id="join" resultMap="findUsers" resultType="list">
select * from titles t,users u
where t.uid=u.id
</select>
<resultMap type="Titles" id="findUsers">
<id property="id" column="id"/>
<result property="title" column="title"/>
<result property="uid" column="uid"/>
<association property="u" javaType="Users" column="uid">
<id property="id" column="id"/>
<result property="uname" column="uname"/>
<result property="pwd" column="pwd"/>
</association>
</resultMap>
注意:select中的resultMap 一定要和下面的resultmap的名称是一致
:使用关键字assocation来连接包含对象 其中的colum不能省,而且在对应的对象中也要有getterandsetter方法
:javaType一定要写当前包含对象的别名
2
<!-- 两表连接查询方法2:使用属性对性映射 -->
<resultMap type="Titles" id="t">
<id column="id" property="id" />
<result property="title" column="title" />
<!-- 属性对象的直接映射 -->
<result property="u.uname" column="uname" />
<result property="u.pwd" column="pwd" />
</resultMap>
<!-- 两表连接查询的语句 -->
<select id="lists" resultMap="t">
select * from titles t,users u where t.uid=u.id
</select>
使用ongl来直接映射对象和属性,不需要使用assocation关键字,通过使用对象点属性来映射对象.
3
<!-- 两表连接查询方法3 通过关键子select-->
<resultMap type="Titles" id="ft">
<id property="id" column="id" />
<result property="title" column="title" />
<association property="u" column="uid" javaType="Users" select="getusers"></association>
</resultMap>
<!-- 查询所有的titls -->
<select id="getlists" resultMap="ft" >
select * from titles
</select>
<!-- 查询所有的users-->
<select id="getusers" resultType="Users" parameterType="int">
select * from users u where u.id=#{uid}
</select>
注意地方:使用两个查询的sql语句,可以方便重用,通过外键查询,这里的uid就是对应的外键
总结:关于对象的嵌套查询,可以是用两个sql语句,也可以是用assocation关键字来直接映射另一个要查询的对象,resultMap是用来映射另一个的结果对象,resultType是当前对象返回的类的全限定名或者是其别名,要注意的是 在一个地方不能同时出现resultMap和resultType,只能用其中一个
4查询集合对象方法1:
<!-- 查询集合的方法2 使用关键子select-->
<resultMap type="Users" id="findUser">
<id column="id" property="id"/>
<result property="uname" column="uname" />
<result property="pwd" column="pwd"/>
<!-- 通过collection来查询多某个用户发表的全部titles -->
<collection property="titles" ofType="Titles" javaType="ArrayList" column="uid" select="selectTitle"/>
</resultMap>
<select id="selectList" resultMap="findUser">
select * from users u where u.id=#{value}
</select>
<select id="selectTitle" resultType="Titles" parameterType="int">
select * from titles t where t.uid=#{value}
</select>
注意:使用两个独立的sql语句,和嵌套查询很类似,但是使用的关键字是collection,该 关键字里面的一些属性是必须要填写的 比如,javaType=ArrayList,offType=”要关联对象类的别名或者是类名的全限定名,select是用来查询关联对象的sql的id。”
查询集合对象的方法2:
<!-- 一个users可以发表多个titles 集合查询方法1 -->
<resultMap type="Users" id="findTitle">
<id column="id" property="id"/>
<result property="uname" column="uname" />
<result property="pwd" column="pwd"/>
<!-- 通过collection来查询多某个用户发表的全部titles -->
<collection property="titles" ofType="Titles" >
<id column="id" property="id"/>
<result property="u" column="u.id"/>
<result property="title" column="title"/>
</collection>
</resultMap>
<!-- 查询的语句 -->
<select id="u" resultType="Users" parameterType="int" resultMap="findTitle">
select * from users u,titles t where u.id=t.uid and u.id=#{value}
</select>
注意:使用一个连接的sql语句,不要两个sql语句,通过在collection关键字里面把要查询的另一个对象的属性全部映射出来就可以了,其中ofType属性是必须要填写的,对应的类型是返回当前查询对象的类的别名或者是其全限定名.
保存对象1:
单个对象的保存:
<!-- 插入用户 -->
<insert id="users" parameterType="Users" useGeneratedKeys="true" keyProperty="id">
insert into users(uname,pwd)
values(#{uname},#{pwd})
</insert>
注意:useGenernateKeys如果是true表示的是主键是自增的,如果是fasle那么主键不是自增的,在我们没添加一条数据都要手动去插入,keyProperty是用来表明哪个是主键列
保存对象2:
多个多想一起保存:
<insert id="add" parameterType="Titles" useGeneratedKeys="true" keyProperty="id">
insert into titles (title,uid) values(#{title},#{u.id})
</insert>
注意:在此种情况下一定要先保存,外键表关联的对象,之后在保存主键表的对象,所以要写两条sql语句,插入的外键的编号,要通过是用对象点属性的方法,而不是单独插入一个外键,比如#{u.id}
5:动态的sql语句
动态的查询语句:
<select id="choose" resultType="Users" parameterType="Users">
select * from users
<where>
<if test="uname!=null">
uname like concat (concat('%',#{uname}),'%')
</if>
<if test="pwd!=null">
and pwd=#{pwd}
</if>
</where>
</select>
这条语句表示根据用户的姓名和密码进行动态的查询,如果什么都不写,就查询所有的信息,如果有就根据对应的条件来查询。
动态的更新语句:
<update id="up" parameterType="Users">
update users
<set>
<if test="uname!=null">
uname=#{uname},
</if>
<if test="pwd!=null">
pwd=#{pwd},
</if>
</set>
<where>
id=#{id}
</where>
</update>
注意使用这条语句关键字set不用再写了,以前更新表是这样写的:update set 表 where 条件
现在关键字set不能写,否则会报错,同时每一个if语句后面要加一个逗号(,)而不是分号(;),否则会保存
多参数的查询:参数返回的类型是map
<!-- 多参数查询信息 返回的是map -->
<select id="getone" resultType="Users" parameterType="map">
select * from users where uname=#{uname} and pwd=#{pwd}
</select>
注意因为查询的是多个参数,所以需要用map来作为查询参数的返回类型,也就是说要把所有要查询的参数都放在一个map集合中,之后再传入进来.使用如下:
SqlSession session=MyBatisUtil.getSession();
Map<String , String>map=new HashMap<String, String>();
map.put("uname","admin");
map.put("pwd", "3333");
Users u=(Users)session.selectOne("demo.getone", map);
6分页查询的语句:
针对sqlserver:
<!-- 分页查询 -->
<select id="getpage" resultMap="users" parameterType="map">
select top ${pagesize} * from users where id not in
(select top (${(pagenum-1)}* ${pagesize}) id from users)
</select>
注意这里首先要知道$和#这两个符号的区别,后一个符号只能接受一个可变的字符串,而前一个是接受一个对象或者是不该变的属性
针对oracle语句
<select id="getpage" resultMap="users" parameterType="map">
SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
WHERE ROWNUM <= {pagesize}
)
WHERE RN >= ${(pagenum-1)}* ${pagesize}
</select>
注意oracle中没有top关键字,只有rownum,伪列,同时使用的是子查询
7核心配置文件:如下面的一样:这个是最基本的配置,也是一些必要的配置,是不能少的
<?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>
<typeAliases>
<typeAlias type="entity.Users" alias="Users"/>
用来配置类的别名,方便以后的使用
<typeAlias type="entity.Titles" alias="Titles"/>
</typeAliases>
配置数据源的远行环境,可以配置多个数据的远行环境,比如可以同时配置sqlserver和oracle两个数据源
<environments default="development">
<environment id="development">
配置事务的管理者是什么,默认还是jdbc,当时当和spring整合时候,这个就有spring来管理
<transactionManager type="jdbc">
</transactionManager>
配置一个数据连接池,包含的一些的基本属性
<dataSource type="POOLED">
<property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="jdbc:sqlserver://localhost:1433;databasename=demo"/>
<property name="username" value="sa"/>
<property name="password" value="ok"/>
</dataSource>
</environment>
</environments>
配置需要加载的映射文件对应的xml,这里面的xml都是要操作的sql语句
<mappers>
<mapper resource="mapper/Users.xml"/>
<mapper resource="mapper/Titles.xml"/>
</mappers>
</configuration>
8与spring框架的整合:
1导入必要的jar包
2:配置mybatis的工厂 如下:
<!-- 配置mybatis的sqlsession工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:SqlConfigMap.xml"></property>
<property name="dataSource" ref="dataSource"></property>
</bean>
其它的配置和hibernate基本都是一样的,当然它可以和hibernate同时公用一个数据源!
9:如何获取sqlsession这个对象:
当自己独立使用的时候,通过读取配置文件来获取,代码如下
static SqlSessionFactory factory=null;
static{
String resources="SqlConfigMapp.xml";
Reader reader;
try {
reader = Resources.getResourceAsReader(resources);
factory=new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static SqlSession getSession()
{
return factory.openSession();
}
两个关键的对象: SqlSessionFactoryBuilder, SqlSessionFactory, SqlSessionFactory,定义成静态,方便资源的使用
Dtd的使用和格式:
核心配置文件的DTD:
<?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">
查询对象的映射文件的DTD:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper SYSTEM "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >