Mybatis实现CRUD
Mybatis简介
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache soware foundation 迁移到了google code,并且改名为MyBatis 。2013 年11月迁移到Github。 iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久 层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)
MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层 框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结 果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始 映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对 象)映射成数据库中的记录。
Mybatis不是一个完全的orm框架,Mybatis需要程序员自己写sql,但是也存在映射(输入参数映射,输出结果映射),学习门槛mybatis比hibernate低;同时灵活性高,特别适用于业务模型易变的项目,使用范围广;
Mybatis更加简化jdbc代码,简化持久层,sql语句从代码中分离,利用反射, 将表中数据与java bean 属性一一映射 即 ORM(Object Relational Mapping 对象关系映射);
首先要引入mybatis框架的架包,以及连接数据库的驱动包(由于我是用的是orcale数据库,所以这里我引入的是orcale驱动包,如果使用的是mysql数据库,自己可以自行将架包换掉即可(即换掉以下图片红色方框里面的,换成mysql的驱动包))
mybatis.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文件 -->
<properties resource="db.properties"/>
<settings>
<!-- 设置MyBatis使用log4j日志支持 -->
<setting name="logImpl" value="log4j"/>
<!--设置启动二级缓冲机制 -->
<setting name="cacheEnabled" value="true"/>
</settings>
<!--类别名的设置有利于在mapper映射文件的书写方便 -->
<typeAliases>
<!-- 给每个类取别名,如果不写则默认为类名的大小写,即大小写不敏感 -->
<typeAlias type="com.ysh.Demo.Good" alias="good"/>
<!--给com.ysh.Demo包下的实体类取别名,即默认为实体类的名称或者是实体类名称的大小写变型 -->
<package name="com.ysh.Demo"/>
</typeAliases>
<!--
用于指明使用哪一个开发环境
default : 用于指定使用的环境的id属性值
-->
<environments default="dvd">
<!-- 用户配置开发环境 id: 环境的唯一标识 -->
<environment id="dvd">
<!--
事务管理器
JBDC : 表示采用JDBC一样的事务管理方式
-->
<transactionManager type="jdbc"/>
<!--
用于配置数据库连接池和数据库连接参数
POOLED : 表示mybatis采用连接池技术
-->
<dataSource type="pooled">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- SQL映射文件配置 -->
<mappers>
<!-- 指明SQL映射文件路径 resource : 包路径
com/shsxt.../xxxMapper.xml-->
<mapper resource="com/ysh/Mappers/MapperUser.xml"/>
<mapper resource="com/ysh/Mappers/MapperGoods.xml"/>
<!--指明SQL映射文件所有的包,即运行时会自动扫描该包中的所有映射文件 -->
<package name="com.ysh.Mappers"/>
</mappers>
</configuration>
Mybatis实现CRUD(未使用接口绑定方案)
这里我只使用了一个实体类,即Good,User并没有使用到
首先准备db.properties,Mybatis.xml
db.properties(由于我这里使用的是orcale驱动器,如果使用mysql数据库的可以自行从网上查询mysql数据库的连接配置文件,区别不太大)
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:XE
username=SCOTT
password=TIGER
Mybatis.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文件 -->
<properties resource="db.properties"/>
<settings>
<!-- 设置MyBatis使用log4j日志支持 -->
<setting name="logImpl" value="log4j"/>
<!--设置启动二级缓冲机制 -->
<setting name="cacheEnabled" value="true"/>
</settings>
<typeAliases>
<!-- 给每个类取别名,如果不写则默认为类名的大小写,即大小写不敏感 -->
<typeAlias type="com.ysh.demo.Good" alias="good"/>
<!--给com.ysh.Demo包下的实体类取别名,即默认为实体类的名称或者是实体类名称的大小写变型 -->
<package name="com.ysh.Demo"/>
</typeAliases>
<!--
用于指明使用哪一个开发环境
default : 用于指定使用的环境的id属性值
-->
<environments default="dvd">
<!-- 用户配置开发环境 id: 环境的唯一标识 -->
<environment id="dvd">
<!--
事务管理器
JBDC : 表示采用JDBC一样的事务管理方式
-->
<transactionManager type="jdbc"/>
<!--
用于配置数据库连接池和数据库连接参数
POOLED : 表示mybatis采用连接池技术
-->
<dataSource type="pooled">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- SQL映射文件配置 -->
<mappers>
<!-- 指明SQL映射文件路径 resource : 包路径
com/shsxt.../xxxMapper.xml-->
<!-- 这里需要特别注意未使用接口绑定方案时使用包扫描时会报错,所以未使用接口绑定方案不能使用包扫描 -->
<!--包扫描 -->
<!--<package name="com.ysh.mappers"/>-->
<mapper resource="com/ysh/mappers/MapperGood.xml"/>
</mappers>
</configuration>
util层
package com.ysh.util;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.sql.DriverManager;
public class MybatisUtil {
static InputStream is;
static SqlSessionFactory factory;
static {
try {
//加载配置文件
is = Resources.getResourceAsStream("Mybatis.xml");
//构建sql会话工厂
factory=new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSession(){
//这里可以设置事务自动提交factory.openSession(true),默认是不自动提交,这里我没有自动提交事务,所以在后续对数据的增删改需要自己手动提交事务
SqlSession sqlSession = factory.openSession();
return sqlSession;
}
}
mapper层
<?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">
<!--由于我这里没有写接口绑定方案,所以这里的命名方式可以随意,但是我建议取包名.xml文件名,这样更规范一点 -->
<mapper namespace="com.ysh.mappers.MapperGood">
<!--查询 -->
<select id="selectById" resultType="com.ysh.demo.Good" parameterType="int">
select * from hd_goods where gid=#{gid}
</select>
<!--更新 -->
<update id="updateById" parameterType="Good" >
update hd_goods set name=#{name} where gid=#{gid}
</update>
<!--更新 -->
<insert id="addGood" parameterType="Good">
insert into hd_goods(gid,name) values(#{gid},#{name})
</insert>
<!--删除 -->
<delete id="deleteByid" parameterType="list">
delete from hd_goods where gid in (
<foreach collection="list" item="item" separator=",">
#{item}
</foreach>
)
</delete>
</mapper>
test
package com.ysh.test;
import com.ysh.demo.Good;
import com.ysh.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.Arrays;
import java.util.List;
public class GoodTest {
public static void main(String[] args) {
selectGood();
//dateGood();
//add();
//deleteGood();
}
//查询测试
public static void selectGood(){
SqlSession session = MybatisUtil.getSession();
/*com.ysh.mappers.MapperGood.selectById这里时定位到MapperGood.xml,
因为这里之前MapperGood.xml中的命名
空间为 namespace="com.ysh.mappers.MapperGood",
selectById是指定位到哪个sql语句,即每个sql标签的id属性值,即<select id="">
*/
List<Good> list = session.selectList("com.ysh.mappers.MapperGood.selectById", 1);
//方法引用遍历集合
list.forEach(System.out::println);
session.close();
}
//更新测试
public static void updateGood(){
SqlSession session = MybatisUtil.getSession();
Good good=new Good(1,"hahh",null,null,null,null);
session.update("com.ysh.mappers.MapperGood.updateById",good);
//手动提交事务
session.commit();
session.close();
}
public static void add(){
SqlSession session = MybatisUtil.getSession();
Good good=new Good(17,"hahh",null,null,null,null);
session.update("com.ysh.mappers.MapperGood.addGood",good);
//手动提交事务
session.commit();
session.close();
}
public static void deleteGood(){
SqlSession session = MybatisUtil.getSession();
List<Integer> list= Arrays.asList(6,17);
session.update("com.ysh.mappers.MapperGood.deleteByid",list);
//手动提交事务
session.commit();
session.close();
}
}
结果运行截图:
Mybatis实现CRUD(使用接口绑定方案)
Mybatis.xml文件与上面xml文件一致,只不过我将文件扫描换成了包扫描
<mappers>
<!-- 指明SQL映射文件路径 resource : 包路径
com/shsxt.../xxxMapper.xml-->
<!-- <mapper resource="com/ysh/mappers/MapperGood.xml"/>-->
<!--由于这里我使用了接口绑定方案,所以可以使用包扫描,当然也可以使用以上方式 -->
<package name="com.ysh.mappers"/>
</mappers>
Mapper层:这里要注意命名规范,一般都是与相对应的xml文件命名一致(之前命名时我就是以包名.xml文件名,因为接口名与xml文件名一致,所以我没有粘贴代码,有需要直接在上面复制)
<!--MapperGood.xml与以上文件一致,但是这里需要特别注意的这里的命名空间不能任意取了,这里必须指定到与xml相对应的接口,例如我这里与MapperGood.xml相对应的接口名为MapperGood,所以在namespace="MapperGood文件所在的包名.接口名(即自己的名称MapperGood)" -->
<mapper namespace="com.ysh.mappers.MapperGood">
接口代码:这里需要注意的是这里的接口中的方法名必须与MapperGood.xml文件中sql标签中id属性值相对应,这是Mybatis框架映射的体现
package com.ysh.mappers;
import com.ysh.demo.Good;
import java.util.List;
public interface MapperGood {
//selectById()方法名对应MapperGood.xml中<select id="selectById"></select>标签id的属性值
public List<Good> selectById(int i);
public void updateById(Good good);
public void addGood(Good good);
public void deleteByid(List<Integer> list);
}
test层:测试代码
package com.ysh.test;
import com.ysh.demo.Good;
import com.ysh.mappers.MapperGood;
import com.ysh.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.Arrays;
import java.util.List;
public class GoodTest {
public static void main(String[] args) {
selectGood();
updateGood();
add();
deleteGood();
}
public static void selectGood(){
//得到SqlSession会话
SqlSession session = MybatisUtil.getSession();
/*
使用getMapper()获取接口实现类对象,参数为接口的class对象,通
过参数指定接口,这里体现了多态
*/
MapperGood mapper = session.getMapper(MapperGood.class);
//调用接口中的方法
List<Good> list = mapper.selectById(1);
list.forEach(System.out::println);
//关闭资源
session.close();
}
public static void updateGood(){
//得到SqlSession会话
SqlSession session = MybatisUtil.getSession();
/*
使用getMapper()获取接口实现类对象,参数为接口的class对象,通
过参数指定接口,这里体现了多态
*/
MapperGood mapper = session.getMapper(MapperGood.class);
Good good=new Good(1,"hahh",null,null,null,null);
//调用接口中的方法
mapper.updateById(good);
//提交事务
session.commit();
//关闭资源
session.close();
}
public static void add(){
//得到SqlSession会话
SqlSession session = MybatisUtil.getSession();
/*
使用getMapper()获取接口实现类对象,参数为接口的class对象,通
过参数指定接口,这里体现了多态
*/
MapperGood mapper = session.getMapper(MapperGood.class);
Good good=new Good(17,"hahh",null,null,null,null);
//调用接口中的方法
mapper.addGood(good);
//提交事务
session.commit();
//关闭资源
session.close();
}
public static void deleteGood(){
//得到SqlSession会话
SqlSession session = MybatisUtil.getSession();
/*
使用getMapper()获取接口实现类对象,参数为接口的class对象,通
过参数指定接口,这里体现了多态
*/
MapperGood mapper = session.getMapper(MapperGood.class);
List<Integer> list= Arrays.asList(6,17);
mapper.deleteByid(list);
//提交事务
session.commit();
//关闭资源
session.close();
}
}
util层代码与以上一致
运行结果:
使用接口绑定方案解决多个参数传入问题
例如以下代码(这里我是在以上接口代码中作修改):
第一种方法:定位取值
package com.ysh.mappers;
import com.ysh.demo.Good;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface MapperGood {
List<Good> selectById(int i);
//为变量取别名,方面mapper映射文件的接收,即#{arg0}、#{param1}取的是接口中第一个变量的值即变量id的值,#{arg1}、#{param2}取的是接口中第二个变量的值,即变量name的值
/*
以下是对mapper文件中sql语句的修改
//并且如果接口中传入多个参数的话,不写传入的参数类型即不写parameterType="×××"
<update id="updateById">
update hd_goods set name=#{arg1} where gid=#{arg0}
</update>
<update id="updateById">
update hd_goods set name=#{param2} where gid=#{param1}
</update>
*/
void updateById(int id,String name);
void addGood(Good good);
void deleteByid(List<Integer> list);
}
MapperGood.xml的中< update >标签中内容的修改
<!-- 第一种方式 -->
<update id="updateById">
update hd_goods set name=#{arg1} where gid=#{arg0}
</update>
<!--第二种方式 -->
<update id="updateById">
update hd_goods set name=#{param2} where gid=#{param1}
</update>
第二种方法:取别名取值
package com.ysh.mappers;
import com.ysh.demo.Good;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface MapperGood {
List<Good> selectById(int i);
//为变量取别名,方面mapper映射文件的接收,即#{name}取的是接口中name变量的值,#{gid}取的是接口中gid变量的值
/*
//并且如果接口中传入多个参数的话,不写传入的参数类型即不写parameterType="×××"
<update id="updateById">
update hd_goods set name=#{name} where gid=#{gid}
</update>
*/
void updateById(@Param("gid") int id, @Param("name") String name);
void addGood(Good good);
void deleteByid(List<Integer> list);
}
MapperGood.xml的中< update >标签中内容的修改
<update id="updateById">
update hd_goods set name=#{name} where gid=#{gid}
</update>
参数传入知识点
注意:如果sql标签中传入的参数为引用类型,例如Good类型,这时候#{name} 、#{gid}取值是从Good类中的属性取值,即name、gid是Good的属性名,不可出现其它非Good类中属性名。
<update id="updateById" parameterType="Good">
update hd_goods set name=#{name} where gid=#{gid}
</update>
但是如果传入的参数是一个基本数据类型或者包装类类型的话,#{name},name的名称可以随便改变,可以是任意字符
<delete id="deleteById" parameterType="int">
delete from hd_goodswhere gid=#{gid}
<!--以下语句都行 -->
<!--delete from hd_goodswhere gid=#{id} -->
<!--delete from hd_goodswhere gid=#{1} -->
</delete>
如果传入的参数是一个List集合,则可以通过< foreach >标签遍历集合,例如
<!--#{item}表示取属性item中item的值,open表示以 ( 开始 ; separator表示以 ,分割; close表示以 )结束-->
<delete id="deleteByid" parameterType="list">
delete from hd_goods where gid in
<foreach collection="list" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</delete>
如果返回值类型为Map类型,则是以查询的字段名为key,查询到的结果为value,例如
<select id="selectById" resultType="map" parameterType="int">
select * from hd_goods where gid>#{gid}
</select>
运行结果:
列取别名–解决列名与属性名不一致问题
<select id="selectAll" resultMap="rm">
select name gname,gid from hd_goods
</select>
关系型映射查询–解决列名(数据库中的字段名)与属性名不一致问题
<!--resultMap标签中的子标签<id/>是标识数据库表中的主键, <result/>是标识数据库中的非主键字段 -->
<resultMap id="rm" type="good">
<id property="gid" column="gid"/>
<result property="name" column="gname"/>
</resultMap>
<!--关系型映射 -->
<select id="selectAll" resultMap="rm">
select name gname,gid from hd_goods
</select>
关系型映射查询resultMap–实现多表查询(一对一|多对一)
例如在员工和部门之间,一个员工只能属于一个部门,一个部门有多个员工,即员工和部门存在多对一关系,如果这时候有个需求使用Mybatis框架实现查询员工表以及所属部门表的基本信息输出到控制台上;
实现思路:
- 首先员工实体类中首先要有一个成员对象期类型为部门实体类的对象;
- 然后使用resultMap中的< association >< /association >标签获取部门信息;
<resultMap id="haha" type="Emp">
<id property="empno" column="empno"/>
<result property="ename" column="ename"/>
<result property="job" column="job"/>
<association property="dept" javaType="Dept">
<id property="deptno" column="deptno"/>
<result property="dname" column="dname"/>
<result property="loc" column="loc"/>
</association>
</resultMap>
<select id="selectAll" resultMap="haha">
select empno,ename,job,e.deptno,dname,loc from emp e left join dept d on e.deptno=d.deptno
</select>
关系型映射查询resultMap–实现多表查询(一对多)
例如在员工和部门之间,一个员工只能属于一个部门,一个部门有多个员工,即部门和员工存在一对多关系,如果这时候有个需求使用Mybatis框架实现查询部门中所有员工的基本信息输出到控制台上;
- 首先部门表中有个成员变量来存储员工信息,这里我用List集合来存储每个部门的员工信息,泛型为员工类型
- 然后使用resultMap中的< collection >< /collection >标签获取改部门的员工信息;
<resultMap id="hehe" type="Dept">
<id property="deptno" column="deptno"/>
<result property="dname" column="dname"/>
<result property="loc" column="loc"/>
<collection property="list" javaType="list" ofType="Emp">
<id property="empno" column="empno"/>
<result property="ename" column="ename"/>
<result property="job" column="job"/>
</collection>
</resultMap>
<select id="selectAll" resultMap="hehe">
select empno,ename,job,e.deptno,dname,loc from emp e,dept d where e.deptno=d.deptno
</select>
动态SQL—if标签
<!--动态sql if的用法-->
<select id="selectBy01" resultType="Good">
select * from hd_goods where 1=1
<if test="gid!=null and gid!=0">
and gid=#{gid}
</if>
<if test="name!=null and name!=''">
and name=#{name}
</if>
</select>
动态SQL—where标签
<!--动态sql where的用法 -->
<!--where会自动去除前面多有的and -->
<select id="selectBy02" resultType="Good">
select * from hd_goods
<where>
<if test="gid!=null and gid!=0">
and gid=#{gid}
</if>
<if test="name!=null and name!=''">
and name=#{name}
</if>
</where>
</select>
动态SQL—choose when otherwise
<!--动态sql choose when otherwise的用法 -->
<!--choose when otherwise只能选择一个,例如如果第一个、第二个判断条件都为true满足即gid不为
空和不为0,name不为null和不为空串,但是这时候where的判断条件为where gid= ××××,
即优先选择第一个,也只能选择一个作为where中的条件判断-->
<select id="selectBy03" resultType="Good">
select * from hd_goods where
<choose>
<when test="gid!=null and gid!=0">
gid=#{gid}
</when>
<when test="name!=null and name!=''">
name=#{name}
</when>
<otherwise>
1=1
</otherwise>
</choose>
</select>
动态SQL—set标签
<!--动态sql set的用法 -->
<!--set标签会自动去除末尾的逗号 -->
<select id="selectBy04" resultType="Good">
update hd_goods
<set>
gid=#{gid},
<if test="name!=null and name!=''">
name=#{name},
</if>
<if test="price!=null and price!=0">
price=#{price},
</if>
</set>
where gid=#{gid}
</select>
动态SQL—foreach标签
<!--批量删除 -->
<delete id="deleteByid" parameterType="list">
delete from hd_goods where gid in (
<foreach collection="list" item="item" separator=",">
#{item}
</foreach>
)
</delete>
动态SQL–sql include
<sql id="all">gid,name,price</sql>
<select id="selectBy03" resultType="Good">
select <include refid="all"/> from hd_goods where
<choose>
<when test="gid!=null and gid!=0">
gid=#{gid}
</when>
<when test="name!=null and name!=''">
name=#{name}
</when>
<otherwise>
1=1
</otherwise>
</choose>
</select>
批量插入–方法1
<!--批量添加 方法1-->
<insert id="insertMany" parameterType="list">
<foreach collection="list" open="begin" separator=";" close=";end;" item="item">
insert into hd_goods(gid,name) values(#{item.gid},#{item.name})
</foreach>
</insert>
批量插入–方法2
<!--批量添加 方法2-->
<insert id="insertMany02" parameterType="list">
insert into hd_goods(gid,name)
<foreach collection="list" separator="union" item="item">
select #{item.gid},#{item.name} from dual
</foreach>
</insert>
批量修改
<!--批量修改-->
<update id="updateMany" parameterType="list">
<foreach collection="list" item="item" open="begin" close=";end;" separator=";">
update hd_goods set name=#{item.name} where gid=#{item.gid}
</foreach>
</update>
批量删除
<!--批量删除 -->
<delete id="deleteByid" parameterType="list">
delete from hd_goods where gid in (
<foreach collection="list" item="item" separator=",">
#{item}
</foreach>
)
</delete>
Mybatis缓冲机制
- 一级缓存:默认开启. 线程级别的缓存, SqlSession 的缓存 ,系统默认就有,如果想要关闭可以在mapper层的xml中的sql标签中将flushcache属性设置为true,该属性默认为false;
- 二级缓存:进程级别的缓存, SqlSessionFactory 的缓存,默认关闭, 需要使用的时候, 要为某个命名空间开启 二级缓存(首先在 mapper层的xml文件 中配置cache).
<mapper namespace="com.ysh.mappers.MapperGood">
<!--开启二级缓存 -->
<cache />
<select id="selectById" resultType="map" parameterType="int" >
select * from hd_goods where gid>#{gid}
</select>
</mapper>
如果想要关闭二级缓存则在mybatis.xml配置文件中的加入以下配置
<!-- 二级缓存的设置 -->
<settings>
<setting name="cacheEnabled" value="false"/>
</settings>
日志文件
日志文件级别,级别排序DEBUG < INFO < WARN < ERROR < FATAL
- DEBUG(人为调试信息)
- INFO(普通信息)
- WARN(警告)
- ERROR(错 误)
- FATAL(系统错误)
# Set root category priority to INFO and its only appender to CONSOLE.
# log4j.rootCategory=DEBUG, CONSOLE
#这里只能打印比info级别高的日志信息在控制台上,,LOGFILE表示将日志文件信息生成一个文件
log4j.rootCategory=INFO, CONSOLE,LOGFILE
log4j.logger.com.ysh.mappers=DEBUG
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
#%m表示日志信息 %c表示打印哪个包名.类名打印的日志 %l表示打印哪个包名.类名.方法名打印的日志(即调用了这个方法)
#%d表示打印时间 %n表示换行,即这里表示输出格式
log4j.appender.CONSOLE.layout.ConversionPattern= %m %n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
#将生成的日志文件保存在D:/yinwei目录下,没有该目录则自动创建(注意这里的路径都是用/反斜杠),并且命名为test.log
log4j.appender.LOGFILE.File=D:/yinwei/test.log
#是否可以在源文件后面追加,true表示可以,false表示覆盖
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=- %m %l%n
注解开发
CRUD注解
- @Select: 类似于select标签
- @Insert: 类似于insert标签
- @Update: 类似于update标签
- @Delete: 类似于delete标签
其它注解
- @Results: 类似于resultMap标签
- @Result: 类似 resultMap的子标签
- @One: 类似于association标签
- @Many: 类似于collection标签
@One、@Results、@Result的用法实例(一对一以及多对一,即多个员工可能位于一个部门)
MapperEmp接口
@Select("select empno,ename,job,e.deptno,dname,loc from emp e left join dept d on e.deptno=d.deptno")
@Results(value = {@Result(column = "empno",property = "empno",id = true),
@Result(column = "ename",property = "ename"),
@Result(column = "job",property = "job"),
@Result(property = "dept",one = @One(select="com.ysh.mappers.MapperDept.selectById"),column = "deptno")})
public List<Emp> selectAll();
MapperDept接口
@Select("select * from dept where deptno=#{no}")
public Dept selectById(@Param("no") int no);
@Many、@Results、@Result的用法实例(一对多,即一个部门有多个员工)
MapperDept接口
@Select("select empno,ename,job,e.deptno,dname,loc from emp e,dept d where e.deptno=d.deptno")
@Results({@Result(property = "deptno",column = "deptno",id = true),
@Result(property = "dname",column = "dname"),
@Result(property = "loc", column="loc"),
@Result(property = "list",many = @Many(select = "com.ysh.mappers.MapperEmp.selectby"),column ="deptno")})
public List<Dept> selectAll();
MapperEmp接口
@Select("select * from emp where deptno=#{deptno}")
public List<Emp> selectby(int deptno);
逆向工程
mybatis-generator是一款mybatis自动代码生成工具,可以 通过配置,快速生成pojo,mapper和xml文件.
generatorConfig.xml配置 需添加到资源包下 src下
generatorConfig.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>
<properties resource="db.properties"/>
<!--数据库驱动 -->
<context id="Tables" targetRuntime="MyBatis3">
<!-- 生成的Java文件的编码 -->
<property name="javaFileEncoding" value="UTF-8" />
<!-- JavaBean 实现 序列化 接口 -->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
<commentGenerator>
<property name="suppressDate" value="false" />
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="false" />
</commentGenerator>
<!--数据库链接地址账号密码 -->
<jdbcConnection
driverClass="${driver}"
connectionURL="${url}"
userId="${username}"
password="${password}">
</jdbcConnection>
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true 时把JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!--生成 Model 类存放位置 -->
<javaModelGenerator targetPackage="com.ysh.pojo"
targetProject="E:\IDEAproject\ReturnProject11_07\src">
<!--构造器-->
<property name="constructorBased" value="true"/>
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!--生成映射文件存放位置 -->
<sqlMapGenerator targetPackage="com.ysh.mappers"
targetProject="E:\IDEAproject\ReturnProject11_07\src">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!--生成接口类存放位置(Dao|Mapper) -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.ysh.mappers" targetProject="E:\IDEAproject\ReturnProject11_07\src">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 参考数据库中需要生成的对应表信息 -->
<table tableName="dept" domainObjectName="Dept"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
<columnOverride column="deptno" javaType="Integer"/>
</table>
<table tableName="emp" domainObjectName="Emp"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false"></table>
<!--<table tableName="dept" domainObjectName="Dept"
enableCountByExample="true" enableUpdateByExample="true"
enableDeleteByExample="true" enableSelectByExample="true"
selectByExampleQueryId="true"></table>-->
</context>
</generatorConfiguration>
运行并测试
package test;
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;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class Util {
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<>();
boolean overwrite = true;
try {
//指定 逆向工程配置文件
File configFile = new File("src/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);
} catch (Exception e) {
e.printStackTrace();
}
}
}