Mybatis

来源:互联网 发布:泰国人用淘宝吗 编辑:程序博客网 时间:2024/05/23 02:15

Mybatis是一个java的持久层框架  Github下载

 jdbc.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_mybatis
jdbc.username=root
jdbc.password=123456


mybatis-config.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 resource="jdbc.properties"/> 引入资源文件
<typeAliases>
<typeAlias alias="Student" type="com.java1234.model.Student"/> 把类建一个别名 用student来代替类
</typeAliases>
<environments default="development"> 环境 开发环境、测试环境、正式环境
<environment id="development">  
<transactionManager type="JDBC" /> 还有manager事物管理
<dataSource type="POOLED"> 连接池
<property name="driver" value="${jdbc.driverClassName}" /> 配置数据库
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<mappers> 映射器 
<mapper resource="com/java1234/mappers/StudentMapper.xml" />
</mappers>
</configuration>


public class Student {


private Integer id;
private String name;
private Integer age;



public Student() {
super();
// TODO Auto-generated constructor stub
}



public Student(String name, Integer age) {
super();
this.name = name;
this.age = age;
}


package com.java1234.util;


import java.io.InputStream;


import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;


public class SqlSessionFactoryUtil {  用来获取数据库连接获取数据库的


private static SqlSessionFactory sqlSessionFactory;

public static SqlSessionFactory getSqlSessionFactory(){
if(sqlSessionFactory==null){
InputStream inputStream=null;
try{
inputStream=Resources.getResourceAsStream("mybatis-config.xml"); 读取的文件变为一个输入流
sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); 构建build
}catch(Exception e){
e.printStackTrace();
}
}
return sqlSessionFactory;
}

public static SqlSession openSession(){
return getSqlSessionFactory().openSession(); 不能直接用returnsqlSessionFactory  要调用方法
}
}


package com.java1234.mappers;


import com.java1234.model.Student;


public interface StudentMapper { 映射接口


public int add(Student student);  返回值影响的记录
}

StudentMapper.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="com.java1234.mappers.StudentMapper"> 接口的完整路径


<insert id="add" parameterType="Student"  > add id是方法名  入参Student 如果不写typeAlias要写一个完整的路径名
insert into t_student values(null,#{name},#{age}) #的熟悉
</insert>


</mapper> 


package com.java1234.service;


import org.apache.ibatis.session.SqlSession;


import com.java1234.mappers.StudentMapper;
import com.java1234.model.Student;
import com.java1234.util.SqlSessionFactoryUtil;


public class StudentTest {


public static void main(String[] args) {
SqlSession sqlSession=SqlSessionFactoryUtil.openSession();
StudentMapper studentMapper=sqlSession.getMapper(StudentMapper.class); 类 底层 通过studentMapper直接可以调用add来操作
Student student=new Student("李四",11);
int result=studentMapper.add(student);  返回的记录数
sqlSession.commit(); 提交事物
if(result>0){ 
System.out.println("添加成功!");
}
}
}


主配置文件 日志配置

mybatis-config.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 resource="jdbc.properties"/> -->
<properties>
<property name="jdbc.driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/db_mybatis"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="123456"/>
</properties>
<!-- <typeAliases>
<typeAlias alias="Student" type="com.java1234.model.Student"/>
</typeAliases> -->
<typeAliases>
<package name="com.java1234.model"/> 包下的所有类都进行扫描都进行取别名
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC" /> JDBC用来管理应用程序的事物周期 Managed应用服务器 托管数据库连接的生命周期
<dataSource type="POOLED"> 用了连接池 JNDI 使用应用服务器配置JNDI数据源获取数据库连接 POOLED用的时候从服务器拿连接
<property name="driver" value="${jdbc.driverClassName}" /> 配置属性
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<mappers> 引入映射文件 所有orm框架都有映射文件
<!-- <mapper resource="com/java1234/mappers/StudentMapper.xml" /> --> 找xml文件
<!-- <mapper class="com.java1234.mappers.StudentMapper"/> --> 找到接口的类文件
<package name="com.java1234.mappers"/>映射文件
</mappers>
</configuration>


Log4j日志

log4j.rootLogger=info,appender1,appender2 根信息


log4j.appender.appender1=org.apache.log4j.ConsoleAppender  输出目标


log4j.appender.appender2=org.apache.log4j.FileAppender   输出到文件
log4j.appender.appender2.File=C:/logFile.txt
 
log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout 类型
log4j.appender.appender2.layout=org.apache.log4j.TTCCLayout  


package com.java1234.service;


import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;


import com.java1234.mappers.StudentMapper;
import com.java1234.model.Student;
import com.java1234.util.SqlSessionFactoryUtil;


public class StudentTest {


private static Logger logger=Logger.getLogger(StudentTest.class); main方法是static的

public static void main(String[] args) {
SqlSession sqlSession=SqlSessionFactoryUtil.openSession();
StudentMapper studentMapper=sqlSession.getMapper(StudentMapper.class);
Student student=new Student("李四",11);
int result=studentMapper.add(student);
sqlSession.commit();
if(result>0){
logger.info("添加成功!");
}
}
}


xml配置SQL映射器

package com.java1234.service;


import java.util.List;


import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;


import com.java1234.mappers.StudentMapper;
import com.java1234.model.Student;
import com.java1234.util.SqlSessionFactoryUtil;


public class StudentTest2 {


private static Logger logger=Logger.getLogger(StudentTest.class);
private SqlSession sqlSession=null; 每次都要使用sqlSession
private StudentMapper studentMapper=null; 映射器

/**
* 测试方法前调用
* @throws Exception
*/
@Before
public void setUp() throws Exception {
sqlSession=SqlSessionFactoryUtil.openSession();
studentMapper=sqlSession.getMapper(StudentMapper.class);
}


/**
* 测试方法后调用
* @throws Exception
*/
@After
public void tearDown() throws Exception {
sqlSession.close();
}


@Test
public void testAdd() {
logger.info("添加学生"); 规范
Student student=new Student("王五",12);
studentMapper.add(student); 已经有了映射器
sqlSession.commit();
}

@Test
public void testUpdate(){
logger.info("修改学生");
Student student=new Student(8,"王五2",13); 重载构造器 new一个实体
studentMapper.update(student);
sqlSession.commit();
}

@Test
public void testDelete(){
logger.info("删除学生");
studentMapper.delete(8); 构造方法id
sqlSession.commit();
}

@Test
public void testFindById(){
logger.info("通过ID查找学生");
Student student=studentMapper.findById(1); 查询不需要提交事物
System.out.println(student); 重写toString
}


@Test
public void testFind(){
logger.info("查找所有学生");
List<Student> studentList=studentMapper.find();
for(Student s:studentList){
System.out.println(s);
}
}
}


public interface StudentMapper {


public int add(Student student);

public int update(Student student);

public int delete(Integer id);

public Student findById(Integer id); 通过id来寻找学生

public List<Student> find(); 查询全部分页查询
}


<?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="com.java1234.mappers.StudentMapper">


<resultMap type="Student" id="StudentResult"> 专门定义一个返回的结果 type集合的每一个元素Student
<id property="id" column="id"/> 主键 column 对应数据库的id 数据库和modl要一致
<result property="name" column="name"/>
<result property="age" column="age"/>
</resultMap>


<insert id="add" parameterType="Student"  >
insert into t_student values(null,#{name},#{age})
</insert>


<update id="update" parameterType="Student"> id接口方法对应
update t_student set name=#{name},age=#{age} where id=#{id}
</update>

<delete id="delete" parameterType="Integer">
delete from t_student where id=#{id} 所有的数据都是入参中取的
</delete>

<select id="findById" parameterType="Integer" resultType="Student"> 即有入参又有返回参数 resultType返回的类型
select * from t_student where id=#{id}
</select>

<select id="find" resultMap="StudentResult"> 返回的是一个集合 自定义的id
select * from t_student
</select>
</mapper> 


关系映射一对一

一个学生一个地址

public class Address {


private Integer id;
private String sheng;
private String shi;
private String qu;


public class Student {


private Integer id;
private String name;
private Integer age;
private Address address;

@Test
public void testFindStudentWithAddress() {
logger.info("查询学生(带地址)");
Student student=studentMapper.findStudentWithAddress(2);
System.out.println(student);
}

对象级联

StudentMapper.xml

<!-- <resultMap type="Student" id="StudentResult">
<id property="id" column="id"/>
<result property="name" column="name"/> 
<result property="age" column="age"/>

<result property="address.id" column="addressId"/> column 外键的名字
<result property="address.sheng" column="sheng"/>
<result property="address.shi" column="shi"/>
<result property="address.qu" column="qu"/>
</resultMap> -->

<select id="findStudentWithAddress" resultMap="StudentResult" parameterType="Integer">   resultMap是上面的id
select * from t_student t1,t_address t2 where t1.addressId=t2.id and t1.id=#{id} 两张表的关联查询# id是test
</select>


StudentMapper.java

public Student findStudentWithAddress(Integer id); 通过学生id查询学生

把address独立处理

<resultMap type="Address" id="AddressResult">
<result property="id" column="id"/>  column主键
<result property="sheng" column="sheng"/>
<result property="shi" column="shi"/>
<result property="qu" column="qu"/>
</resultMap>


<resultMap type="Student" id="StudentResult">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<association property="address" resultMap="AddressResult"/> properties属性类里面的 关联上面的id
</resultMap> 


直接嵌套进去

<resultMap type="Student" id="StudentResult">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<association property="address" javaType="Address"> 类里面的属性
<result property="id" column="id"/>
<result property="sheng" column="sheng"/>
<result property="shi" column="shi"/>
<result property="qu" column="qu"/>
</association>
</resultMap>

开发模式

AddressMapper.java

package com.java1234.mappers;


import com.java1234.model.Address;


public interface AddressMapper {


public Address findById(Integer id);


}

AddressMapper.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="com.java1234.mappers.AddressMapper">


<resultMap type="Address" id="AddressResult">
<result property="id" column="id"/>
<result property="sheng" column="sheng"/>
<result property="shi" column="shi"/>
<result property="qu" column="qu"/>
</resultMap>

<select id="findById" parameterType="Integer" resultType="Address">
select * from t_address where id=#{id}
</select>


</mapper> 


<resultMap type="Student" id="StudentResult">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<association property="address" column="addressid" select="com.java1234.mappers.AddressMapper.findById"></association> 关联address对象 columb对应student表的外键  映射到接口方法 传进去的是id 
</resultMap>

<select id="findStudentWithAddress" resultMap="StudentResult" parameterType="Integer">
select * from t_student t1,t_address t2 where t1.addressId=t2.id and t1.id=#{id}
</select>


一对多

一个年级有很多学生

public class Grade {


private Integer id;
private String gradeName;
private List<Student> students; 通过年级找学生



public class Student {


private Integer id;
private String name;
private Integer age;
private Address address;
private Grade grade; 数据库表示gradeId外键

GradeMapper.java

public interface GradeMapper {


public Grade findById(Integer id);


}


<?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="com.java1234.mappers.GradeMapper">


<resultMap type="Grade" id="GradeResult">
<result property="id" column="id"/>
<result property="gradeName" column="gradeName"/>
<collection property="students" column="id" select="com.java1234.mappers.StudentMapper.findByGradeId"></collection> 去查找 带id主键 一对多家collection
</resultMap>

<select id="findById" parameterType="Integer" resultMap="GradeResult">
select * from t_grade where id=#{id} 传入一个id
</select>


</mapper> 

StudentMapper.java

public Student findByGradeId(Integer gradeId);

<select id="findByGradeId" resultMap="StudentResult" parameterType="Integer">
select * from t_student where gradeId=#{gradeId}
</select>


@Test 测试一对多
public void testFindGradeWithStudents() {
logger.info("查询年级(带学生)");
Grade grade=gradeMapper.findById(1);
System.out.println(grade); 重写grade的tostring
}

从学生端查询也要查询年级、

StudentMapper.xml

<resultMap type="Student" id="StudentResult">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<association property="address" column="addressId" select="com.java1234.mappers.AddressMapper.findById"></association>
<association property="grade" column="gradeId" select="com.java1234.mappers.GradeMapper.findById"></association>grade属性  column student 的外键 带一个外键过去
</resultMap>


@Test
public void testFindStudentWithGrade(){
logger.info("查询学生(带年级)");
Student student=studentMapper.findStudentWithAddress(1);
System.out.println(student);
}

@Override  互相打印死循环
public String toString() {
return "Grade [id=" + id + ", gradeName=" + gradeName +"]";
}


@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age
+ ", address=" + address + ", grade=" + grade + "]";
}


动态sql

public interface StudentMapper {


public List<Student> searchStudents(Map<String,Object> map);

public List<Student> searchStudents2(Map<String,Object> map);
}


<?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="com.java1234.mappers.StudentMapper">


<resultMap type="Student" id="StudentResult">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
</resultMap>

<select id="searchStudents" parameterType="Map" resultMap="StudentResult">
select * from t_student  条件个数不知道
where gradeId=#{gradeId} 指定年级下的学生
<if test="name!=null"> 有可能带name条件
and name like #{name} 拼接 模糊查询
</if>
<if test="age!=nulll">
and age=#{age} age是= integer
</if>
</select>

<select id="searchStudents2" parameterType="Map" resultMap="StudentResult">
select * from t_student 
<choose> 为了开发的方便 一个搜索框 选个下拉框选择根据什么来查询
<when test="searchBy=='gradeId'">
where gradeId=#{gradeId}
</when>
<when test="searchBy=='name'"> 标志通过某一个字段来查询
where name like #{name}
</when>
<otherwise>
where age=#{age}
</otherwise>
</choose>
 
</select>
</mapper> 


@Test
public void testSearchStudents() {
logger.info("添加学生(带条件)");
Map<String,Object> map=new HashMap<String,Object>();
map.put("gradeId", 2);
// map.put("name", "%李%");
// map.put("age", 11);
List<Student> studentList=studentMapper.searchStudents(map);
for(Student student:studentList){
System.out.println(student);
}
}

@Test
public void testSearchStudents2() {
logger.info("添加学生(带条件)");
Map<String,Object> map=new HashMap<String,Object>();
map.put("searchBy", "age"); 根据年级来搜索
map.put("gradeId", 2);
map.put("name", "%李%");
map.put("age", 11);
List<Student> studentList=studentMapper.searchStudents2(map);
for(Student student:studentList){
System.out.println(student);
}
}


StudentMapper.java

public List<Student> searchStudents3(Map<String,Object> map);

public List<Student> searchStudents4(Map<String,Object> map);

public List<Student> searchStudents5(Map<String,Object> map);

public int updateStudent(Student student);

xml

<select id="searchStudents3" parameterType="Map" resultMap="StudentResult">
select * from t_student 
<where> 条件不符合 and 会把第一个and or去掉
<if test="gradeId!=null">
gradeId=#{gradeId}
</if>
<if test="name!=null">
and name like #{name}
</if>
<if test="age!=nulll">
and age=#{age}
</if>
</where>
</select>

<select id="searchStudents4" parameterType="Map" resultMap="StudentResult">
select * from t_student 
<trim prefix="where" prefixOverrides="and|or">
<if test="gradeId!=null">
gradeId=#{gradeId}
</if>
<if test="name!=null">
and name like #{name}
</if>
<if test="age!=nulll">
and age=#{age}
</if>
</trim>
</select>

<select id="searchStudents5" parameterType="Map" resultMap="StudentResult">
select * from t_student 
<if test="gradeIds!=null"> 某个年纪小的学生  gradeIds 集合
<where>
gradeId in 集合in
<foreach item="gradeId" collection="gradeIds" open="(" separator="," close=")"> 每次遍历去一个元素放在gradeIds中 (,)
#{gradeId} 每次取到的数值
</foreach>
</where>
</if>
</select>

<update id="updateStudent" parameterType="Student">
update t_student
<set> 更新的时候使用
<if test="name!=null">
name=#{name},
</if>
<if test="age!=null">
age=#{age},
</if>
</set>
where id=#{id}
</update>


@Test
public void testSearchStudents3() {
logger.info("添加学生(带条件)");
Map<String,Object> map=new HashMap<String,Object>();
map.put("gradeId", 2);  where都可以加上
map.put("name", "%李%");
map.put("age", 11);
List<Student> studentList=studentMapper.searchStudents3(map);
for(Student student:studentList){
System.out.println(student);
}
}

@Test
public void testSearchStudents4() {
logger.info("添加学生(带条件)");
Map<String,Object> map=new HashMap<String,Object>();
map.put("gradeId", 2);
// map.put("name", "%李%");
// map.put("age", 11);
List<Student> studentList=studentMapper.searchStudents4(map);
for(Student student:studentList){
System.out.println(student);
}
}

@Test
public void testSearchStudents5() {
logger.info("添加学生(带条件)");
Map<String,Object> map=new HashMap<String,Object>();
List<Integer> gradeIds=new ArrayList<Integer>();
// gradeIds.add(1);
gradeIds.add(2); 添加1年级
map.put("gradeIds", gradeIds);
List<Student> studentList=studentMapper.searchStudents5(map);
for(Student student:studentList){
System.out.println(student);
}
}

@Test
public void testUpdateStudent(){
logger.info("更新学生(带条件)");
Student student=new Student();
student.setId(1);
student.setName("张三3");
student.setAge(13);
studentMapper.updateStudent(student);
sqlSession.commit();
}


处理CLOB BLOB Blob(二进制图片,电影,音乐)

public class Student {


private Integer id;
private String name;
private Integer age;
private byte[] pic;
private String remark;

public String toString() {  pic流来处理
return "Student [id=" + id + ", name=" + name + ", age=" + age
+ ", remark=" + remark + "]";
}


StudentMapper.java

public int insertStudent(Student student);

public Student getStudentById(Integer id);


StudentMapper.xml

<insert id="insertStudent" parameterType="Student">
insert into t_student values(null,#{name},#{age},#{pic},#{remark});
</insert>


<select id="getStudentById" parameterType="Integer" resultType="Student"> 映射文件  resultType类型
select * from t_student where id=#{id}
</select>


@Test
public void testInsertStudent(){
logger.info("添加学生");
Student student=new Student();
student.setName("张三4");
student.setAge(14);
student.setRemark("很长的本文...");
byte []pic=null;
try{
File file=new File("c://boy.jpg");
InputStream inputStream=new FileInputStream(file); 读的时候输入流 取的时候输出流
pic=new byte[inputStream.available()]; 长度是avaliable
inputStream.read(pic);
inputStream.close();
}catch(Exception e){
e.printStackTrace();
}
student.setPic(pic);
studentMapper.insertStudent(student);
sqlSession.commit();
}

@Test
public void testGetStudentById(){
logger.info("通过ID查找学生");
Student student=studentMapper.getStudentById(4);
System.out.println(student);
byte []pic=student.getPic();
try{
File file=new File("d://boy2.jpg");
OutputStream outputStream=new FileOutputStream(file);
outputStream.write(pic);
outputStream.close();
}catch(Exception e){
e.printStackTrace();
}
}


传入多个参数HashMap Map

public List<Student> searchStudents6(String name,int age);  通过name和age来查询


<resultMap type="Student" id="StudentResult">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
</resultMap>

<select id="searchStudents6" resultMap="StudentResult">
select * from t_student where name like #{param1} and age=#{param2} 内置param参数指定 
</select>


@Test
public void testSearchStudents6() {
logger.info("添加学生(带条件)");
List<Student> studentList=studentMapper.searchStudents6("%3%",12);
for(Student student:studentList){
System.out.println(student);
}
}


Mybatis逻辑分页 先把100条数据取出来放在内存里 从内存里取10条

public List<Student> findStudents(RowBounds rowBounds);



<select id="findStudents" resultMap="StudentResult" flushCache="false" useCache="true">  resultMap返回的Student 
select * from t_student
</select>


@Test
public void testFindStudent(){
logger.info("查询学生");
int offset=0,limit=3;  从第0个开始取三个
RowBounds rowBounds=new RowBounds(offset,limit); 定义参数rowBounds 参数第一个是start 第二个limit每页大小
List<Student> studentList=studentMapper.findStudents(rowBounds); 返回的是集合
for(Student student:studentList){
System.out.println(student);
}
}


真正参数是map 物理分页

public List<Student> findStudents2(Map<String,Object> map);

<select id="findStudents2" parameterType="Map" resultMap="StudentResult">
select * from t_student
<if test="start!=null and size!=null"> 每页大小
limit #{start},#{size} 拼接一下
</if>
</select>


@Test
public void testFindStudent2(){
logger.info("查询学生");
Map<String,Object> map=new HashMap<String,Object>();
map.put("start", 3); 从3开始
map.put("size", 3); 取3条数据
List<Student> studentList=studentMapper.findStudents2(map);
for(Student student:studentList){
System.out.println(student);
}
}


Mybatis缓存 并发量大

<mapper namespace="com.java1234.mappers.StudentMapper">

配置一定要放在nameSpace下
<!--
    1,size:表示缓存cache中能容纳的最大元素数。默认是1024;
    2,flushInterval:定义缓存刷新周期,以毫秒计;
      3,eviction:定义缓存的移除机制;默认是LRU(least recently userd,最近最少使用),还有FIFO(first in first out,先进先出)
      4,readOnly:默认值是false,假如是true的话,缓存只能读。
     -->
<cache size="1024" flushInterval="60000" eviction="LRU" readOnly="false"/> 实际只有查询用到缓存


<select id="findStudents" resultMap="StudentResult" flushCache="false" useCache="true">  flush 清空缓存
select * from t_student
</select>


<insert id="insertStudent" parameterType="Student" flushCache="true"> update delete都是true
insert into t_student values(null,#{name},#{age},#{pic},#{remark});
</insert>


注解配置 不够灵活 不支持所有的功能

public interface StudentMapper {


@Insert("insert into t_student values(null,#{name},#{age})")
public int insertStudent(Student student);

@Update("update t_student set name=#{name},age=#{age} where id=#{id}")
public int updateStudent(Student student);

@Delete("delete from t_student where id=#{id}")
public int deleteStudent(int id);

@Select("select * from t_student where id=#{id}")
public Student getStudentById(Integer id);

@Select("select * from t_student")
@Results(
{
@Result(id=true,column="id",property="id"), 定义每一个字段的映射 id true主键
@Result(column="name",property="name"),
@Result(column="age",property="age")
}
)
public List<Student> findStudents(); 查询所有结果集 返回集合

}


public class StudentTest {


private static Logger logger=Logger.getLogger(StudentTest.class);
private SqlSession sqlSession=null;
private StudentMapper studentMapper=null;

/**
* 测试方法前调用
* @throws Exception
*/
@Before
public void setUp() throws Exception {
sqlSession=SqlSessionFactoryUtil.openSession();
studentMapper=sqlSession.getMapper(StudentMapper.class);
}


/**
* 测试方法后调用
* @throws Exception
*/
@After
public void tearDown() throws Exception {
sqlSession.close();
}


@Test
public void testInsert() {
logger.info("添加学生");
Student student=new Student("琪琪",11);
studentMapper.insertStudent(student);
sqlSession.commit();
}

@Test
public void testUpdate() {
logger.info("更新学生");
Student student=new Student(6,"琪琪2",12);
studentMapper.updateStudent(student);
sqlSession.commit();
}

@Test
public void testDelete() {
logger.info("删除学生");
studentMapper.deleteStudent(6);
sqlSession.commit();
}

@Test
public void testGetById() {
logger.info("通过ID查找学生");
Student student=studentMapper.getStudentById(1);
System.out.println(student);
}

@Test
public void testFindStudents() {
logger.info("查找所有学生");
List<Student> studentList=studentMapper.findStudents();
for(Student student:studentList){
System.out.println(student);
}
}


}


注解关系映射

查询学生的时候把地址查询出来 一对一关联

public class Student {


private Integer id;
private String name;
private Integer age;
private Address address;
private Grade grade;


StudentMapper.java

@Select("select * from t_student where id=#{id}") 学生的id
@Results(
{
@Result(id=true,column="id",property="id"),
@Result(column="name",property="name"),
@Result(column="age",property="age"),
@Result(column="addressId",property="address",one=@One(select="com.java1234.mappers.AddressMapper.findById")) 查询address信息 column是student的外键穿一个id给address的方法入参  property student的属性
}
)
public Student selectStudentWithAddress(int id); 



带一个id过去

AddressMapper.java
public interface AddressMapper {


@Select("select * from t_address where id=#{id}") 那边的外键到这就是主键了
public Address findById(Integer id);


}

@Test
public void testSelectStudentWithAddress() {
logger.info("查找学生(带地址)");
Student student=studentMapper.selectStudentWithAddress(3); 
System.out.println(student);
}


多对一 一对多

一个年级很多学生

public class Grade {


private Integer id;
private String gradeName;
private List<Student> students;


public class Student {


private Integer id;
private String name;
private Integer age;
private Address address;
private Grade grade;

@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age
+ ", address=" + address + ", grade=" + grade + "]";
}


public interface GradeMapper {


@Select("select * from t_grade where id=#{id}")
@Results( 映射
{
@Result(id=true,column="id",property="id"),
@Result(column="gradeName",property="gradeName"),
@Result(column="id",property="students",many=@Many(select="com.java1234.mappers.StudentMapper.selectStudentByGradeId")) 吧grade的主键带过去给student properties属性是一个集合 many=@Many 一对多 
}
)
public Grade findById(Integer id);

}

StudentMapper.java

@Select("select * from t_student where gradeId=#{gradeId}")
@Results(
{
@Result(id=true,column="id",property="id"),
@Result(column="name",property="name"),
@Result(column="age",property="age"),
@Result(column="addressId",property="address",one=@One(select="com.java1234.mappers.AddressMapper.findById")) 通过外键来查询学生
}
)
public Student selectStudentByGradeId(int gradeId);



private static Logger logger=Logger.getLogger(StudentTest2.class);
private SqlSession sqlSession=null;
private StudentMapper studentMapper=null;
private GradeMapper gradeMapper=null;

/**
* 测试方法前调用
* @throws Exception
*/
@Before
public void setUp() throws Exception {
sqlSession=SqlSessionFactoryUtil.openSession();
studentMapper=sqlSession.getMapper(StudentMapper.class);
gradeMapper=sqlSession.getMapper(GradeMapper.class);
}


/**
* 测试方法后调用
* @throws Exception
*/
@After
public void tearDown() throws Exception {
sqlSession.close();
}

@Test
public void testSelectGradeWithStudents() {
logger.info("查找年级(带学生)");
Grade grade=gradeMapper.findById(2);
System.out.println(grade);
List<Student> studentList=grade.getStudents();
for(Student student:studentList){
System.out.println(student);
}
}

注解容易报错 报错重写toString


双向

查询的时候带年级

@Select("select * from t_student where id=#{id}")
@Results(
{
@Result(id=true,column="id",property="id"),
@Result(column="name",property="name"),
@Result(column="age",property="age"),
@Result(column="addressId",property="address",one=@One(select="com.java1234.mappers.AddressMapper.findById")),
@Result(column="gradeId",property="grade",one=@One(select="com.java1234.mappers.GradeMapper.findById"))
}
)
public Student selectStudentWithAddressAndGrade(int id);
}


@Test
public void testSelectStudentWithAddressAndGrade() {
logger.info("查找学生(带年级,带地址)");
Student student=studentMapper.selectStudentWithAddressAndGrade(1);
System.out.println(student);
}


动态sql注解

StudentDynaSqlProvider.java


public String insertStudent(final Student student){ 匿名内部类用final
return new SQL(){ 最终返回动态拼接完的sql
{
INSERT_INTO("t_student");
if(student.getName()!=null){
VALUES("name", "#{name}");
}
if(student.getAge()!=null){
VALUES("age", "#{age}"); "#{age}"参数可以不屑student,getName()
}
}
}.toString();
}


public interface StudentMapper {


@InsertProvider(type=StudentDynaSqlProvider.class,method="insertStudent")
public int insertStudent(Student student);

@Test
public void testInsert() {
logger.info("添加学生");
Student student=new Student("琪琪",11);
studentMapper.insertStudent(student);
sqlSession.commit();
}


public String updateStudent(final Student student){
return new SQL(){
{
UPDATE("t_student");
if(student.getName()!=null){
SET("name=#{name}"); 更新set
}
if(student.getAge()!=null){
SET("age=#{age}");
}
WHERE("id=#{id}");
}
}.toString();
}

@UpdateProvider(type=StudentDynaSqlProvider.class,method="updateStudent")
public int updateStudent(Student student);

@Test
public void testUpdate() {
logger.info("更新学生");
Student student=new Student(6,"琪琪2",12);
studentMapper.updateStudent(student);
sqlSession.commit();
}


public String deleteStudent(){
return new SQL(){
{
DELETE_FROM("t_student");
WHERE("id=#{id}");
}
}.toString();
}

@DeleteProvider(type=StudentDynaSqlProvider.class,method="deleteStudent")
public int deleteStudent(int id);

@Test
public void testDelete() {
logger.info("删除学生");
studentMapper.deleteStudent(6);
sqlSession.commit();
}


public String getStudentById(){
return new SQL(){
{
SELECT("*");
FROM("t_student");
WHERE("id=#{id}");
}
}.toString();
}

@SelectProvider(type=StudentDynaSqlProvider.class,method="getStudentById")
public Student getStudentById(Integer id);

@Test
public void testGetById() {
logger.info("通过ID查找学生");
Student student=studentMapper.getStudentById(1);
System.out.println(student);
}


public String findStudents(final Map<String,Object> map){  有条件的用map
return new SQL(){
{
SELECT("*");
FROM("t_student");
StringBuffer sb=new StringBuffer();
if(map.get("name")!=null){
sb.append(" and name like '"+map.get("name")+"'");
}
if(map.get("age")!=null){
sb.append(" and age="+map.get("age"));
}
if(!sb.toString().equals("")){ sql什么都没有拼where条件不需要的
WHERE(sb.toString().replaceFirst("and", "")); 去掉第一个and 
}
}
}.toString();
}

@SelectProvider(type=StudentDynaSqlProvider.class,method="findStudents")
public List<Student> findStudents(Map<String,Object> map);

@Test
public void testFindStudents() {
logger.info("查找所有学生");
Map<String,Object> map=new HashMap<String,Object>();
// map.put("name", "%张%");
// map.put("age", 12);
List<Student> studentList=studentMapper.findStudents(map);
for(Student student:studentList){
System.out.println(student);
}
}


Mybatis Spring SpringMVC整合

spring与SpringMVC整合

log4j.properties

log4j.rootLogger=info,appender1,appender2


log4j.appender.appender1=org.apache.log4j.ConsoleAppender 


log4j.appender.appender2=org.apache.log4j.FileAppender 
log4j.appender.appender2.File=C:/logFile.txt
 
log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout
log4j.appender.appender2.layout=org.apache.log4j.TTCCLayout  


web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>MyBatisPro05</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
    <!-- Spring配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 编码过滤器 --> 默认ISO 8859-1
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- 添加对springmvc的支持 -->
<servlet>
<servlet-name>springMVC</servlet-name> 当做servlet
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup> 1 启动
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>


spring-mvc.xml 

<?xml version="1.0" encoding="UTF-8"?>    
<beans xmlns="http://www.springframework.org/schema/beans"    
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    xmlns:p="http://www.springframework.org/schema/p"  
    xmlns:aop="http://www.springframework.org/schema/aop"   
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:jee="http://www.springframework.org/schema/jee"  
    xmlns:tx="http://www.springframework.org/schema/tx"  
    xsi:schemaLocation="    
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd  
        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/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd  
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">    


<!-- 使用注解的包,包括子集 -->
<context:component-scan base-package="com.java1234.controller" /> 扫描下面的所有类作为controller层的类


<!-- 视图解析器 --> 解析controller返回的东西 解析.jsp的后缀
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/" />
<property name="suffix" value=".jsp"></property>
</bean>


</beans>  


applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>    
<beans xmlns="http://www.springframework.org/schema/beans"    
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    xmlns:p="http://www.springframework.org/schema/p"  
    xmlns:aop="http://www.springframework.org/schema/aop"   
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:jee="http://www.springframework.org/schema/jee"  
    xmlns:tx="http://www.springframework.org/schema/tx"  
    xsi:schemaLocation="    
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd  
        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/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd  
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">    
        
<!-- 自动扫描 -->
<context:component-scan base-package="com.java1234.dao" /> Mybatis的所有接口定义在dao下面 controller不用扫描
<context:component-scan base-package="com.java1234.service" />

<!-- 配置数据源 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/db_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>


<!-- 配置mybatis的sqlSessionFactory -->  sessionFactory由spring提供的
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描mappers.xml文件 --> 扫描所有的映射文件
<property name="mapperLocations" value="classpath:com/java1234/mappers/*.xml"></property>
<!-- mybatis配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>


<!-- DAO接口所在包名,Spring会自动查找其下的类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.java1234.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> 主要注入bean
</bean>


<!-- (事务管理)transaction manager, use JtaTransactionManager for global tx --> 所有spring都要用到
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

<!-- 配置事务通知属性 -->  
    <tx:advice id="txAdvice" transaction-manager="transactionManager">  
        <!-- 定义事务传播属性 -->  
        <tx:attributes>  
            <tx:method name="insert*" propagation="REQUIRED" />  
            <tx:method name="update*" propagation="REQUIRED" />  
            <tx:method name="edit*" propagation="REQUIRED" />  
            <tx:method name="save*" propagation="REQUIRED" />  
            <tx:method name="add*" propagation="REQUIRED" />  
            <tx:method name="new*" propagation="REQUIRED" />  
            <tx:method name="set*" propagation="REQUIRED" />  
            <tx:method name="remove*" propagation="REQUIRED" />  
            <tx:method name="delete*" propagation="REQUIRED" />  
            <tx:method name="change*" propagation="REQUIRED" />  
            <tx:method name="get*" propagation="REQUIRED" read-only="true" />  
            <tx:method name="find*" propagation="REQUIRED" read-only="true" />  
            <tx:method name="load*" propagation="REQUIRED" read-only="true" />  
            <tx:method name="*" propagation="REQUIRED" read-only="true" />  
        </tx:attributes>  
    </tx:advice>  
  
    <!-- 配置事务切面 -->  
    <aop:config>  
        <aop:pointcut id="serviceOperation"  
            expression="execution(* com.java1234.service.*.*(..))" />  
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />  
    </aop:config>  


</beans>



mybatis-config.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>
<!-- 别名 -->
<typeAliases>
<package name="com.java1234.entity"/>  所有下面的都别名 不然得写全
</typeAliases>
</configuration>



User.java

package com.java1234.entity;


public class User {


private Integer id;
private String userName;
private String password;

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 getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}


}



UserDao.java

package com.java1234.dao;


import com.java1234.entity.User;


public interface UserDao { 接口 实现mybatis去实现


public User login(User user);  实现mybatise实现  sessionFactory  mappers实现 没查到返回null 查到包含所有用户信息字段
}


UserMapper.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="com.java1234.dao.UserDao">


<resultMap type="User" id="UserResult">结果集 type mybatis别名 
<result property="id" column="id"/>
<result property="userName" column="userName"/>
<result property="password" column="password"/>
</resultMap>

<select id="login" parameterType="User" resultMap="UserResult">  id方法名 User传入的对象
select * from t_user where userName=#{userName} and password=#{password}
</select>


</mapper> 


UserService.java

package com.java1234.service;


import com.java1234.entity.User;


public interface UserService {


public User login(User user);
}


UserServiceImpl.java

package com.java1234.service.impl;


import javax.annotation.Resource;


import org.springframework.stereotype.Service;


import com.java1234.dao.UserDao;
import com.java1234.entity.User;
import com.java1234.service.UserService;


@Service("userService") spring把所有DAOmybatise的实现变为bean,通过注解实现bean
public class UserServiceImpl implements UserService{ 实现类 实现方法


@Resource 注入DAO
private UserDao userDao; 名字取类名 规范

@Override
public User login(User user) {
return userDao.login(user);
}


}


UserController.java

package com.java1234.controller;


import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;


import com.java1234.entity.User;
import com.java1234.service.UserService;


@Controller 
@RequestMapping("/user")
public class UserController {


@Resource 接口中的方法
private UserService userService;

@RequestMapping("/login")
public String login(User user,HttpServletRequest request){ 返回的是String  user实体 需要session 
User resultUser=userService.login(user); 前台封装的数据
if(resultUser==null){ 没查到数据
request.setAttribute("user", user);
request.setAttribute("errorMsg", "用户名或密码错误!");
return "index"; spring接收到 在spring-mvc.xml do
}else{
HttpSession session=request.getSession();
session.setAttribute("currentUser", resultUser); 把查到的数据放到
return "redirect:/success.jsp";
}
}
}


index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/user/login.do" method="post"> action请求的controller会写controller映射login 
userName:<input type="text" name="userName" value="${user.userName }"/><br/> 前面的数据也要回显
password:<input type="password" name="password" value="${user.password }"><br/>
<input type="submit" value="login"/><font color="red">${errorMsg }</font> 错误转发到index.jsp 
</form>
</body>
</html>


success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
欢迎:${currentUser.userName }
</body>
</html>


server ADD and Remove  Add  finish  debug

http://localhost:8080/Mybatis05