商品订单数据模型:
一对一查询:
编写映射文件:
<select id="getOrderByUser" resultType="orderuser">
SELECT
o.`id`,
o.`user_id` userId,
o.`number`,
o.`createtime`,
o.`note`,
u.username,
u.address
FROM
`order` o
LEFT JOIN `user` u ON u.id=o.user_id
</select>
编写接口:
/**
* 一对一关联查询
* @return
*/
List<OrderUser> getOrderByUser();
编写测试类:
@Test
public void testGetOrderByUser() {
SqlSessionFactory sqlSessionFactory=SqlSessionFactoryUtils.getSqlSessionFactory();
SqlSession sqlSession=sqlSessionFactory.openSession();
OrderMapper orderMapper=sqlSession.getMapper(OrderMapper.class);
List<OrderUser> list= orderMapper.getOrderByUser();
for (OrderUser orderUser : list) {
System.out.println(orderUser);
}
sqlSession.close();
}
结果:
这样的一对一关联查询是不合理的 因为没有了面向对象的思想,接下来就要用到relustMap。
编写映射:
<resultMap type="order" id="order_user_resultmap">
<!--映射主键的-->
<id property="id" column="id"/>
<!--映射普通字段的-->
<result property="userId" column="user_id"></result>
<result property="number" column="number"></result>
<result property="createtime" column="createtime"></result>
<result property="note" column="note"></result>
<!--用于一对一查询的-->
<association property="user" javaType="com.st.mybatis.pojo.User">
<id property="id" column="user_id"/>
<result property="username" column="username"/>
<result property="address" column="address"/>
</association>
</resultMap>
<select id="getOrderByUserMap" resultMap="order_user_resultmap">
SELECT
o.`id`,
o.`user_id`,
o.`number`,
o.`createtime`,
o.`note`,
u.username,
u.address
FROM
`order` o
LEFT JOIN `user` u ON u.id=o.user_id
</select>
association:用于配置一对一关系
property:order里面的User属性
javaType:user的数据类型,支持别名
编写接口:
/**
* 一对一关联查询的resultmap使用
*/
List<Order> getOrderByUserMap();
编写测试类:
扫描二维码关注公众号,回复:
10558879 查看本文章
@Test
public void testGetOrderByUserMap() {
SqlSessionFactory sqlSessionFactory=SqlSessionFactoryUtils.getSqlSessionFactory();
SqlSession sqlSession=sqlSessionFactory.openSession();
OrderMapper orderMapper=sqlSession.getMapper(OrderMapper.class);
List<Order> list= orderMapper.getOrderByUserMap();
for (Order order : list) {
System.out.println(order);
System.out.println("这个订单用户为:"+order.getUser());
}
sqlSession.close();
}
结果:
一对多关联查询:
编写映射:
<resultMap id="order_oder_map" type="user">
<!--主键-->
<id property="id" column="id"/>
<!--配置普通字段映射-->
<result property="username" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<result property="uuid1" column="uuid1"/>
<!--配置一对多的查询-->
<collection property="orders" ofType="com.st.mybatis.pojo.Order">
<id property="id" column="oid"/>
<!--<result property="userId" column="user_id"></result>-->
<result property="number" column="number"></result>
<result property="createtime" column="createtime"></result>
<result property="note" column="note"></result>
</collection>
</resultMap>
<select id="getUserOrderMap" resultMap="order_oder_map">
SELECT
u.`id`,
u.`username`,
u.`birthday`,
u.`sex`,
u.`address`,
u.`uuid1`,
o.`id` oid,
o.`number`,
o.`createtime`,
o.`note`
FROM
`user` u
LEFT JOIN `order` o
ON o.`user_id`=u.`id`
</select>
collection:这个是一对多的语法
编写接口:
/**
* 一对多关联查询resultmap使用
*/
List<User> getUserOrderMap();
编写测试类:
@Test
public void testGetUserOrderMap() {
SqlSessionFactory sesessionfactory=SqlSessionFactoryUtils.getSqlSessionFactory();
SqlSession sqlsession=sesessionfactory.openSession();
UserMapper userMapper=sqlsession.getMapper(UserMapper.class);
List<User> list=userMapper.getUserOrderMap();
for (User user1 : list) {
System.out.println(user1);
for (Order order : user1.getOrders()) {
if(order.getId()!=null) {
System.out.println("此用户下的订单有:"+order);
}
}
}
sqlsession.close();
}
结果与数据库查询结果一致:
Mybats整合Spring
整合思路:
- SqlSessionFactory对象应该放到Spring容器中作为单列存在。
- 传统dao的开发方式中,应该从Spring容器中获得sqlsession对象
- Mapper代理形式中,应该从Spring容器中直接获得mapper的代理对象。
- 数据库的链接以及数据库连接池事务管理交给spring容器管理
整合步骤:
- 创建一个Java工程
- 导入jar包
- mybatis的配置文件sqlapConfig.xml
- 编写Spring的配置文件
数据库链接及连接池
sqlsessionFactory对象,配置到spring容器中
编写spring的配置文件 - 复制jdbc.properties配置文件到新工程
- 复制log4.propertiies配置文件到新工程
applicationConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath:jdbc.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>
<!--sqlSessionFactory配置-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!--加载mybatis核心配置文件-->
<property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
<!--配置别名 包扫描器-->
<property name="typeAliasesPackage" value="com.st.mybatis.pojo"></property>
</bean>
<!--传统Dao配置-->
<bean class="com.st.mybatis.dao.impl.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>
传统Dao开发:
- 复制user.xml到新工程,并修改,只留下要测试的三个方法
- 在SqlMapConfig.xml加载user.xml
- 复制UserDao接口到新工程,并修改,只留下要测试的三个方法
- 编写UserDaoImpl实现类,关键是继承SqlSessionDaoSupport
编写user.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"D://mybatis-dtd/dtd/mybatis-3-mapper.dtd">
<!--命名空间,用于隔离sql-->
<mapper namespace="user">
<!--
id: sql语句执行的唯一标识
parameterType: 入参的类型
resultType: 返回结果的数据类型
#{}:是一个占位符 相当于jdbc的?
'%${value}%'字符串拼接指令
-->
<select id="getUserById" parameterType="int" resultType="com.st.mybatis.pojo.User">
SELECT
`id`,
`username`,
`birthday`,
`sex`,
`address`
FROM `user`
WHERE id=#{id}
</select>
<select id="getUserByUsername" parameterType="String" resultType="com.st.mybatis.pojo.User">
SELECT
`id`,
`username`,
`birthday`,
`sex`,
`address`
FROM `user`
<!--WHERE username LIKE #{name} -->
where username like '%${value}%'
</select>
<!--
selectKey:主键返回
keyProperty:user的主键
result:主键的数据类型
order:指定selectKey在什么时候执行/fater之后
-->
<!--
useGeneratedKeys:使用自增 与keyProperty配套使用.
keyProperty:user主键
-->
<insert id="inserUser" parameterType="com.st.mybatis.pojo.User" useGeneratedKeys="true" keyProperty="id">
<!--
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
-->
INSERT INTO `user` (
`username`,
`birthday`,
`sex`,
`address`
)
VALUES
(
#{username},
#{birthday},
#{sex},
#{address}
);
</insert>
<insert id="inserUserUUID" parameterType="com.st.mybatis.pojo.User" useGeneratedKeys="true" keyProperty="id">
<selectKey keyProperty="uuid1" resultType="String" order="BEFORE">
SELECT UUID()
</selectKey>
INSERT INTO `user` (
`username`,
`birthday`,
`sex`,
`address`,
`uuid1`
)
VALUES
(
#{username},
#{birthday},
#{sex},
#{address},
#{uuid1}
);
</insert>
<update id="updateUserById" parameterType="com.st.mybatis.pojo.User">
UPDATE
`user`
SET
`username` = #{username},
`address` = #{address}
WHERE `id` = #{id};
</update>
<delete id="deleteUserById" parameterType="int" >
DELETE
FROM
`user`
WHERE `id` = #{id};
</delete>
</mapper>
接口:
package com.st.mybatis.dao;
import java.util.List;
import com.st.mybatis.pojo.User;
public interface UserDao {
//根据用户ID查询用户信息
User getUserById(Integer id);
//根据用户姓名查找用户列表
List<User> getUserByUsername(String userName);
//添加用户
void insertUser(User user);
}
编写实现类:
package com.st.mybatis.dao.impl;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import com.st.mybatis.dao.UserDao;
import com.st.mybatis.pojo.User;
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
@Override
public User getUserById(Integer id) {
SqlSession sqlSession=super.getSqlSession();
User user=sqlSession.selectOne("user.getUserById", id);
return user;
}
@Override
public List<User> getUserByUsername(String userName) {
SqlSession sqlSession=super.getSqlSession();
List<User> userlist=sqlSession.selectList("user.getUserByUsername",userName);
return userlist;
}
@Override
public void insertUser(User user) {
SqlSession sqlSession=super.getSqlSession();
sqlSession.selectList("user.inserUser",user);
}
}
配置Dao:
编写测试类:
package com.st.mybatis.test;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.st.mybatis.dao.UserDao;
import com.st.mybatis.pojo.User;
public class UserDaoTest {
private ApplicationContext applicationContext;
@Before
public void init() {
applicationContext=new ClassPathXmlApplicationContext("classpath:applicationConfig.xml");
}
@Test
public void testGetUserById() {
UserDao dao=applicationContext.getBean(UserDao.class);
User user=dao.getUserById(10);
System.out.println(user);
}
@Test
public void testGetUserByUsername() {
fail("Not yet implemented");
}
@Test
public void testInsertUser() {
fail("Not yet implemented");
}
}
输出查询结果:
Mapper动态代理Dao开发:
- 复制UserMapper.xml到新工程,并修改,只留下要测试的三个方法
- 复制UserMapper接口到新工程,并修改,只留下要测试的三个方法
- 配置Mapper
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"D://mybatis-dtd/dtd/mybatis-3-mapper.dtd">
<!--
动态代理开发规则:
1.namespace必需是接口的全路径名
2.接口的方法名必须与sql id一致
3.接口的入参与parameterType类型一致
4.接口的返回值必须与resultType类型一致
-->
<!--命名空间,用于隔离sql-->
<mapper namespace="com.st.mybatis.mapper.UserMapper">
<!--
id: sql语句执行的唯一标识
parameterType: 入参的类型
resultType: 返回结果的数据类型
#{}:是一个占位符 相当于jdbc的?
'%${value}%'字符串拼接指令
-->
<select id="getUserById" parameterType="int" resultType="usEr">
SELECT
`id`,
`username`,
`birthday`,
`sex`,
`address`
FROM `user`
WHERE id=#{id}
</select>
<select id="getUserByUsername" parameterType="String" resultType="com.st.mybatis.pojo.User">
SELECT
`id`,
`username`,
`birthday`,
`sex`,
`address`
FROM `user`
<!--WHERE username LIKE #{name} -->
where username like '%${value}%'
</select>
<!--
selectKey:主键返回
keyProperty:user的主键
result:主键的数据类型
order:指定selectKey在什么时候执行/fater之后
-->
<!--
useGeneratedKeys:使用自增 与keyProperty配套使用.
keyProperty:user主键
-->
<insert id="inserUser" parameterType="com.st.mybatis.pojo.User" useGeneratedKeys="true" keyProperty="id">
<!--
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
-->
INSERT INTO `user` (
`username`,
`birthday`,
`sex`,
`address`
)
VALUES
(
#{username},
#{birthday},
#{sex},
#{address}
);
</insert>
</mapper>
UserMapper.java
package com.st.mybatis.mapper;
import java.util.List;
import com.st.mybatis.pojo.User;
public interface UserMapper {
//根据用户ID查询用户信息
User getUserById(Integer id);
//根据用户姓名查找用户列表
List<User> getUserByUsername(String userName);
//添加用户
void inserUser(User user);
}
第一种方式:
applicationConfig.xml
<!--动态代理模式 第一种方式-->
<bean id="baseMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" abstract="true" lazy-init="true">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<!--开启接口扫描-->
<bean id="oneMapper" parent="baseMapper">
<property name="mapperInterface" value="com.st.mybatis.mapper.UserMapper" />
</bean>
编写测试类:
/**
* 加载配置容器
*/
private ApplicationContext applicationContext;
@Before
public void init() {
applicationContext=new ClassPathXmlApplicationContext("classpath:applicationConfig.xml");
}
@Test
public void testGetUserById() {
UserMapper userMapper=applicationContext.getBean(UserMapper.class);
User user=userMapper.getUserById(10);
System.out.println(user);
}
结果:
第一种需要配置多个接口.
第二种:推荐使用
<!--动态代理第二种方式:包扫描 (推荐)-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.st.mybatis.mapper"></property>
</bean>
编写测试类:
运行结果:
逆向工程:
mybatis逆向工程:
可以去官网下载:
jar包:
<?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.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useSSL=false&suseSSL=true" userId="root"
password="123456">
</jdbcConnection>
<!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg"
userId="yycg"
password="yycg">
</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.st.ssm.po"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.st.ssm.mapper"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.st.ssm.mapper"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<table schema="" tableName="user"></table>
<table schema="" tableName="orders"></table>
<!-- 有些表的字段需要指定java类型
<table schema="" tableName="">
<columnOverride column="" javaType="" />
</table> -->
</context>
</generatorConfiguration>
执行main方法:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;
public class GeneratorSqlmap {
public void generator() throws Exception{
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
//指定 逆向工程配置文件
File configFile = new File("generatorConfig.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 {
GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap();
generatorSqlmap.generator();
} catch (Exception e) {
e.printStackTrace();
}
}
}
刷新项目 可以看到自动生成了.:
引入包:
其他测试方法和用法基本和正常查询一致.略。