1.导jar包
mybatis-3.5.4.jar
mysql-connector-java-5.1.47.jar
2.配置mybatis
conf.xml:配置数据库信息 和 需要加载的映射文件
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
mappers>
configuration>
注意事项:
<typeAliases>
<typeAlias type="com.xiaoming.entity.Student" alias="student">typeAlias>
<package name="com.xiaoming.entity"/>
typeAliases>
3.表 - 类
4.映射文件
xxMapper.xml : 增删改查标签
<mapper namespace="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
select>
mapper>
5.测试类Test:
session.seleceOne(“需要查询的SQL的namespace.id”,“SQL的参数值”);
a.需要获取conf.xml配置文件
//conf.xml ->reader
Reader reader = Resources.getResourceAsReader("conf.xml");
//reader -> sqlsession
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sessionFactory.openSession();
String statement = "namespace.id";
Studentinfo studentinfo = session.selectOne(statement,SQL的参数值);
(session.commit;)//需要修改数据库的则要这条 增删改需要
session.close;
约定优于配置
前四步不变,加入一个新的接口
接口规范:
测试类Test:
Reader reader = Resources.getResourceAsReader("conf.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sessionFactory.openSession();
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
studentMapper.需要调用的方法();
session.close();
1.MyBatis自带一些常见的类型处理器
int - number
2.自定义MyBatis类型处理器
java - 数据库(jdbc类型)
实例:
实体类Stu’dent : boolean stuSex true: 男
false:女
表student: number stuSex 1:男
0:女
自定义类型转换器(boolean - number)步骤:
a.创建转换器:需要实现TypeHandler接口
i.实现TypeHandler接口
ii.继承BaseTypeHandler
set: java —>数据库 get: db—>java
b.配置conf.xml:
<typeHandlers>
<typeHandler handler="com.xiaoming.converter.BooleanAndIntConverter" jdbcType="BOOLEAN" javaType="INTEGER"/>
typeHandlers>
c.StudentMapper.xml
使用了类型转换器
i.表中属性和类中字段能自动匹配(String+varchar int+number)则用resultType,不一样(boolean-int)则用resultMap
ii.表中属性名和类中字段名能够合理识别(stuNo-stuno)则用resultType,不一样(id-stuNo)则用resultMap
<resultMap id="studentResult" type="student">
<id property="stuNo" column="stuNo"/>
<result property="stuName" column="stuName"/>
<result property="stuAge" column="stuAge"/>
<result property="graName" column="graName"/>
<result property="stuSex" column="stuSex" javaType="BOOLEAN" jdbcType="INTEGER"/>
resultMap>
注意:
a.mysql数据库boolean、int 要全部大写!
b.输入参数parameterType
i.类型为 简单类型(8个基本类型+String)
1.#{} ${}
#{任意值}
${value} 其中的value必须是value
2.
#{} 会自动给String类型加上’’(单引号) (自动类型转换)
${} 原样输出 适合于动态排序 sql语句中order by ${value} 排序
3.
#{} 防止SQL注入
${} 不防止
ii.对象类型
#{属性名}
${属性名}
???
create procedure deleteStu(in sno int)
READS SQL DATA
begin
delete from student where stuno = sno;
end
CREATE PROCEDURE num_from_employee (IN emp_id INT, OUT count_num INT )
READS SQL DATA
BEGIN
SELECT COUNT(*) INTO count_num
FROM STUDENT
WHERE d_id=emp_id ;
END
1.根据姓名和年龄查询学生(返回单个学生)
xxxMapper.xml中用where if 嵌套SQL语句
例:
select stuNo,stuName,stuAge from student
<where>
<if test="stuAge != null and stuAge != 0 ">
and stuAge=#{stuAge}
if>
<if test="stuName != null and stuName != ''">
and stuName=#{stuName}
if>
where>
2.迭代
不使用foreach
select * from student
<where>
<if test="stuNos!=null and stuNos.size>0">
and stuNo in (stuNos)
if>
where>
使用foreach
select * from student
<where>
<if test="stuNos!=null and stuNos.size>0">
<foreach collection="stuNos" open="and stuNo in (" close=")" item="stuNo" separator=",">
#{stuNo}
foreach>
if>
where>
注意:collection=“stuNos” 集合 open=“and stuNo in (” open 就是集合左边的 close=")" 同理
item=“stuNo” 每个元素的名字 类似于 for 循环中的i separator=","每个元素之间的分隔符 #{stuNo}
and stuNo in (stuNos)
3.简单类型的数组:
将foreach中的if collection 的改为array
select * from student
<where>
<if test="array!=null and array.length>0">
<foreach collection="array" open=" and stuNo in (" close=")" item="stuNo" separator=",">
#{stuNo}
</foreach>
</if>
</where>
4.集合 集合用list
select * from student
<where>
<if test="list!=null and list.size>0">
<foreach collection="list" open=" and stuNo in (" close=")" item="stuNo" separator=",">
#{stuNo}
</foreach>
</if>
</where>
5.对象数组 parameterType =“Object[]” item ="数组的对象类型"其他与array一样
select * from student
<where>
<if test="array!=null and array.length>0">
<foreach collection="array" open=" and stuNo in (" close=")" item="stuNo" separator=",">
#{对象类型.stuNo}
</foreach>
</if>
</where>
6.将相同的SQL语句打包
相同的sql语句写在其中到需要引用的地方
在不同的包下面需要写包路径.xxx
A.一对一:
a.业务扩展类
resultType=“StudentBusiness” 返回类型牵连两张表的时候需要业务扩展类 业务扩展类继承一张表(较多属性的)另 一张表的属性写在业务扩展类中(包括get and set)
注意:在接口中返回类型一定是业务扩展类的类型,用父类的类型不会报错(多态)
<select id="queryStudentByNoWithOO" resultType="StudentBusiness" parameterType="int">
select s.*,c.* from student s inner join studentcard c
on s.cardid = c.cardid
where s.stuNo = #{stuNo}
select>
b.resultMap
返回类型改为resultMap id 为下列resultMap的id 其他的同上
<resultMap id="xxx" type="">
<id property="" column=""/>
<result property="" column=""/>
...
<association property="card" javaType="StudentCard">
<id property="cardId" column="cardId">id>
<result property="cardInfo" column="cardInfo">result>
association>
resultMap>
B.一对多:(MyBatis:多对一,多对多 本质是一对多)
<resultMap id="student_class_map" type="StudentClass">
<id property="classId" column="classId">id>
<result property="className" column="className">result>
<collection property="students" ofType="Student">
<id property="stuNo" column="stuNo"/>
<result property="stuName" column="stuName"/>
<result property="stuAge" column="stuAge"/>
collection>
resultMap>
1.导入log4j.jar(在MyBatis)
2.配置conf.xml (在properties后面)
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
3.创建 log4j.properties(名字必须和conf.xml中的value一样)
log4j.rootLogger = debug
# Global logging configuration 开发时候建议使用 debug
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
其中debug 有DEBUG\INFO\WARN\ERROR四种
< < <
一般在调试用DEBUG 运行用INFO
1.一对一
a.先在StudentMapper.xml配置
<select id="queryStuByNoWithOOLazy" resultMap="student_card_lazy_map" >
/*先查学生*/
select * from student
select>
<resultMap id="student_card_lazy_map" type="student">
<id property="stuNo" column="stuNo"/>
<result property="stuName" column="stuName"/>
<result property="stuAge" column="stuAge"/>
<association property="card" javaType="StudentCard" select="com.xiaoming.mapper.StudentCardMapper.queryStuCard" column="cardId">
association>
resultMap>
b创建StudentCardMapper.xml
<select id="queryStuCard" resultType="studentCard" parameterType="int">
select * from studentcard where cardid = #{cardId}
select>
注意(******):StudentMapper.xml中再查学生卡中的 select 属性为StudentCardMapper.xml 的 namespace.id 且column 为 两个表的外键属性名
c.配置conf.xml
<settings>
<setting name="logImpl" value="LOG4J"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
settings>
注意(***********):新建了xxxMapper.xml文件 一定一定要在conf.xml中配置
<mappers>
<mapper resource="com/xiaoming/mapper/StudentMapper.xml"/>
<mapper resource="com/xiaoming/mapper/StudentCardMapper.xml"/>
mappers>
d.测试
2.一对多
a.判断先查询哪个?(例如:学生信息表与班级信息表 先查询班级信息表 则创建班级信息Mapper.xml 否则在学生信息表里配置)
<select id="queryClassAndStuByLazy" resultMap="student_class_lazy_map" parameterType="int">
select * from studentclass
select>
<resultMap id="student_class_lazy_map" type="StudentClass">
<id property="classId" column="classId">id>
<result property="className" column="className">result>
<collection property="students" ofType="Student" select="com.xiaoming.mapper.StudentMapper.queryStuInClass" column="classId">
collection>
resultMap>
同一对一
注意(*******): namespace 一定一定要改!!!
b.如果是班级信息Mapper.xml则需要创建新的接口且接口名与namespace的名字相同(要与namespace对应起来)
c.然后在稍后查询的那张表的xml里配置(学生信息Mapper.xml)
<select id="queryStuInClass" parameterType="int" resultType="student">
select * from student where classid=#{classId}
</select>
d.测试
1、一级缓存
在sqlsession对象的有缓存 MyBatis默认开启一级缓存。
一级缓存:两次或两次以上查询相同的语句,不会再执行sql语句直接用sqlsession缓存的数据(省略了数据库的访问)
commit() 重新访问数据库 清空缓存
2、二级缓存
MyBatis自带二级缓存
a.在conf.xml中配置
禁用: 在XxxMapper.xml 中不用的加入
<select ......useCache="false">select>
清理: commit();
命中率: 1.zs 0%
2. 50%
3. 2/3
…
表、类、接口、mapper.xml密切相关,当知道一个的时候其他三个可以自动生成
表—>其他三个
MyBatis Generator Core.jar、slf4j-log4j12-1.7.30.jar、mybatis-generator-core-1.3.5.jar、
mysql-connector-java-5.1.47.jar
写日志文件 log4j.properties↑
创建generator.xml
<generatorConfiguration>
<context id="MybatisGenerator" targetRuntime="mybatis3">
<commentGenerator>
<property name="suppressAllComments" value="true"/>
commentGenerator>
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatis"
userId="root" password="123456">
jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
javaTypeResolver>
<javaModelGenerator targetPackage="com.xiaoMing.entity" targetProject="./src">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
javaModelGenerator>
<sqlMapGenerator targetPackage="com.xiaoMing.mapper" targetProject="./src">
<property name="enableSubPackages" value="false"/>
sqlMapGenerator>
<javaClientGenerator targetPackage="com.xiaoMing.mapper" type="XMLMAPPER" targetProject="./src">
<property name="enableSubPackages" value="false"/>
javaClientGenerator>
<table tableName="Student"/>
<table tableName="StudentCard"/>
<table tableName="StudentClass"/>
context>
generatorConfiguration>
测试类写
List<String> warnings = new ArrayList<>();
File file = new File("E:\\IDEA\\SecondMyBatis\\ThirdProject\\src\\generator.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration configuration = cp.parseConfiguration(file);
DefaultShellCallback callback = new DefaultShellCallback(true);
MyBatisGenerator generator = new MyBatisGenerator(configuration,callback,warnings);
generator.generate(null);