根据用户ID查询用户信息
public class MybatisTest {
@Test
public void TestGetUserById() throws Exception {
//SqlSessionFactoryBuilder这个类可以加载核心配置文件
//创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
//创建核心配置文件的输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//通过输入流创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = ssfb.build(inputStream);
//创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行查询,参数一:sql id 参数二:入参
User user = sqlSession.selectOne("user.getUserById", 1);
//输出结果
System.out.println(user);
//释放资源
sqlSession.close();
}
}
<?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">
<!--namespace:命名空间,用于隔离sql语句,后继有重要作用
#{}:占位符,相当于jdbc的?
${}:字符串拼接指令,如果入参为普通类型{}内部只能写value
-->
<mapper namespace="user">
<!--id:sql id,语句的唯一标识
parameterType:入参的数据类型
resultType:返回结果的数据类型
-->
<select id = "getUserById" parameterType="int" resultType="com.itheima.mybatis.pojo.User">
SELECT
*
FROM `user`
WHERE id = #{id2}
</select>
</mapper>
<!-- resultType:如果返回结果为集合,只需设置为每一个的数据类型-->
1.导入依赖jar包
2.配置SqlMapConfig.xml
3.配置log4j.properties
4.pojo
5.配置sql查询的映射文件,user.xml
<mapper namespace="user">
</mapper>
6.SqlMapConfig加载映射文件:
<mappers>
<mapper resource="mybatis/user.xml"/>
</mappers>
需求完成步骤:
1.编写sql语句
2.配置user关系映射文件
3.编写测试程序
每一次都要加载一次配置文件,于是抽取出来编写一个工具类:
SqlSessionFactoryUtils.java:
public class SqlSessionFactoryUtils {
private static SqlSessionFactory sqlSessionFactory;
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
static {
try {
// 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
// 创建核心配置文件的输入流
InputStream inputStream;
inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 通过输入流创建SqlSessionFactory对象
sqlSessionFactory = ssfb.build(inputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Test
public void testGetUserByUserName() {
//获取SqlSessionFactory
SqlSessionFactory sqlSessionFactory=SqlSessionFactoryUtils.getSqlSessionFactory();
//创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//List<User> list = sqlSession.selectList("user.getUserByUserName", "%张%");
List<User> list = sqlSession.selectList("user.getUserByUserName", "张");
for (User user : list) {
System.out.println(user);
}
//释放资源
sqlSession.close();
}
<!--resultType:如果返回结果为集合,只需设置为每一个的数据类型 -->
<select id = "getUserByUserName" parameterType="string" resultType="com.itheima.mybatis.pojo.User">
SELECT
*
FROM `user`
<!-- WHERE username LIKE #{name} -->
WHERE username like '%${value}%'
</select>
插入用户:
<!--插入用户 -->
<!--useGeneratedKeys:使用自增 keyProperty与之配套使用,这里是user的主键 -->
<insert id="insertUser" parameterType="com.itheima.mybatis.pojo.User" useGeneratedKeys="true" keyProperty="id">
<!--selectKey:主键返回
keyProperty:user中的主键属性
resultType:主键数据类型
order:指定selectKey何时执行,AFTER之后
-->
<!-- <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>
@Test
public void testInsertUser() {
//获取SqlSessionFactory
SqlSessionFactory sqlSessionFactory=SqlSessionFactoryUtils.getSqlSessionFactory();
//创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//List<User> list = sqlSession.selectList("user.getUserByUserName", "%张%");
User user = new User();
user.setUsername("张飞4");
user.setSex("1");
user.setBirthday(new Date());
user.setAddress("深圳黑马");
sqlSession.insert("user.insertUser", user);
System.out.println(user);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
Mybatis Dao开发方式
Dao需求:根据用户ID查询用户信息
根据用户名查找用户列表
添加用户
原始Dao开发方式:
1.编写user映射文件
User getUserById(Integer id);
2.新建UserDao接口
3.新建UserDaoImpl接口实现类
4.使用dao测试
接口动态代理,
动态代理dao开发规则:
1.namespace必须是接口的全路径名
2.接口的方法名必须与映射文件的sql id一致
3.接口的输入参数必须与映射文件的parameterType类型一致
4.接口的返回类型必须与映射文件的resultType类型一致
1.创建UserMapper.xml映射文件
<?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">
<!--namespace:命名空间,用于隔离sql语句,后继有重要作用
#{}:点位符,相当于jdbc的?
${}:字符串拼接指令,如果入参为普通类型{}内部只能写value
-->
<!--动态代理开发规则:
1.namespace必需是接口的全路径名
2.接口的方法名必需与sql id一致
3.接口的入参与parameterType类型一致
4.接口的返回值必须与resultType类型一致
-->
<mapper namespace="com.itheima.mybatis.mapper.UserMapper">
<!--id:sql id,语句的唯一标识
parameterType:入参的数据类型
resultType:返回结果的数据类型
-->
<select id = "getUserById" parameterType="int" resultType="user">
SELECT
*
FROM `user`
WHERE id = #{id2}
</select>
<!--resultType:如果返回结果为集合,只需设置为每一个的数据类型 -->
<select id = "getUserByUserName" parameterType="string" resultType="com.itheima.mybatis.pojo.User">
SELECT
*
FROM `user`
<!-- WHERE username LIKE #{name} -->
WHERE username like '%${value}%'
</select>
<!--插入用户 -->
<!--useGeneratedKeys:使用自增 keyProperty与之配套使用,这里是user的主键 -->
<insert id="insertUser" parameterType="com.itheima.mybatis.pojo.User" useGeneratedKeys="true" keyProperty="id">
<!--selectKey:主键返回
keyProperty:user中的主键属性
resultType:主键数据类型
order:指定selectKey何时执行,AFTER之后
-->
<!-- <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>
2.创建UserMapper接口:
package com.itheima.mybatis.mapper;
import java.util.List;
import com.itheima.mybatis.pojo.User;
public interface UserMapper {
/**
* 根据用户ID查询用户信息
* @param id
* @return
*/
User getUserById(Integer id);
List<User> getUserByUserName(String userName);
void insertUser(User user);
}
3.加载UserMapper.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>
<!--先加载内部标签,再加载外部文件,名称一致时,会替换内容 -->
<properties resource="jdbc.properties">
<property name="jdbc.username" value="root1"/>
<property name="jdbc.password" value="root"/>
</properties>
<typeAliases>
<!--单个别名定义,别名的使用,不区分大小写 -->
<!-- <typeAlias type="com.itheima.mybatis.pojo.User" alias="user"/> -->
<!--别名包扫描器:别名是类的全称,不区分大小写,推荐方式 -->
<package name="com.itheima.mybatis.pojo"/>
</typeAliases>
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!--加载映射文件 -->
<mappers>
<mapper resource="mybatis/user.xml"/>
<!-- <mapper resource="mybatis/UserMapper.xml"/> -->
<!--映射文件:class扫描器:
1.接口文件必须与映射文件同一目录下
2.接口文件名称必须与映射文件的名称一致
-->
<!-- <mapper class="com.itheima.mybatis.mapper.UserMapper"/> -->
<!--映射文件包扫描 ,推荐方式:
1.接口文件必须与映射文件同一目录下
2.接口文件名称必须与映射文件的名称一致
-->
<package name="com.itheima.mybatis.mapper"/>
</mappers>
</configuration>
4.测试动态代理Dao
package com.itheima.mybatis.test;
import java.util.Date;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import com.itheima.mybatis.mapper.UserMapper;
import com.itheima.mybatis.pojo.User;
import com.itheima.mybatis.utils.SqlSessionFactoryUtils;
public class UserMapperTest {
@Test
public void testGetUserById() {
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
//获取接口的代理人实现类,getMapper底层是反射和动态代理
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUserById(30);
System.out.println(user);
sqlSession.close();
}
@Test
public void testGetUserByUserName() {
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
//获取接口的代理人实现类
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> list = userMapper.getUserByUserName("张");
for (User user : list) {
System.out.println(user);
}
sqlSession.close();
}
@Test
public void testInsertUser() {
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
//获取接口的代理人实现类
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("赵子龙");
user.setSex("1");
user.setBirthday(new Date());
user.setAddress("深圳黑马");
userMapper.insertUser(user);
sqlSession.commit();
sqlSession.close();
}
}
jdbc.properties:
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
ResultMap定义:
OrderMapper.xml
<mapper namespace="com.itheima.mybatis.mapper.OrderMapper">
<select id="getOrderList" resultType="order">
SELECT
`id`,
`user_id` userId,
`number`,
`createtime`,
`note`
FROM
`order`
</select>
<!-- resultMap定义 -->
<resultMap type="order" id="order_list_map">
<!--<id>用于映射主键 -->
<id property="id" column="id"/>
<!--普通字段用<result>映射 -->
<result property="userId" column="user_id"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
</resultMap>
<!--使用resultMap -->
<select id="getOrderListMap" resultMap="order_list_map">
SELECT
`id`,
`user_id`,
`number`,
`createtime`,
`note`
FROM
`order`
</select>
<resultMap type="order" id="order_user_map">
<!--<id>用于映射主键 -->
<id property="id" column="id"/>
<!--普通字段用<result>映射 -->
<result property="userId" column="user_id"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
<!--association用于配置一对一关系
property:order里面的User属性
javaType:user的数据类型,支持别名
-->
<association property="user" javaType="com.itheima.mybatis.pojo.User">
<id property="id" column="user_id"/>
<result property="username" column="username"/>
<result property="address" column="address"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
</association>
</resultMap>
<!--一对一关联查询: resultType使用 -->
<select id="getOrderUserMap" resultMap="order_user_map">
SELECT
o.`id`,o.`user_id`,o.`number`,o.`createtime`,o.`note`,u.`username`,u.`address`
,u.`birthday`,u.`sex`
FROM `order` o
LEFT JOIN `user` u
ON u.`id` = o.`user_id`
</select>
</mapper>
UserMapper.xml:
<?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">
<!--namespace:命名空间,用于隔离sql语句,后继有重要作用
#{}:点位符,相当于jdbc的?
${}:字符串拼接指令,如果入参为普通类型{}内部只能写value
-->
<!--动态代理开发规则:
1.namespace必需是接口的全路径名
2.接口的方法名必需与sql id一致
3.接口的入参与parameterType类型一致
4.接口的返回值必须与resultType类型一致
-->
<mapper namespace="com.itheima.mybatis.mapper.UserMapper">
<!--sql片段的抽取,定义 -->
<sql id="user_sql">
`id`,
`username`,
`birthday`,
`sex`,
`address`
</sql>
<!--id:sql id,语句的唯一标识
parameterType:入参的数据类型
resultType:返回结果的数据类型
-->
<select id = "getUserById" parameterType="int" resultType="user">
SELECT
<!--sql片段使用:refid引用定义好的sql片段id -->
<include refid="user_sql"></include>
FROM `user`
WHERE id = #{id2}
</select>
<!--resultType:如果返回结果为集合,只需设置为每一个的数据类型 -->
<select id = "getUserByUserName" parameterType="string" resultType="com.itheima.mybatis.pojo.User">
SELECT
*
FROM `user`
<!-- WHERE username LIKE #{name} -->
WHERE username like '%${value}%'
</select>
<!--插入用户 -->
<!--useGeneratedKeys:使用自增 keyProperty与之配套使用,这里是user的主键 -->
<insert id="insertUser" parameterType="com.itheima.mybatis.pojo.User" useGeneratedKeys="true" keyProperty="id">
<!--selectKey:主键返回
keyProperty:user中的主键属性
resultType:主键数据类型
order:指定selectKey何时执行,AFTER之后
-->
<!-- <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>
<!--第二天开始 -->
<!--resultType:如果返回结果为集合,只需设置为每一个的数据类型 -->
<select id = "getUserByQueryVo" parameterType="queryvo" resultType="com.itheima.mybatis.pojo.User">
SELECT
*
FROM `user`
<!-- WHERE username LIKE #{name} -->
WHERE username like '%${user.username}%'
</select>
<!--resultType:如果返回结果为集合,只需设置为每一个的数据类型 -->
<select id = "getUserByPojo" parameterType="user" resultType="com.itheima.mybatis.pojo.User">
SELECT
*
FROM `user`
<!-- WHERE username LIKE #{name} -->
<!-- WHERE 1=1
<if test="username!=null and username!=''">
and username LIKE '%${username}%'
</if>
<if test="sex!=null and sex!=''">
and sex = #{sex}
</if> -->
<!--<where>自动补上where关键字,同时处理多余and -->
<where>
<if test="username!=null and username!=''">
and username LIKE '%${username}%'
</if>
<if test="sex!=null and sex!=''">
and sex = #{sex}
</if>
</where>
</select>
<select id="getUserByIds" parameterType="queryvo" resultType="user">
SELECT
<include refid="user_sql"></include>
FROM
`user`
<where>
<!--foreach循环标签
collection:要遍历的集合
open:循环开始之前输出的内容
item:设置循环变量
separator:分隔符
close:循环结束之后输出的内容
-->
<!--目的:id IN(1,25,29,30,35) -->
<foreach collection="ids" open="id IN(" item="uId" separator="," close=")">
#{uId}
</foreach>
</where>
</select>
<resultMap type="user" id="user_order_map">
<id property="id" column="id" />
<result property="username" column="username" />
<result property="address" column="address" />
<result property="birthday" column="birthday" />
<result property="sex" column="sex" />
<!--collection用于配置一对多关联
property:User当中Order的属性
ofType:orders的数据类型,支持别名
-->
<collection property="orders" ofType="order">
<id property="id" column="oid"/>
<!--普通字段用<result>映射 -->
<!-- <result property="userId" column="id"/> -->
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
</collection>
</resultMap>
<select id="getUserOrderMap" resultMap="user_order_map">
SELECT
u.`id`,u.`username`,u.`birthday`,u.`sex`,u.`address`,u.`uuid2`,o.`id` oid,o.`number`,o.`createtime`,o.`note`
FROM `user` u
LEFT JOIN `order` o ON o.`user_id`=u.`id`
</select>
</mapper>
@Test
public void testGetUserByIds() {
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
//获取接口的代理人实现类
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
QueryVo vo = new QueryVo();
//构建id列表
vo.setIds(Arrays.asList(1,25,29,30,35));
List<User> list = userMapper.getUserByIds(vo);
for(User user:list) {
System.out.println(user);
}
sqlSession.close();
}
Mybatis整合spring:
整合思路:
1.SqlSessionFactory对象应该放到spring容器中作为单例存在
2.传统dao的开发方式中,应该从spring容器中活得sqlSession对象
3.Mapper代理形式中,应该从spring容器中直接获得mapper的代理对象
4.数据库的连接以及数据库连接池事务管理都交给spring容器来完成
整合步骤:
1.导入jar包
2.mybatis的配置文件sqlmapConfig.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>
<mappers>
<mapper resource="mybatis/user.xml"></mapper>
</mappers>
</configuration>
3.编写spring的配置文件
数据库连接及连接池;sqlsessionFactory对象,配置到spring容器中;编写spring的配置文件
applicationContext.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>
<!--SqlSessinFactory配置 -->
<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.itheima.mybatis.pojo"></property>
</bean>
<!--传统Dao配置 -->
<bean class="com.itheima.mybatis.dao.impl.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
<!--动态代理配置方式:第一种 -->
<!-- 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.itheima.mybatis.mapper.UserMapper" />
</bean> -->
<!--动态代理,第二种方式:包扫描(推荐) -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.mybatis.mapper"></property>
</bean>
</beans>
4.测试:
public class UserDaoTest {
private ApplicationContext applicationContext;
@Before
public void init() {
applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
}
@Test
public void testGetUserById() {
UserDao userDao = applicationContext.getBean(UserDao.class);
User user = userDao.getUserById(30);
System.out.println(user);
}
}
public class UserMapperTest {
private ApplicationContext applicationContext;
@Before
public void init() {
applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
}
@Test
public void testGetUserById() {
UserMapper userMapper = applicationContext.getBean(UserMapper.class);
User user=userMapper.getUserById(30);
System.out.println(user);
}
}