实现一对一,一对多查询
三个重点:1.resultmap 2.动态Sql 3.关联查询
创建工程,配置环境
- 使用的工具是idea和MySQL,还有数据库的图形界面工具sqlyog,maven环境已经搭好前提下
- idea创建工程 maven.xxx.quickstart,添加模组maven.xxx.webapp,在对应pom.xml文件(小的)下
<build></build>
标签和内容可以删除,因为maven已经自带了编译的功能不需要这个。 - 配置环境,在对应pom.xml的
<dependencies></dependencies>
标签中添加依赖
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--日志包-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
访问数据库的四大信息
在资源文件夹下建一个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>
<typeAliases>
<package name="com.wzx.bean"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- 四大信息 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/(这里写数据库名)?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 一个mapper标签可以指定一个映射文件-->
<mappers>
<mapper resource="这里写要映射的子文件类似com/yzf/dao/UserDao.xml""/>
</mappers>
</configuration>
SqlSession
是mybatis的核心,获取session对象对数据库访问,动态资源文件下创建对应类,也是访问数据库要的准备
public class MySessionUtils {
private static SqlSessionFactory sessionFactory;
//static 静态代码,在类加载的时候执行一次,且只执行一次
static{
// 》1 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 》2 创建SqlSessionFactory对象
InputStream inputStream = MySessionUtils.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
sessionFactory = sqlSessionFactoryBuilder.build(inputStream);//加载核心配置文件 参1 输入流
// 》3 加载SqlMapConfig.xml配置文件
}
public static SqlSession getSession() {
// 》4 创建SqlSession对象
SqlSession sqlSession = sessionFactory.openSession();
return sqlSession;
}
}
资源文件添加后缀.properties属性文件
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
重点1.resultMap
resultMap标签映射关系和resultMap使用,在不改表不改类的情况下,字段名不一样的时候可以赋值。如果库里数据名和类名一样就可以不写<id colunmn="x" property="x"><result column="X" property="x"/>
只要在type做好映射就好了。还有<association property="xx" javaType="xx"></association>
标签可以自定义类型(重点3有例子),表连接查询能用到,property表示类名,javaType表示类的类型
<resultMap id="OrderMap" type="com.yzf.domain.Order">
<!-- 主键部份-->
<id column="oid" property="oid"/>
<!-- 非主键部分-->
<result column="(表名)" property="(类名)"/>
<!--查询字段名与类的变量名一样的可以不写 -->
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
</resultMap>
<select id="findAll" resultMap="OrderMap">
select * from tab_order
</select>
测试使用。创建接口Dao类,测试里用getSession获取session,然后getMapper(xxx.class)(自动写方法实现sql语句),然后添加对应的方法名,添加xml文件,就是上面那部分代码修改一下。在最大的xml配置文件添加小的就行了。
重点2.动态Sql
有if标签,where和foreach等,最常用来高级搜索
例如select * from xx where xx like “xx” and xx = “xx”
有两个条件,如果想自由搜寻就适合用标签
<select id="findByUser" resultType="com.yzf.domain.User">
<where>
<if test="username != null and username != '' ">
and username like #{username}
</if>
<if test="address != null and address != '' ">
and address = #{address}
</if>
</where>
</select>
foreach标签,查询多个值的时候使用
<select id="findId" parameterType="list" resultType="com.yzf.domain.User">
select * from userlist
<where>
<foreach collection="list" item="id" open="uid in(" close=")" separator=",">
#{id}
</foreach>
</where>
</select>
collection里的名字要对应接口的变量名,如果名字不一样可以在接口里添加@Param注解List<User> findId(@Param("ooo") List<Integer> list);
item是遍历列表,集合元素赋值给item和python的循环差不多#{id}里面的id和item一样代表取每一个的值。open表示开始 close表示结束,separator代表分隔符。
重点3.关联查询,一对一
关系假设的是订单与用户关系,一个订单对应一个客户。(内连接inner join 左外连接 left outer join 右外连接right outer join 子查询select 嵌套 select)连接方便查看
- 使用resultType方法返回值时,测试类里写下面的,对应接口写
List<UserOrder> findAllUserOrder();
SqlSession session = MySessionUtils.getSession();
OrderDao orderDao = session.getMapper(OrderDao.class);
List<UserOrder> order = orderDao.findAllUserOrder();
System.out.println(order);
session.close();
对应的xml里写,要新建一个javaBean类保存数据,因为两个表连接了,数据数量对不上,用resultType必须有一个类对应全部的属性。
<select id="findAllUserOrder" resultType="com.yzf.domain.UserOrder">
select * from tab_order o left join userlist u on o.user_id = u.uid
</select>
- 使用resultMap时,结合上面,在order类上面添加成员变量user,
private User user
,测试里写
SqlSession session = MySessionUtils.getSession();
OrderDao orderDao = session.getMapper(OrderDao.class);
List<Order> list = orderDao.findAllUserOrder2();
System.out.println(list);
session.close();
这里写在OrderDao.xml,记得添加autoMapping=true,resultMap标签的type要设置好还有association中的property和javaType,查询方法一般一个个写不用*号,不写星号类似(select u.username from userlist u left join tab_order on u.id = o.id)userlist和tab_order是表名
<resultMap id="UserOrderMap" type="com.yzf.domain.Order" autoMapping="true" >
<id property="oid" column="oid"></id>
<association autoMapping="true" property="user" javaType="com.yzf.domain.User">
</association>
</resultMap>
<select id="findAllUserOrder2" resultMap="UserOrderMap">
select * from tab_order o left join userlist u on o.user_id = u.uid
</select>
一对多查询
数据库select * from userlist u left join tab_order o on u.uid=o.user_id
。在bean类User中定义List后面要用collection对应它private List<Order> orders;
这是集合类型
<resultMap id="UsersMap" type="com.yzf.domain.User" autoMapping="true">
<id property="uid" column="uid"></id>
<collection property="orders" ofType="com.yzf.domain.Order" autoMapping="true">
</collection>
</resultMap>
<select id="findAllUsers" resultMap="UsersMap">
select * from userlist u left join tab_order o on u.uid=o.user_id
</select>
- 其中 < collection property=“order” javaType=“com.yzf.domain.Order”>中collection表示集合,property指定变量是定义那个变量名,ofType指里面的元素类型,记得是ofType
来源:oschina
链接:https://my.oschina.net/u/4354530/blog/4658824