mybatis是一个持久层框架,是为了简化dao层开发的一个框架。
注意原来的com.dao和com.dao.impl这两个包都不用存在了,新建一个包叫做com.mapper的。
mybatis的config文件,随便取个什么名字,就叫mybatis.xml好了。大致配置如下:
<configuration>
<environments default="default">
<environment id="default">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="lijingjing"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/mapper/FlowerMapper.xml"/>
mappers>
configuration>
一般来说这个文件的命名都是什么什么Mapper
<mapper namespace="com.mapper.FlowerMapper">
<select id="selAll" resultType="com.pojo.Flower">
select * from flower
select>
mapper>
在META-INFO中建立content.xml文件,如下
<Context>
Context>
在src下创建log4j.properties文件,内容如下:
# 这一行代表输出的级别为DEBUG,还有INFO、WARN、ERROR、FATAL四个级别,依次递增,若指定级别为INFO,则DEBUG消息无法输出
# 这一行同时指定了输出位置为控制台和文件
log4j.rootCategory=INFO,CONSOLE
log4j.logger.com.mapper.FlowerMapper=DEBUG
# 这两行是固定格式
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
# 这一行指定了输出时的信息:l表示发生位置(行数),d表示时间,m表示消息,n是换行,p表示输出级别
log4j.appender.CONSOLE.layout.ConversionPattern=-%p-%d{yyyy/MM/dd HH:mm:ss,SSS}-%l-%L-%m%n
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
# 指定文件位置,根目录为项目根目录
log4j.appender.LOGFILE.File=C:\\coding\\logFiles\\login.log
# 表示追加
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=-%p-%d{yyyy/MM/dd HH:mm:ss,SSS}-%l-%L-%m%n
使mybatis开启log4j日志功能(实测不开启也会自动输出日志)
<settings>
<setting name="logImpl" value="log4j"/>
settings>
<typeAliases>
<typeAlias type="com.pojo.Flower" alias="flo"/>
typeAliases>
mapper文件:
<mapper namespace="com.mapper.FlowerMapper">
<select id="selAll" resultType="flo">
select * from flower
select>
<select id="selById" resultType="flo" parameterType="int">
select * from flower where id=#{0}
select>
<insert id="ins" parameterType="flo">
insert into flower values(default,#{name},#{price},#{production})
insert>
mapper>
java测试文件:
package com.test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
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 com.pojo.Flower;
public class Test {
public static void main(String[] args) throws IOException {
//打开SqlSession
InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session= factory.openSession();
List<Flower> list = session.selectList("com.mapper.FlowerMapper.selAll");
for(Flower flower:list) {
System.out.println(flower);
}
Flower flower = session.selectOne("com.mapper.FlowerMapper.selById",2);
System.out.println(flower);
//可以直接把返回的结果集转为map,第二个参数是指定那一列当做key
Map<Integer,Flower> map = session.selectMap("com.mapper.FlowerMapper.selAll", "id");
for(int key:map.keySet()) {
System.out.println(map.get(key));
}
//插入记录
Flower flower2 = new Flower();
flower2.setName("新增花卉");
flower2.setPrice(12.56);;
flower2.setProduction("南非");
try {
//第二个参数为要插入的数据
int res = session.insert("com.mapper.FlowerMapper.ins",flower2);
if(res>0) {
System.out.println("插入成功");
}else {
System.out.println("插入失败");
}
}catch (Exception e) {
//回滚
session.rollback();
}
//提交(默认不开启自动提交,所以手动提交)
session.commit();
session.close();
}
}
对于一个mapper.xml文件,里面写了一堆sql语句,调用的时候很麻烦,我们可以创建一个接口来跟它绑定,以后直接调用接口的方法即可。
注意该接口的全限定路径即为mapper.xml文件中的namespace。
package com.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.pojo.Flower;
public interface FlowerMapper {
public List<Flower> selAll();
public List<Flower> selByIdPrice(int id,double price);
public List<Flower> selByIdNamePricePriduction(@Param("id")int id,@Param("name")String name,@Param("price")double price,@Param("production")String production);
public int upd(@Param("id")int id,@Param("name")String name);
}
注意方法的名称应与xml文件中定义的id相同,方法的调用如下
FlowerMapper flowerMapper = session.getMapper(FlowerMapper.class);
List<Flower> list = flowerMapper.selAll();
还有一个点需要注意,如果使用接口了,需要改动全局配置文件mybatis.xml中的mapper,改动如下:
<mappers>
<package name="com.mapper"/>
mappers>
当有多个参数时,xml中不用再写parameterType,示例如下:
<select id="selByIdPrice" resultType="flo">
select * from flower where id < #{arg0} and price < #{arg1}
select>
同时注意xml文件中小于号和大于号是不被允许的,解决方案见代码注释。
但是一般不使用arg0这种写法,为了可以直接写成#{id}这样的形式,在mapper接口的方法中可以添加@Param注解,例如:
public int upd(@Param("id")int id,@Param("name")String name);
当然如果参数本身不是基本数据类型,而是对象的话,可以直接写成#{对象属性名称}。
简化大量类似的sql语句的编写(这个真是好东西,深有体会),主要就是通过一些标签来做,示例如下:
<select id="selByIdNamePricePriduction" resultType="flo">
select * from flower
<where>
<if test="id!=0">
and id<#{id}
if>
<if test="price!=0">
and price<#{price}
if>
<if test="name!=null and name!=''">
and name=#{name}
if>
<if test="production!=null and production!=''">
and production=#{production}
if>
where>
select>
<update id="upd">
update flower
<set>
id=#{id},
<if test="name!=null and name!=''">
name=#{name},
if>
set>
<where>
and id=#{id}
where>
update>
还有一些其他标签,但我感觉用处不大,就不一一列举了,以后用到的时候百度一下就行了。
昨天说到了一种给pojo类起别名的方法,是直接给类起别名,但是如果实体类太多的话,不如直接使得pojo那个包能被直接识别,在mapper.xml中resultType可以直接写类名的纯小写形式,一样能够识别,以后尽量用这种方式吧。
<typeAliases>
<typeAlias type="com.pojo.Flower" alias="flo"/>
<package name="com.pojo"/>
typeAliases>
数据库的中文识别问题,这个之前没注意到,其实和直接使用jdbc的时候差不多,全局配置中把url写成以下这样既可:
<property name="url" value="jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=UTF-8"/>
注意使用原生jdbc写java代码的时候是没有amp;这个的,现在需要这个是因为在xml中&需要被转义成&才能被解析,道理和上面的> <一样。