mybatis(二)

一、输入映射和输出映射

1.1 输入参数映射

1.1.1 传递简单类型

上一节演示过了

1.1.2 传递pojo对象

Mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名称。

1.1.3 传递pojo包装对象

开发中通过pojo传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。
Pojo类中包含pojo。
需求:根据用户名查询用户信息,查询条件放到QueryVo的user属性中。

public class QueryVo {

	private User user;

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
}
在UserMapp.xml中添加:
<select id="findUserByVo" parameterType="com.ken.pojo.QueryVo" resultType="com.ken.pojo.User">
	select * from user where username like '%${user.username}%' and sex=#{user.sex}
</select>
UserMapper接口中添加方法声明:
List<User> findUserByVo(QueryVo vo);
UserMapperTest中添加:
@Test
public void testFindUserByVo() throws Exception {
	SqlSession openSession = factory.openSession();
	// 通过getMapper方法来实例化接口
	UserMapper mapper = openSession.getMapper(UserMapper.class);
	QueryVo vo = new QueryVo();
	User user = new User();
	user.setUsername("王");
	user.setSex("1");
	vo.setUser(user);
	mapper.findUserByVo(vo);
	openSession.commit();
}

1.2 返回值映射

1.2.1 输出简单类型

UserMapper.xml

<select id="findUserCount" resultType="java.lang.Integer">
	select count(*) from user
</select>

UserMapper

Integer findUserCount();
UserMapperTest
@Test
public void testFindUserCount() throws Exception {
	SqlSession openSession = factory.openSession();
	UserMapper mapper = openSession.getMapper(UserMapper.class);
	Integer count = mapper.findUserCount();
	System.out.println("========" + count);
	openSession.commit();
}
只有返回结果为一行一列的时候,那么返回值类型才可以指定成基本类

1.2.2 输出pojo对象

参考上一节内容

1.2.3 输出pojo列表

参考上一节内容

1.3 resultMap

二、动态sql

通过mybatis提供的各种标签方法实现动态拼接sql。

2.1 If

UserMapper.xml

<select id="findUserByUserNameAndSex" parameterType="user" resultType="user">
	select * from user where 1=1
	<if test="username!=null and username!=''">
		and username like '%${username}%'
	</if>
	<if test="sex!=null and sex!=''">
		and sex=#{sex}
	</if>
</select>
UserMapper
List<User> findUserByUserNameAndSex(User user);
UserMapperTest
@Test
public void testFindUserByUserNameAndSex() throws Exception {
	SqlSession openSession = factory.openSession();
	UserMapper mapper = openSession.getMapper(UserMapper.class);
	
	User user = new User();
//		user.setUsername("王");
	user.setSex("1");
	List<User> list = mapper.findUserByUserNameAndSex(user);
	System.out.println(list);

	openSession.commit();
}

2.2 Where

我们可以对上面这个例子的配置文件用where进行修改

<select id="findUserByUserNameAndSex" parameterType="user"
	resultType="user">
	select * from user
	 <!-- 
	 	where标签作用:
	 	会自动向sql语句中添加where关键字
	 	会去掉第一个条件的and关键字
	  -->
	<where>
		<if test="username!=null and username!=''">
			username like '%${username}%'
		</if>
		<if test="sex!=null and sex!=''">
			and sex=#{sex}
		</if>
	</where>
</select>

我们还可以把where里面的片段提取出来,以便复用。



2.3 Foreach

我们要实现一个查询:

select * from user where id in (1, 10, 28, 33)
UserMapper.xml
<select id="findUserByIds" parameterType="queryVo" resultType="user" >
	select * from user 
	<where>
		<if test="ids != null">
			<!-- 
			foreach:循环传入的集合参数。
			collection:传入的集合的变量名称。
			item:每次循环将循环出的数据放入这个变量中,这里可以随便取名。用于下方占位符里。
			open:循环开始拼接的字符串;】。
			close:循环结束拼接的字符串。
			separator:循环中拼接的分隔符。
			 -->
			<foreach collection="ids" item="id" open="id in (" close=")" separator=",">
				#{id}
			</foreach>
		</if>
	</where>
</select>
UserMapper:
List<User> findUserByIds(QueryVo vo);
测试:
@Test
public void testFindUserByIds() throws Exception {
	SqlSession openSession = factory.openSession();
	UserMapper mapper = openSession.getMapper(UserMapper.class);

	QueryVo vo = new QueryVo();
	List<Integer> ids = new ArrayList<>();
	ids.add(1);
	ids.add(10);
	ids.add(16);
	ids.add(28);
	vo.setIds(ids);

	List<User> list = mapper.findUserByIds(vo);
	System.out.println(list);

	openSession.commit();
}

2.4 Sql片段

三、关联查询

3.1 一对一关联

一对一:自动映射

public class Orders {
	private Integer id;
	private Integer userId;
	private String number;
	private Date createtime;
	private String note;
	private User user;
}
public class CustomOrders extends Orders {
	private int uid;
	private String username;
	private String sex;
	private Date birthday;
	private String address;
	//getter and setter
}

UserMapper.xml

<!-- 一对一:自动映射 -->
<select id="findOrdersAndUser1" resultType="com.ken.pojo.CustomOrders">
	select a.*, b.id uid, username, birthday, sex, address from orders a, user b where a.user_id = b.id
</select>

UserMapper

List<CustomOrders> findOrdersAndUser1();

测试:

@Test
public void testFindOrderAndUser() throws Exception {
	SqlSession openSession = factory.openSession();
	UserMapper mapper = openSession.getMapper(UserMapper.class);

	List<CustomOrders> list = mapper.findOrdersAndUser1();
	System.out.println(list);

	openSession.commit();
}
一对一:手动映射(mybatis标准的方式)

UserMapper.xml

<!-- 一对一:手动映射 -->
<!-- 
	id:resultMap的唯一标识
	type:将查询出的数据放入这个指定的对象中
	注意:手动映射需要指定数据库中标的字段名域java中pojo类的属性名称的对应关系
	 -->
<resultMap type="com.ken.pojo.Orders" id="ordersAndUserResultMap">
	<id column="id" property="id"/>
	<result column="user_id" property="userId"/>
	<result column="number" property="number"/>
	<result column="createtime" property="createtime"/>
	<result column="note" property="note"/>
	<!-- 
		association:指定单个对象的对应关系
		property:指定将数据放入Orders中的user属性中
		javaType:user属性的类型
	 -->
	<association property="user" javaType="com.ken.pojo.User">
		<id column="uid" property="id"/>
		<result column="username" property="username"/>
		<result column="birthday" property="birthday"/>
		<result column="sex" property="sex"/>
		<result column="address" property="address"/>
	</association>
</resultMap>
<select id="findOrdersAndUser2" resultMap="ordersAndUserResultMap">
	select a.*, b.id uid, username, birthday, sex, address from orders a, user b
	where a.user_id = b.id
</select> 

UserMapper

List<Orders> findOrdersAndUser2();

测试:

@Test
public void testFindOrderAndUser2() throws Exception {
	SqlSession openSession = factory.openSession();
	UserMapper mapper = openSession.getMapper(UserMapper.class);

	List<Orders> list = mapper.findOrdersAndUser2();
	System.out.println(list);

	openSession.commit();
}

3.2 一对多关联

public class User implements Serializable {
	private int id;
	private String username;
	private String sex;
	private Date birthday;
	private String address;
	private List<Orders> ordersList;
	//getter and setter
}

UserMapper.xml

<resultMap type="com.ken.pojo.User" id="userAndOrdersResultMap">
	<id column="id" property="id"/>
	<result column="username" property="username"/>
	<result column="birthday" property="birthday"/>
	<result column="sex" property="sex"/>
	<result column="address" property="address"/>
	<!-- 
		指定对应的集合关系映射 
		property:将数据放入User对象中的ordersList属性中
		ofType:指定ordersList属性的泛型类型
	-->
	<collection property="ordersList" ofType="com.ken.pojo.Orders">
		<id column="oid" property="id"/>
		<result column="user_id" property="userId"/>
		<result column="number" property="number"/>
		<result column="createtime" property="createtime"/>
	</collection>
</resultMap>
<select id="findeUserAndOrders" resultMap="userAndOrdersResultMap">
	select a.*, b.id oid, user_id, number, createtime from user a, orders b where a.id = b.user_id
</select>

UserMapper

List<User> findeUserAndOrders();

测试:

@Test
public void testFindeUserAndOrders() throws Exception {
	SqlSession openSession = factory.openSession();
	UserMapper mapper = openSession.getMapper(UserMapper.class);

	List<User> list = mapper.findeUserAndOrders();
	System.out.println(list);

	openSession.commit();
}

映射工程代码

四、Mybatis整合spring

凡是spring的配置文件中,要引入其他的配置文件,都要加classpath。如果不是spring的配置文件,就不要加classpath。

4.1 spring整合原生dao的方式

整合思路:

1、SqlSessionFactory对象应该放到spring容器中作为单例存在。

2、传统dao的开发方式中,应该从spring容器中获得sqlsession对象。
3、Mapper代理形式中,应该从spring容器中直接获得mapper的代理对象。
4、数据库的连接以及数据库连接池事务管理都交给spring容器来完成。

5.2整合需要的jar包
1、spring的jar包
2、Mybatis的jar包
3、Spring+mybatis的整合包。
4、Mysql的数据库驱动jar包。
5、数据库连接池的jar包。

5.3整合的步骤
第一步:创建一个java工程。
第二步:导入jar包。(上面提到的jar包)
第三步:mybatis的配置文件sqlmapConfig.xml
第四步:编写Spring的配置文件
1、数据库连接及连接池
2、事务管理(暂时可以不配置)
3、sqlsessionFactory对象,配置到spring容器中
4、mapeer代理对象或者是dao实现类配置到spring容器中。
第五步:编写dao或者mapper文件

第六步:测试。

5.3.1SqlMapConfig.xml
5.3.2applicationContext.xml
5.3.3db.properties

5.4Dao的开发
三种dao的实现方式:
1、传统dao的开发方式
2、使用mapper代理形式开发方式
3、使用扫描包配置mapper代理。

5.4.1传统dao的开发方式
接口+实现类来完成。需要dao实现类需要继承SqlsessionDaoSupport类

5.4.1.1 Dao实现类
5.4.1.2 配置dao

spring整合mybatis,dao方式

4.2 spring整合mapper的方式

applicationContext.xml

<!-- Mapper接口代理实现 -->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
	<!-- 配置mapper接口的全路径名称 -->
	<property name="mapperInterface" value="com.ken.mapper.UserMapper"/>
	<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>

UserMapperTest

private ApplicationContext applicationContext;
	
	@Before
	public void setUp(){
		applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
	}
	
	@Test
	public void testFindUserById(){
		UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper");
		User user = userMapper.findUserById(1);
		System.out.println(user);
	}
}

4.3 批量导入mapper

applicationContext.xml

<!-- 
	使用包扫描的方式批量导入mapper
	扫描后引用的时候可以使用类名,首字母小写
 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
	<!-- 指定要扫描的包的全路径名称。如果有多个包,用应为状态下的逗号分隔 -->
	<property name="basePackage" value="com.ken.mapper"/>
</bean>

UserMapperTest

@Test
public void testFindUserById() {
	UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper");//扫描后引用的时候可以使用类名,首字母小写
	User user = userMapper.findUserById(1);
	System.out.println(user);
}

五、逆向工程

使用官方网站的mapper自动生成工具mybatis-generator-core-1.3.2来生成po类和mapper映射文件。
作用:mybatis官方提供逆向工程,可以使用它通过数据库中的表来自动生成Mapper接口和映射文件(单表增删改查)和Po类.

可以根据表结构自动的生成po类,还可以生成单表的mapper。

5.1 创建mybatis_generator java工程

5.2 导包:

1.这个工程是mybatis的逆向工程,所以要导入mybatis的核心包

2.根据数据库中的表生成po类,所以要连接数据,需要数据库驱动包

3.mybatis逆向工程的jar包

5.3 在工程下创建generator.xml


generator.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
	<context id="testTables" targetRuntime="MyBatis3">
		<commentGenerator>
			<!-- 是否去除自动生成的注释 true:是 : false:否 -->
			<property name="suppressAllComments" value="true" />
		</commentGenerator>
		<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
		<jdbcConnection driverClass="com.mysql.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root"
			password="123456">
		</jdbcConnection>

		<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 
			和 NUMERIC 类型解析为java.math.BigDecimal -->
		<javaTypeResolver>
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver>

		<!-- targetProject:生成PO类的位置 -->
		<javaModelGenerator targetPackage="com.ken.pojo"
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
			<!-- 从数据库返回的值被清理前后的空格 -->
			<property name="trimStrings" value="true" />
		</javaModelGenerator>
		<!-- targetProject:mapper映射文件生成的位置 -->
		<sqlMapGenerator targetPackage="com.ken.mapper"
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</sqlMapGenerator>
		<!-- targetPackage:mapper接口生成的位置 -->
		<javaClientGenerator type="XMLMAPPER"
			targetPackage="com.ken.mapper" targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</javaClientGenerator>
		<!-- 指定数据库表 -->
		<table tableName="orders"></table>
		<table tableName="user"></table>

		<!-- 有些表的字段需要指定java类型 <table schema="" tableName=""> <columnOverride column="" 
			javaType="" /> </table> -->
	</context>
</generatorConfiguration>

5.4 调用类

public class StartServer {
	public void generator() throws Exception {
		List<String> warnings = new ArrayList<String>();
		boolean overwrite = true;
		File configFile = new File("generator.xml");
		ConfigurationParser cp = new ConfigurationParser(warnings);
		Configuration config = cp.parseConfiguration(configFile);
		DefaultShellCallback callback = new DefaultShellCallback(overwrite);
		MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
		myBatisGenerator.generate(null);
	}

	public static void main(String[] args) throws Exception {
		try {
			StartServer startServer = new StartServer();
			startServer.generator();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
5.5 运行->刷新


注意:mybatis逆向工程的生成的代码是追加形式的。如果,重复运行了逆向工程,我们打开类,没问题,但是文件的大小变了。再用这些文件,就没法用。所以,要重新运行,就要把原来生成的文件全部删除。

5.6 使用

将刚刚生成的的mapper和po拷贝到我们之前的工程mybatis_spring对应的包下(把之前包里的文件删除)。


UserMapperTest

@Test
public void testFindUserById() {
	UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper");
	User user = userMapper.selectByPrimaryKey(1);
	System.out.println(user);
}
@Test
public void testFindUserAndSex() {
	UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper");
	// 创建UserExample对象
	UserExample userExample = new UserExample();
	// 通过UserExample对象创建查询条件封装对象(Criteria中是封装的查询条件)
	Criteria criteria = userExample.createCriteria();
	criteria.andUsernameLike("%王%");
	criteria.andSexEqualTo("1");
	List<User> list = userMapper.selectByExample(userExample);
	System.out.println(list);
}

逆向工程代码


逆向工程使用


资源下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值