MyBatis开发环境搭建
1.数据库的搭建
2.创建对应的实体类,mapper层接口(dao接口)
3.导入jar包
核心包
依赖包
4.创建并配置核心配置文件(MyBatisConfig.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 引入属性配置文件
settings 设置运行的环境变量
typeAliases 类型命名(别名)
typeHandlers类型处理器
plugins 插件 (插件可以改变MyBatis底层的行为 功能非常强大)
environments环境
mappers 映射文件加载器
-->
<!-- 作用:加载属性文件 -->
<properties resource="jdbc.properties"></properties>
<!-- 别名 :就是给你的类起一个简单一点的名称 alias自定义名称 type:类全限定名
(其实真实项目中并不常用,
第一因为它的可读性差,其他不熟悉的人看代码,还得回来找
第二因为spring整合后核心配置文件就没了
)
-->
<!--
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>
-->
<!-- 作用:环境配置 (其中可以配置多个环境 default是默认使用哪个)-->
<environments default="dev">
<!-- 其中一个环境 -->
<environment id="dev">
<!-- 事物 -->
<transactionManager type="JDBC"/>
<!-- 数据源
(type:数据源类型——有三种:
UNPOOLED:不支持数据源
POOLED:支持简单的数据源
JNDI:通过jndi从tomcat之类的容器里获取数据源。 )
-->
<dataSource type="POOLED">
<!-- 这里value引用的属性文件中的值 -->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 映射加载器 resoure里写映射文件的全限定名-->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
5,映射配置文件(xxxMapper.xml)
常用顶级子节点
cache是缓存配置。
<cache type="PERPETUAL" eviction="LRU" flushInterval="60000" size="512" readOnly="true" />
type:cache实现类,默认为PERPETUAL,可以使用自定义的cache实现类(别名或完整类名皆可)
eviction:回收算法,默认为LRU,可选的算法有:
LRU– 最近最少使用的:移除最长时间不被使用的对象。
FIFO– 先进先出:按对象进入缓存的顺序来移除它们。
SOFT– 软引用:移除基于垃圾回收器状态和软引用规则的对象。
WEAK– 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
flushInterval-刷新间隔,默认为1个小时,单位毫秒
size-缓存大小,默认大小1024,单位为引用数
readOnly-只读
cache-ref是引用别的缓存配置
<cache-ref namespace="com.someone.application.data.SomeMapper"/>
如果你不想定义自己的cache,可以使用cache-ref引用别的cache。因为每个cache都以namespace为id,所以cache-ref只需要配置一个namespace属性就可以了。resultMap结果映射配置
<resultMapid="userResultMap" type="User">
<idproperty=" userid " column="userid"/>
<result property="username" column="username" />
<result property="password" column="password" />
</resultMap>
结果映射配置的是数据库字段和实体类字段的对应关系,property表示了实体类字段名,column表示了数据库字段名(常在关联查询时配置结果集用)
sql通用sql配置
<sql id="userColumns"> userid,username,password </sql>
这个元素可以被用来定义可重用的SQL代码段,可以包含在其他语句中。例如:
<select id="queryUsers" parameterType="UserDto" resultType="UserDto" useCache="false">
select <include refid="userColumns"/> from t_user t where t.username = #{username}
</select>
statement包括增删改查
<?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它有两个作用:一是用于区分不同的mapper(在不同的mapper文件里,子元素的id可以相同,mybatis通过namespace和子元素的id联合区分),
二是与接口关联(应用程序通过接口访问mybatis时,mybatis通过接口的完整名称查找对应的mapper配置,因此namespace的命名务必小心一定要某接口同名)。
-->
<mapper namespace="mapper.UserDao">
<!--
mapper配置文件还有几个顶级子元素(它们须按照顺序定义):
cache -配置本定命名空间的缓存。
cache-ref –从其他命名空间引用缓存配置。
resultMap –结果映射,用来描述如何从数据库结果集映射到你想要的对象。
sql –可以重用的SQL块,可以被其他数据库操作语句引用。
insert|update|delete|select–数据库操作语句
-->
<!-- 配置缓存 -->
<!--
type:cache实现类,默认为PERPETUAL,可以使用自定义的cache实现类(别名或完整类名皆可)
eviction:回收算法,默认为LRU,可选的算法有:
LRU– 最近最少使用的:移除最长时间不被使用的对象。
FIFO– 先进先出:按对象进入缓存的顺序来移除它们。
SOFT– 软引用:移除基于垃圾回收器状态和软引用规则的对象。
WEAK– 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
flushInterval-刷新间隔,默认为1个小时,单位毫秒
size-缓存大小,默认大小1024,单位为引用数
readOnly-只读
-->
<cache type="PERPETUAL" eviction="LRU" flushInterval="60000" size="512" readOnly="true" />
<!-- 引用缓存 -->
<!--
如果你不想定义自己的cache,可以使用cache-ref引用别的cache。因为每个cache都以namespace为id,所以cache-ref只需要配置一个namespace属性就可以了。
需要注意的是,如果cache-ref和cache都配置了,以cache为准。
-->
<!-- <cache-ref namespace="com.someone.application.data.SomeMapper"/> -->
<!-- 结果映射 -->
<!--
resultMap提供了从数据库表列名到java对象属性的映射管理, type属性标记java类型(别名)
-->
<resultMap id="userResultMap" type="POJO.UserModel">
<!--property指带java中的属性,column指带数据库表的列名。 -->
<id property=" userid " column="uid" />
<result property="username" column="name" />
</resultMap>
<!-- 通用sql配置 -->
<!-- 调用的时候在语句中 <include refid="userquanziduan"/> -->
<sql id="userquanziduan"> uid,name,telno,sex,age,address </sql>
<!-- 查 -->
<!--
parameterType:传入参数的全限定名或别名
resultType:返回结果的全限定名或别名
useCache:是否放入缓存
-->
<select id="queryUsers" parameterType="POJO.UserModel" resultType="POJO.UserModel" useCache="false">
select <include refid="userquanziduan"/> from t_user t where t.username = #{username}
</select>
<!-- 添加 -->
<!--
useGeneratedKeys:(仅对insert有用)这会告诉MyBatis使用JDBC的getGeneratedKeys方法来取出由数据(比如:像MySQL和SQL Server这样的数据库管理系统的自动递增字段)内部生成的主键。默认值:false。
keyProperty:(仅对insert有用)标记一个属性,MyBatis会通过getGeneratedKeys或者通过insert语句的selectKey子元素设置它的值。默认:不设置。
-->
<insert id="insertUser" parameterType="POJO.UserModel" useGeneratedKeys="true" keyProperty="uid">
<!--
selectKey给了你一个简单的行为在你的数据库中来处理自动生成的主键,而不需要使你的Java代码变得复杂。在上面的示例中,selectKey元素将会首先运行,
userid会被设置,然后插入语句会被调用。另外,selectKey节点生成的KeyGenerator优先级高于statement节点的useGeneratedKeys属性生成的KeyGenerator对象,
也就是说配置了SelectKey子节点就不需要再配置useGeneratedKeys属性了。
-->
<!--
<selectKey keyProperty="userid" resultType="int" order="BEFORE">
select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
</selectKey>
-->
insert into t_user (<include refid="userquanziduan"/>)
values (#{uid},#{name},#{telno},#{sex},#{age},#{address})
</insert>
<!-- 更新 -->
<update id="updateUserName" parameterType="string">
update t_user set
name = #{name},
where uid = #{uid}
</update>
<!-- 删除 -->
<delete id="deleteUserById" parameterType="int">
delete from t_user where uid = #{userid}
</delete>
<!-- 动态sql -->
<select id="findUserById" parameterType="POJO.UserModel" resultType="POJO.UserModel">
select <include refid="userquanziduan"/> from t_user
<!--
where:表示完整where条件配置的标签,它代表一个完整的where条件包括关键字where
它可以自动去掉第一个条件之前的and或者or
通常配合if标签一起使用完成动态条件
-->
<where>
<!--
if:表示条件分支判断的标签
test:表示分支的判断条件
用and表示与 用or表示或
-->
<if test="uid !=null and uid != 0">
and uid=#{uid}
</if>
</where>
</select>
<select id="findUserById1" parameterType="java.util.List" resultType="POJO.UserModel">
select <include refid="userquanziduan"/> from t_user
<!--
foreach:表示循环动态SQL的控制标签
collection:表示循环依据的集合对象名
此处参数是POJO类型的时候,名字必须是POJO中对应的属性名
item:表示每次循环使用的临时变量名
separator:表示每次循环的分割符号
open:表示循环之前的开始部分(不参与循环)
close:表示循环之后的结束部分(不参与循环)
-->
<where>
<foreach collection="list" item="s" separator="," open="uid in (" close=")">
#{s.uid}
</foreach>
</where>
</select>
<!-- 关联查询 -->
<!-- 一对一 -->
<!-- 分开形式 -->
<resultMap type="POJO.UserModel" id="userOneToOne">
<result property="uid" column="uid"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="telno" column="telno"/>
<result property="address" column="address"/>
<result property="age" column="age"/>
<association property="orderModel" resultMap="OrderModelOneToOne"></association>
</resultMap>
<resultMap type="POJO.OrderModel" id="OrderModelOneToOne">
<result column="orderId" property="orderId"/>
<result column="userId" property="userId"/>
<result column="orderStatus" property="orderStatus"/>
<result column="createDateTime" property="createDateTime"/>
<result column="updateDateTime" property="updateDateTime"/>
</resultMap>
<!-- 合并形式 -->
<!--
<resultMap type="POJO.UserModel" id="userOneToOne">
<result property="uid" column="uid"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="telno" column="telno"/>
<result property="address" column="address"/>
<result property="age" column="age"/>
<association property="orderModel" javaType="POJO.OrderModel">
<result column="orderId" property="orderId"/>
<result column="userId" property="userId"/>
<result column="orderStatus" property="orderStatus"/>
<result column="createDateTime" property="createDateTime"/>
<result column="updateDateTime" property="updateDateTime"/>
</association>
</resultMap>
-->
<select id="selectOneToOne" parameterType="int" resultMap="userOneToOne">
SELECT u.name,u.address,r.orderId,r.orderStatus FROM t_user u,t_order1 r where u.uid = r.userId and u.uid=#{in}
</select>
<!-- 一对多 -->
<resultMap type="POJO.UserModel" id="userOneToMany">
<result property="uid" column="uid"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="telno" column="telno"/>
<result property="address" column="address"/>
<result property="age" column="age"/>
<collection property="list" resultMap="OrderModelOneToMany" />
</resultMap>
<resultMap type="POJO.OrderModel" id="OrderModelOneToMany">
<result column="orderId" property="orderId"/>
<result column="userId" property="userId"/>
<result column="orderStatus" property="orderStatus"/>
<result column="createDateTime" property="createDateTime"/>
<result column="updateDateTime" property="updateDateTime"/>
</resultMap>
<select id="selectOneToMany" parameterType="int" resultMap="userOneToMany">
SELECT u.name,u.address,r.orderId,r.orderStatus FROM t_user u,t_order1 r where u.uid = r.userId and u.uid=#{in}
</select>
</mapper>
6.测试类应用
普通应用(只做简单演示)
public class MyBatisTest {
//把通用的提取出来
SqlSessionFactory ssf= null;
//before是 junit的注释 表示在方法之前运行
@Before
public void inti() throws IOException{
InputStream inputStream=Resources.getResourceAsStream("MyBatisConfig.xml");
ssf= new SqlSessionFactoryBuilder().build(inputStream);
}
/*
* 删除
*/
//不用beginTransaction MyBatis的事物是根据执行的语句自动开启的
@Test
public void deleteUserById() throws Exception{
//先创建一个会话对象
SqlSession ss = null;
try {
//读取核心配置文件
InputStream inputStream=Resources.getResourceAsStream("MyBatisConfig.xml");
//根据配置文件 创建一个会话工厂
SqlSessionFactory ssf= new SqlSessionFactoryBuilder().build(inputStream);
//获得会话
ss=ssf.openSession();
/*进行调用配置文件中的映射
第一个参数:表示要执行的SQL:namespace名.sql的id
第二个参数:表示执行SQL的参数*/
ss.delete("user.deleteUserById", 1002);
ss.commit();
} catch (Exception e) {
e.printStackTrace();
ss.rollback();
throw e;
} finally {
// 关闭会话
ss.close();
}
}
接口模式编程应用(动态代理)
原则:用接口规范映射文件的定义,保证一下四项内容一致。
接口 | 映射文件 |
完全限定名 | namespace |
方法名 | SQL的id |
接口方法的参数类型 | parameterType |
接口方法的返回值类型 | resultType |
public interface UserDao {
List<UserModel> findUserById(UserModel userModel);
List<UserModel> findUserById1(List<UserModel> list);
List<UserModel> selectOneToOne(int i);
UserModel selectOneToMany(int i);
}
public class MyBatisTest {
private SqlSessionFactory sessionFactory;
@Before
public void init() throws IOException{
InputStream inputStream=Resources.getResourceAsStream("MyBatisConfig.xml");
sessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
//测试if where标签
public void findUserById() {
SqlSession ss = sessionFactory.openSession();
//这里通过MaBatis来获取userdao的动态代理对象
UserDao dao = ss.getMapper(UserDao.class);
UserModel user = new UserModel();
user.setUid(1010);
List<UserModel> findUserById = dao.findUserById(user);
System.out.println(findUserById);
}
//测试foreach
@Test
public void findUserById1() {
SqlSession ss = sessionFactory.openSession();
UserDao dao = ss.getMapper(UserDao.class);
List<UserModel> list = new ArrayList<>();
UserModel userModel1=new UserModel();
UserModel userModel2=new UserModel();
userModel1.setUid(1001);
userModel2.setUid(1002);
list.add(userModel1);
list.add(userModel2);
List<UserModel> findUserById = dao.findUserById1(list);
System.out.println(findUserById);
}
//测试一对一
@Test
public void selectOneToOne() {
SqlSession ss = sessionFactory.openSession();
UserDao dao = ss.getMapper(UserDao.class);
List<UserModel> findUserById = dao.selectOneToOne(1003);
System.out.println(findUserById);
}
//测试一对多
@Test
public void selectOneToMany() {
SqlSession ss = sessionFactory.openSession();
UserDao dao = ss.getMapper(UserDao.class);
UserModel selectOneToMany = dao.selectOneToMany(1001);
System.out.println(selectOneToMany.getList().size());
}
}
到这里就可以简单的上手应用了,不是很详细,但是可以简单应用,希望可以帮助大家