一、MyBatis简介
Mybatis是面向sql的持久层框架,类似于Hibernate,它封装了jdbc访问数据库的过程,我们开发过程中,只需专注于sql语句本身的拼装,其它复杂的过程全部可以交给mybatis去完成。
二、MyBatis入门
1. 导入依赖jar包
2. 配置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>
<!-- 和spring整合后 environments配置将废除 -->
<!-- default默认哪个id就执行那个 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/hibernate?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="19960213zx" />
</dataSource>
</environment>
</environments>
3. 配置log4j.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
4. 创建实体
package pers.zx.mybatis.demo;
import java.util.Date;
public class User {
private Integer id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="+ address + "]";
}
}
5. 配置映射文件
<?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语句
#{}:相当于占位符
-->
<mapper namespace="user">
<!-- id: sql id,语句的唯一标识
parameterType:输入参数的数据类型,比如要查询id=1的人,1是int型的
resultType:返回结果的数据类型
-->
<select id="getUserById" parameterType="int" resultType="pers.zx.mybatis.demo.User">
SELECT * FROM USER WHERE id = #{id1}
</select>
</mapper>
6. 在SqlMapConfig.xml中加载映射文件
//在</environments>后面
<!-- 配置映射文件 -->
<mappers>
<mapper resource="mybatis/User.xml"/>
</mappers>
7.编写测试类
public class MybatisTest {
@Test
public void test() throws IOException {
//创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
//创建核心配置文件的输入流
InputStream inputStream=Resources.getResourceAsStream("SqlMapConfig.xml");
//通过输入流创建SqlSessionFactory对象
SqlSessionFactory factory=builder.build(inputStream);
//创建SqlSession对象
SqlSession session=factory.openSession();
//执行查询
User user=session.selectOne("user.getUserById",1);
System.out.println(user);
session.close();
}
}
三、例子测试
1.模糊查询
(1)抽取工具类
public class SqlSessionUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
//创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
//创建核心配置文件的输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//通过输入流创建SqlSessionFactory对象
sqlSessionFactory=builder.build(inputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}
(2)编写User.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语句
#{}:相当于占位符
${}:字符串拼接符,如果是对象则直接放对象的名称,如果是其他类型都放value
-->
<mapper namespace="user">
<!-- id: sql id,语句的唯一标识
parameterType:输入参数的数据类型,比如要查询id=1的人,1是int型的
resultType:返回结果的数据类型
-->
<select id="getUserByName" parameterType="String" resultType="pers.zx.mybatis.demo.User">
SELECT * FROM user WHERE username LIKE '%${value}%'
</select>
</mapper>
(3)测试方法
@Test
public void test1() {
SqlSession session=SqlSessionUtils.getSqlSession();
List<User> list=session.selectList("user.getUserByName", "张");
for (User user : list) {
System.out.println(user);
}
}
2.插入
(1)测试代码:注意要提交事务
@Test
public void test2() {
SqlSession session=SqlSessionUtils.getSqlSession();
User user=new User();
user.setUsername("zx");
user.setSex("男");
user.setBirthday(new Date());
user.setAddress("fhakhfkafah");
session.insert("user.insertUser", user);
//提交事务
session.commit();
session.close();
}
(2)use.xml
<!-- 插入实体parameterType="pers.zx.mybatis.demo.User" -->
<insert id="insertUser" parameterType="pers.zx.mybatis.demo.User">
INSERT INTO user(username,birthday,sex,address) values(
#{username},
#{birthday},
#{sex},
#{address}
);
</insert>
3.获得主键
<!-- 插入实体 -->
<!--方式一: useGeneratedKeys="true"使用自增,可以执行获取id的语句 keyProperty="id"获取的id -->
<insert id="insertUser" parameterType="pers.zx.mybatis.demo.User" useGeneratedKeys="true" keyProperty="id" >
<!-- 方式二:
selectKey :主键返回
keyProperty:user中的主键属性
resultType:主键的数据类型
order:指定selectKey何时执行,after之后(insert之后)
-->
<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>
四、Mybatis体系架构
mybatis是一个基于sql的持久层框架,关键在于核心配置文件以及mapper映射文件,在执行过程中,它会先创建一个SqlSessionFactory工厂,然后利用SqlSession创建session对象,在session对象中有个具体的执行者executor,其里面含有一个MappedStatement来对数据库进行具体的输入输出映射,所以就可以通过这个session来完成对数据库的操作。
五、传统的dao层
1.UserDao
package pers.zx.mybatis.dao;
public interface UserDao {
void insertUser();
}
2.UserDaoImpl
public class UserDaoImpl implements UserDao{
@Override
public void insertUser() {
// TODO Auto-generated method stub
SqlSessionFactory sqlSessionFactory=SqlSessionUtils.getSqlSessionFactory();
SqlSession sqlSession=sqlSessionFactory.openSession(true);
User user=new User();
user.setUsername("zxxx");
user.setSex("男");
user.setBirthday(new Date());
user.setAddress("fhakhfkafah");
sqlSession.insert("user.insertUser", user);
sqlSession.close();
}
}
3.测试类
@Test
public void test3() {
UserDao userDao=new UserDaoImpl();
userDao.insertUser();
}
六、动态代理dao
1.动态代理dao开发规则
1.namespace必需是接口的全路径名
2.接口的方法名必需与映射文件的sql id一致
3.接口的输入参数必需与映射文件的parameterType类型一致
4.接口的返回类型必须与映射文件的resultType类型一致
注意:动态代理只有一个接口没有具体的实现
2.Mapper
package pers.zx.mybatis.mapper;
import pers.zx.mybatis.demo.User;
public interface Mapper {
void insertUser(User user);
}
3.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>
<!-- 和spring整合后 environments配置将废除 -->
<!-- default默认哪个id就执行那个 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql:///hibernate" />
<property name="username" value="root" />
<property name="password" value="19960213zx" />
</dataSource>
</environment>
</environments>
<!-- 配置映射文件 -->
<mappers>
<mapper resource="mybatis/mapper.xml"/>
</mappers>
</configuration>
4.mapper.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">
<mapper namespace="pers.zx.mybatis.mapper.Mapper">
<!--id是Mapper接口中的方法名,parametType是
输入参数的类型
-->
<insert id="insertUser" parameterType="pers.zx.mybatis.demo.User" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO user(username,birthday,sex,address) values(
#{username},
#{birthday},
#{sex},
#{address}
);
</insert>
</mapper>
5.测试方法
@Test
public void test4() {
SqlSession sqlSession=SqlSessionUtils.getSqlSessionFactory().openSession(true);
//获取接口的代理类
Mapper mapper=sqlSession.getMapper(Mapper.class);
User user=new User();
user.setUsername("1");
user.setSex("2");
user.setBirthday(new Date());
user.setAddress("3");
mapper.insertUser(user);
}
七、SqlMapConfig.xml
文件的配置顺序要按照下图,否则会报错
1.配置属性
属性会先加载内部标签,然后再加载外部标签,属性相同时,外部标签会覆盖内部标签
<properties resource="jdbc.properties">
<property name="jdbc.username" value="root1"/>
<property name="jdbc.password" value="123453"/>
</properties>
完整配置文件
<?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="root2"/>
</properties>
<!-- 和spring整合后 environments配置将废除 -->
<!-- default默认哪个id就执行那个 -->
<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/mapper.xml"/>
</mappers>
</configuration>
2.定义别名
<typeAliases>
<!-- 单个别名定义 -->
<!-- <typeAlias type="pers.zx.mybatis.domain.User" alias="user"/> -->
<!-- 别名包扫描器(推荐使用此方式),整个包下的类都被定义别名,别名为类名,不区分大小写-->
<package name="pers.zx.mybatis.domain"/>
</typeAliases>
通过别名配置,在相应的映射类中使用。
4.mappers
<mappers>
<!-- 第一种方式,加载 resource,传统dao只能用这种-->
<mapper resource="mybatis/user.xml"/>
<!-- <mapper resource="mybatis/Mapper.xml"/> -->
<!-- 第二种方式,class扫描器要求:
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致
-->
<!-- <mapper class="pers.zx.mybatis.mapper.Mapper"/> -->
<!-- 第三种方式,包扫描器要求(推荐使用此方式):
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致
-->
<package name="pers.zx.mybatis.mapper"/>
他们是具体如何找到相应的类的,根据包中类的名字或别名。
八、小结
首先,mybatis有两种操作实体的方式,第一种是传统的dao,第二种是动态代理dao,动态代理dao,只需要一个接口类相应的方法,然后配置mapper映射文件,此时映射文件的的命名空间是接口的全类名,其中的id要和接口中相应的方法同名。接口的输入参数要和接口中定义的一致,返回类型也要一致。
然后具体的操作在实现类里面写。
mybatis需要实体类,实体的映射文件,核心配置文件,实现类。
如果需要配置包扫描则需要将实体类和实体的映射文件放到同一个包下,且名称一样。具体要找的时候它会更具具体在包中配置的类名或者在核心配置文件中配置的别名去找。
实体映射文件< mapper>中有id=””,paramterType=””,resultType=””
我们以动态dao为例:id接口中方法名,paramterType输入的参数类型,resultType返回结果类型。
SqlMapConfig:< properties>属性、< environments>数据库配置、< mappping>映射文件位置
九、输入输出映射
1.包装的pojo
所谓的包装的pojo就是在实体中还有实体。
这时在配置文件中所配置的属性就是包装类的属性。被包装的类.属性名
<mapper namespace="pers.zx.mybatis.mapper.Mapper">
<select id="getPojo" parameterType="pers.zx.mybatis.demo.Pojo" resultType="pers.zx.mybatis.demo.User">
<!-- user是pojo中包装的实体 -->
SELECT * FROM USER WHERE username LIKE '%${user.username}%'
</select>
</mapper>
2.resultMap
防止表中字段与实体中的字段不一致。
<mapper namespace="pers.zx.mybatis.mapper.Ordermapper">
<!-- resultMap入门
type:映射成的pojo类型
id:resultMap唯一标识
-->
<resultMap type="pers.zx.mybatis.demo.Order" id="orderMap">
<!-- 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="getOrderListResultMap" resultMap="orderMap">
select * from `order`;
</select>
十、动态标签的使用
1.if标签
<!-- 演示动态sql-if标签的使用情景 -->
<select id="getUserByWhere" parameterType="pers.zx.mybatis.demo.User" resultType="pers.zx.mybatis.demo.User">
<!-- SELECT * FROM USER WHERE username LIKE '%${username}%' and id = #{id} -->
SELECT * FROM USER where 1 = 1
<!-- if标签的使用 -->
<if test="id != null">
and id = #{id}
</if>
<if test="username != null and username != ''">
and username LIKE '%${username}%'
</if>
</select>
2.where标签
<!-- 演示动态sql-where标签的使用情景 -->
<select id="getUserByWhere2" parameterType="pers.zx.mybatis.demo.User"
resultType="pers.zx.mybatis.demo.User">
<!-- include:引入sql片段,refid引入片段id -->
SELECT
*
FROM USER
<!-- where会自动加上where同处理多余的and -->
<where>
<!-- if标签的使用 -->
<if test="id != null">
and id = #{id}
</if>
<if test="username != null and username != ''">
and username LIKE '%${username}%'
</if>
</where>
3.sql片段的用法
定义
<!-- sql片段 定义,id:片段唯一标识 -->
<sql id="user_column">
`id`,
`username`,
`birthday`,
`sex`,
`address`,
`uuid2`
</sql>
使用
SELECT
<!-- sql片段的使用:include:引入sql片段,refid引入片段id -->
<include refid="user_column" />
FROM USER
4.foreach标签
<!-- 演示动态sql-foreach标签的使用情景 -->
<select id="getUserByIds" parameterType="queryvo"
resultType="pers.zx.mybatis.demo.User">
SELECT
*
FROM USER
<!-- where会自动加上where同处理多余的and -->
<where>
<!-- id IN(1,10,25,30,34) -->
<!-- foreach循环标签
collection:要遍历的集合,来源入参
open:循环开始前的sql
separator:分隔符
close:循环结束拼接的sql
-->
<foreach item="uid" collection="ids" open="id IN(" separator=","
close=")">
#{uid}
</foreach> </where>
</select>
十一、关联查询
1.一对一关联
方法一,使用resultType
- 新建OrderUser的pojo,继承自Order。
public class OrderUser extends Order {
private String username;
private String address;
…….get,set
}- 修改order的映射文件,新增查询方法getOrderUser。 < select id=”getOrderUser” resultType=”orderuser全路径”>
SELECT
o.id
//有’’
o.user_id
userId,
o.number
,
o.createtime
,
o.note
,
u.username
,
u.address
FROMorder
o
LEFT JOINuser
u
ON u.id = o.user_id
< /select>
方法二,使用resultMap
- 改造order的pojo
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
private User user;- 修改order的映射文件
<!-- 一对一关联查询-resultMap -->
<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:绑定的用户属性
javaType:属性数据类型,支持别名
-->
<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="sex" column="sex"/>
</association>
</resultMap>
<!-- 一对一关联查询-使用resultMap -->
<select id="getOrderUser2" resultMap="order_user_map">
SELECT
o.`id`,
o.`user_id`,
o.`number`,
o.`createtime`,
o.`note`,
u.`username`,
u.`address`,
u.`sex`
FROM `order` o
LEFT JOIN `user` u
ON u.id = o.`user_id`
</select>
2.一对多关联
1.修改user类
private Integer id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
private List< Order> orders;2.修改user的映射文件
<!-- 一对多关联查询 -->
<resultMap type="user" id="user_order_map">
<id property="id" column="id" />
<result property="username" column="username" />
<result property="birthday" column="birthday" />
<result property="address" column="address" />
<result property="sex" column="sex" />
<result property="uuid2" column="uuid2" />
<!-- collection:配置一对多关系
property:用户下的order属性
ofType:property的数据类型,支持别名
-->
<collection property="orders" ofType="orders的全路径">
<!-- id标签用于绑定主键 -->
<id property="id" column="oid"/>
<!-- 使用result绑定普通字段 -->
<result property="userId" column="id"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
</collection>
</resultMap>
<!-- 一对多关联查询 -->
<select id="getUserOrder" resultMap="user_order_map">
SELECT
u.`id`,
u.`username`,
u.`birthday`,
u.`sex`,
u.`address`,
u.`uuid2`,
o.`id` oid,
o.`number`,
o.`createtime`
FROM `user` u
LEFT JOIN `order` o
ON o.`user_id` = u.`id`
</select>
十二、Mybatis整合Spring
传统dao
1.创建项目导入jar包
2.创建配置文件
SqlMapConfig.xml
applicationContext.xml
3.创建实体类
package pers.zx.mybatis.domain;
import java.util.Date;
import java.util.List;
public class User {
private Integer id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="+ address + "]";
}
}
4.编写实体类的映射文件user.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">
<mapper namespace="user">
<!-- 插入实体 -->
<!--方式一: useGeneratedKeys="true"使用自增,可以执行获取id的语句 keyProperty="id"获取的id -->
<insert id="insertUser" parameterType="pers.zx.mybatis.demo.User" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO user(username,birthday,sex,address) values(#{username},
#{birthday},
#{sex},
#{address}
);
</insert>
</mapper>
5.配置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"/>
</mappers>
</configuration>
6.编写UserDao和UserDaoImpl
package pers.zx.mybatis.dao;
public interface UserDao {
void insertUser();
}
package pers.zx.mybatis.dao.impl;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import pers.zx.mybatis.dao.UserDao;
import pers.zx.mybatis.domain.User;
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
@Override
public void insertUser() {
// TODO Auto-generated method stub
SqlSession sqlSession=super.getSqlSession();
User user=new User();
user.setUsername("xxxzz");
sqlSession.insert("user.insertUser", user);
}
}
7.编写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>
<!-- SqlSessionFactory配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 加载mybatis核心配置文件 -->
<property name="configLocation" value="classpath:SqlMapConfig.xml" />
<!-- 别名包扫描 -->
<property name="typeAliasesPackage" value="pers.zx.mybatis.domain" />
</bean>
<!-- 传统Dao配置 -->
<bean id="userDao" class="pers.zx.mybatis.dao.impl.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<!-- 动态代理配置方式:第一种 -->
<!-- <bean id="baseMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" abstract="true" lazy-init="true">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean> -->
<!-- 配置一个接口 -->
<!-- <bean parent="baseMapper">
<property name="mapperInterface" value="pers.zx.mybatis.mapper.UserMapper" />
</bean> -->
<!-- 动态代理,第二种方式:包扫描(推荐): -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- basePackage多个包用","分隔 -->
<!-- <property name="basePackage" value="com.itheima.mybatis.mapper" /> -->
<property name="basePackage" value="com.itheima.ssm.mapper" />
</bean>
</beans>
8.编写测试类
public class TestofSM {
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao=applicationContext.getBean(UserDao.class);
userDao.insertUser();
}
}
动态Dao
(1)mapper和mapper.xml
import pers.zx.mybatis.domain.User;
public interface Mapper {
void insertUser(User user);
}
<?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="pers.zx.mybatis.mapper.Mapper">
<insert id="insertUser" parameterType="pers.zx.mybatis.domain.User" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO user(username,birthday,sex,address) values(#{username},
#{birthday},
#{sex},
#{address}
);
</insert>
</mapper>
(2)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>
<!-- SqlSessionFactory配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 加载mybatis核心配置文件 -->
<property name="configLocation" value="classpath:SqlMapConfig.xml" />
<!-- 别名包扫描 -->
<property name="typeAliasesPackage" value="pers.zx.mybatis.domain" />
</bean>
<!-- 传统Dao配置 -->
<bean id="userDao" class="pers.zx.mybatis.dao.impl.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<!-- 动态代理配置方式:第一种 -->
<!-- <bean id="baseMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" abstract="true" lazy-init="true">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean> -->
<!-- 配置一个接口 -->
<!-- <bean parent="baseMapper">
<property name="mapperInterface" value="pers.zx.mybatis.mapper.UserMapper" />
</bean> -->
<!-- 动态代理,第二种方式:包扫描(推荐): -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- basePackage多个包用","分隔 -->
<property name="basePackage" value="pers.zx.mybatis.mapper" />
</bean>
</beans>
十三、逆向工程
1.项目结构
2.配置文件
<?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/hibernate" userId="root"
password="root">
</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.zx.mybatis.domain"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.zx.mybatis.mapper"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.zx.mybatis.mapper"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<table schema="" tableName="user"></table>
<table schema="" tableName="order"></table>
<!-- 有些表的字段需要指定java类型
<table schema="" tableName="">
<columnOverride column="" javaType="" />
</table> -->
</context>
</generatorConfiguration>
3.生成类
import java.io.File;
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.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();
}
}
}
4.说明
逆向工程会生成相应的实体类,以及对应的mapper接口和mapper映射文件,还有一个对应的example类。其中example类是用来完成一些数据库连接操作的。
注意:逆向工程只能对单表操作。而且生成的方法中名字长的方法被用的越多。
@Test
public void testSelectByExample() {
UserMapper userMapper = applicationContext.getBean(UserMapper.class);
UserExample example = new UserExample();
//创建Criteria
Criteria criteria = example.createCriteria();
//设置查询条件
criteria.andUsernameLike("%张%");
criteria.andSexEqualTo("2");
List<User> list = userMapper.selectByExample(example);
for (User user : list) {
System.out.println(user);
}
}