Mybatis——传入POJO对象,动态SQL,多表关系

Posted 想54256

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis——传入POJO对象,动态SQL,多表关系相关的知识,希望对你有一定的参考价值。

传入POJO对象

QueryVo.java

public class QueryVo implements Serializable{

    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

SQL映射文件

<!-- 传入POJO对象,查询用户 -->
<select id="findUserByPOJO" parameterType="QueryVo" resultType="User">
	select * from user where id = #{user.id}
</select>

测试类

@Test
public void func9() throws IOException {

    // 1.加载配置文件
    InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
    // 2.创建sqlSessionFactory
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
    // 3.获取sqlsession
    SqlSession sqlSession = sqlSessionFactory.openSession();
    // -------------------------------------------

    // 4.SqlSEssion帮我生成一个实现类(给接口的字节码文件)
    UserDao mapper = sqlSession.getMapper(UserDao.class);

    // 创建一个POJO对象
    QueryVo vo = new QueryVo();
    User u = new User();
    u.setId(2);

    vo.setUser(u);

    User userByPOJO = mapper.findUserByPOJO(vo);

    System.out.println(userByPOJO);

    // -------------------------------------------

}

resultMap(手动指定字段)

数据库表

Order实体文件

public class Order {
	// 订单id
	private int id;
	// 用户id
	private Integer userId;
	// 订单号
	private String number;
	// 订单创建时间
	private Date createtime;
	// 备注
	private String note;
get/set。。。
}

SQL映射文件

由于实体和SQL中的userid字段不同,所以要使用resultMap

<resultMap id="jzy" type="Order">
	<result column="user_id" property="userId" />
</resultMap>

<select id="findOrderById" parameterType="int" resultMap="jzy">

	select * from `order` where id = #{id}
	-- order是关键字,所以要用``包起来

</select>

OrderDao.java

public interface OrderDao {

    Order findOrderById(int i);

}

测试类

public void func() throws IOException {

    // 1.加载配置文件
    InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
    // 2.创建sqlSessionFactory
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
    // 3.获取sqlsession
    SqlSession sqlSession = sqlSessionFactory.openSession();
    // -------------------------------------------

    // 4.执行相应的SQL语句
    OrderDao mapper = sqlSession.getMapper(OrderDao.class);

    Order orderById = mapper.findOrderById(1);

    System.out.println(orderById);

    // -------------------------------------------
}

一.动态SQL

1)if标签&&where标签

<!--	根据性别和名字查询用户  where 可以去掉第一个前ANd   -->
<select id="selectUserBySexAndUsername" parameterType="User" resultType="User">
	<where>
		<if test="sex != null and sex != \'\'">
			 and sex = #{sex} 
		</if>
		<if test="username != null and username != \'\'">
			 and username = #{username}
		</if>
	</where>
 </select>

2)foreach标签

a.直接传入数组

UserDao.java

public interface UserDao {
    List<User> selectUserByIds(int[] ids);
}

配置文件

<!-- 多个ID select * from user where id in (1,2,3)-->
<select id="selectUserByIds" parameterType="int[]" resultType="User">
	<include refid="selector"/>
	<where>
		<!--只要是传入的数组,collection就是"array"-->
		<foreach collection="array" item="id" separator="," open="id in (" close=")">
			#{id}
		</foreach>
	</where>
</select>

测试类

@Test
public void func3() throws IOException {

    // 1.加载配置文件
    InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
    // 2.创建sqlSessionFactory
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
    // 3.获取sqlsession
    SqlSession sqlSession = sqlSessionFactory.openSession();
    // -------------------------------------------

    // 方法一:直接传入一个数组
    int[] ids = {1,2,3};

    UserDao mapper = sqlSession.getMapper(UserDao.class);

    List<User> list = mapper.selectUserByIds(ids);

    System.out.println(list);

    // -------------------------------------------
}

b.直接传入集合

<!-- 多个ID select * from user where id in (1,2,3)-->
<select id="selectUserByIds" parameterType="Integer" resultType="User">
	<include refid="selector"/>
	<where>
		<!--只要是传入的集合,collection就是"list"-->
		<foreach collection="list" item="id" separator="," open="id in (" close=")">
			#{id}
		</foreach>
	</where>
</select>

测试类

// 方法二:直接传入一个集合
List<Integer> ids = new ArrayList<>();

ids.add(1);
ids.add(2);
ids.add(3);

UserDao mapper = sqlSession.getMapper(UserDao.class);

List<User> list = mapper.selectUserByIds(ids);

System.out.println(list);

c.传入一个POJO,里面有集合或者数组

<!-- 多个ID select * from user where id in (1,2,3)-->
<select id="selectUserByIds" parameterType="QueryVo" resultType="User">
	<include refid="selector"/>
	<where>
		<foreach collection="ids" item="id" separator="," open="id in (" close=")">
			#{id}
		</foreach>
	</where>
</select>

测试类

// 方法三:传入一个POJO
//List<Integer> ids = new ArrayList<>();
//
//ids.add(1);
//ids.add(2);
//ids.add(3);
int[] ids = {1,2,3};
QueryVo vo = new QueryVo();
vo.setIds(ids);



UserDao mapper = sqlSession.getMapper(UserDao.class);

List<User> list = mapper.selectUserByIds(vo);

System.out.println(list);

二.关联查询

1、一对一查询

1)在Order中添加一个user字段并提供get,set方法

 

2)书写接口

List<Order> findOrderList();

3)书写配置文件

<resultMap id="jbb" type="Order">
	<id column="id" property="id"/>
	<result column="user_id" property="userId" />
	<result column="number" property="number" />

	<!-- 一对一配置 -->
	<association property="user" javaType="User">
		<id column="user_id" property="id" />
		<result column="username" property="username"/>
	</association>
</resultMap>


<select id="findOrderList" resultMap="jbb">
	select
	o.id,o.user_id,o.number,o.createtime,u.username
	from `order` o
	left join
	user u
	on
	o.user_id=u.id
</select>

4)测试类

public void func4() throws IOException {

    // 1.加载配置文件
    InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
    // 2.创建sqlSessionFactory
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
    // 3.获取sqlsession
    SqlSession sqlSession = sqlSessionFactory.openSession();
    // -------------------------------------------

    OrderDao mapper = sqlSession.getMapper(OrderDao.class);

    List<Order> orderList = mapper.findOrderList();

    System.out.println(orderList);

    // -------------------------------------------
}

2、一对多查询

1)在User中添加一个集合,保存Order对象

2)书写接口

List<User> findUserAllOrder();

3)SQL映射文件

<resultMap id="jjj" type="User">
	<id column="user_id" property="id"/>
	<result column="username" property="username"/>

	<!-- 一对多 -->
	<collection property="orderList" ofType="Order">
		<id column="id" property="id"/>
		<result column="number" property="number"/>
		<result column="createtime" property="createtime"/>
		<result column="user_id" property="userId"/>
	</collection>
</resultMap>

<select id="findUserAllOrder" resultMap="jjj">
	select
	o.id,o.user_id,o.number,o.createtime,u.username
	from user u
	left join
	`order` o
	on
	o.user_id=u.id
</select>

测试类

@Test
public void func5() throws IOException {

    // 1.加载配置文件
    InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
    // 2.创建sqlSessionFactory
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
    // 3.获取sqlsession
    SqlSession sqlSession = sqlSessionFactory.openSession();
    // -------------------------------------------

    OrderDao mapper = sqlSession.getMapper(OrderDao.class);

    List<User> userAllOrderList = mapper.findUserAllOrder();

    System.out.println(userAllOrderList);

    // -------------------------------------------
}

三.与Spring整合

方式一:原始Dao方式

1)Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">

    <!-- 读取配置文件 -->
    <context:property-placeholder location="classpath:db.properties"/>

    <!-- 设置数据库连接池 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="maxActive" value="10" />
        <property name="maxIdle" value="5" />
    </bean>

    <!-- 建立Mybatis的SQLSessionFactory工厂 -->
    <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入连接池 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 核心配置文件的位置 -->
        <property name="configLocation" value="classpath:sqlMapConfig.xml"/>
    </bean>

    <!-- Dao原始Dao -->
    <bean id="userDao" class="cn.x5456.dao.UserDaoImpl">
        <property name="sqlSessionFactory" ref="sqlSessionFactoryBean"/>
    </bean>
    
</beans>

2)UserDao.java

// 继承SqlSessionDaoSupport,调用父类的getSqlSession方法
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {

    public void main(String[] args) {
        super.getSqlSession().selectList("xxx.xxx","参数");
    }
}

方式二:mapper代理模式 

1)Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">

    <!-- 读取配置文件 -->
    <context:property-placeholder location="classpath:db.properties"/>

    <!-- 设置数据库连接池 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="maxActive" value="10" />
        <property name="maxIdle" value="5" />
    </bean>

    <!-- 建立Mybatis的SQLSessionFactory工厂 -->
    <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入连接池 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 核心配置文件的位置 -->
        <property name="configLocation" value="classpath:sqlMapConfig.xml"/>
    </bean>

    <!-- Mapper动态代理开发 -->
    <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="sqlSessionFactory" ref="sqlSessionFactoryBean"/>
        <property name="mapperInterface" value="cn.x5456.dao.UserMapper"/>
    </bean>


</beans>

2)Mybatis主配置文件

<?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="cn.x5456.domain" />
	</typeAliases>
	
	<mappers>
		<package name="cn.x5456.dao"/>
	</mappers>

</configuration>

3)SQL映射关系配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">



<mapper namespace="cn.x5456.dao.UserMapper">	<!-- 将当前接口与接口绑定 -->
	
	<!-- 通过ID查询一个用户 -->
	<select id="findUserById" parameterType="Integer" resultType="User">
		select * from user where id = #{id}
	</select>
	
</mapper>

4)UserMapper接口

public interface UserMapper {
    User findUserById(Integer id);
}

5)测试类

public void func(){
    ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
    UserMapper userMapper = (UserMapper) ac.getBean("userMapper");

    User userById = userMapper.findUserById(1);

    System.out.println(userById);
}

方式三:动态扫描

上面的会有一个弊端,如果Mapper太多,配置文件就变得很多。所以引入扫描

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
	<!-- 基本包 -->
	<property name="basePackage" value="com.itheima.mybatis.mapper"/>
</bean>

获取mapper方法

UserMapper userMapper = ac.getBean(UserMapper.class);

 

以上是关于Mybatis——传入POJO对象,动态SQL,多表关系的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis中输入输出映射和动态Sql

Mybatis中输入输出映射和动态Sql

Mybatis学习输入映射输出映射动态sql

Mybatis中#{}和${}的区别

Mybatis-传参

Mybatis--02