可以通过索引的方式获取 索引从0开始 也可用param1 param2Mybatis安装
要使用 MyBatis, 只需将 mybatis-x.x.x.jar 文件置于 classpath 中即可
官网 http://mybatis.github.io/
下载路径:https://github.com/mybatis/mybatis-3/releases
文档:http://mybatis.github.io/mybatis-3/zh/getting-started.html
pom.xml
<!-- 配置mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
MyBatis简介
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
Mybatis入门配置
从 XML 中构建 SqlSessionFactory:
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。
public class Test {
public static void main(String[] args) throws IOException {
String resource = "com/et/lesson01/mybatis.xml";
//获取文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//工厂类
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//session 操作的是执行sql语句的一个唯一标识符
SqlSession session=sqlSessionFactory.openSession();
List list=session.selectList("selectFood");
System.out.println(list);
mybatis的核心配置
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>
<!--1.数据库的连接信息 告诉properties文件位置 -->
<properties resource="jdbc.properties">
</properties>
<environments default="development">
<environment id="development">
<!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
<mapper resource="com/et/lesson01/test/foodMapper.xml" />
</mappers>
</configuration>
foodMapper.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">
<!-- namespace命名空间 多个文件中的相同id
比如 a.xml (namespace=a)
id="test"
b.xml (namespace=b)
id="test"
a.test
b.test
-->
<mapper namespace="a">
<select id="selectFood" resultType="java.util.Map">
select * from food
</select>
<select id="selectFoodById" resultType="java.util.Map" >
select * from food where foodid=1
</select>
<!--FOOD_SEC.nextval 序列通过下一个值找到主键-->
<insert id="saveFood">
insert into food values(FOOD_SEC.nextval,#{foodname},#{price})
</insert>
<insert id="insertFood" parameterType="java.util.Map">
insert into food(FOODID,FOODNAME,PRICE) values(#{foodid},#{foodname},#{price})
</insert>
<delete id="deleteFood" parameterType="java.util.Map">
<!--
delete from FOOD where FOODID=5
-->
delete from FOOD where FOODID=#{foodid}
</delete>
<update id="updateFood" parameterType="java.util.Map" >
<!-- update FOOD set FOODNAME='酸辣土豆丝' where FOODID =4 -->
update FOOD set FOODNAME=#{foodname},PRICE=#{price} where FOODID =#{foodid}
</update>
</mapper>
public class Test {
public static void main(String[] args) throws IOException {
String resource = "com/et/lesson01/mybatis.xml";
//获取文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//工厂类
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//session 操作的是执行sql语句的一个唯一标识符
SqlSession session=sqlSessionFactory.openSession();
List list=session.selectList("selectFood");
System.out.println(list);
//通过id查找
Map map=(Map)session.selectOne("selectFoodById");
System.out.println(map);
/* //添加
Map map1=new HashMap();
map1.put("foodid", "5");
map1.put("foodname", "酸辣土豆丝");
map1.put("price", "155");
session.insert("insertFood", map1);
System.out.println(map1);
//删除
session.delete("deleteFood");
session.commit();
//修改
session.update("a.updateFood");
session.commit();*/
//删除
/*Map map1=new HashMap();
map1.put("foodid", "4");
session.delete("deleteFood", map1);
session.commit();
System.out.println(map1);*/
//修改
Map map1=new HashMap();
map1.put("foodid", "1");
map1.put("foodname", "酸辣土豆丝");
map1.put("price", "20");
session.update("updateFood", map1);
session.commit();
System.out.println(map1);
}
@Test
public void saveFood() throws IOException{
SqlSession session=getSession();
Food food=new Food();
food.setPrice("100");
food.setFoodname("回锅肉");
session.insert("a.saveFood", food);
session.commit();
}
}
mybatis参数传递的方式有两种
第一种方式
<!--使用#{键}方式 实际上是使用占位符 问号(?) 来替代
可以通过索引的方式获取 索引从0开始 也可用param1 param2
-->
<select id="selectFoodParam" resultType="java.util.Map">
select * from food where price=#{price} and foodname=#{foodname}
</select>
第二中方式
<!--使用${键}方式 使用是直接替换对应的的键 注意如果是字符串说过添加'' -->
<select id="selectFoodByParam" resultType="java.util.Map">
select * from food where price=${price} and foodname='${foodname}'
</select>
通过map和对象都可以传值
public class MyTest {
public static SqlSession getSession() throws IOException{
String resource = "com/et/lesson01/test/mybatis.xml";
//获取文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//工厂类
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//session 操作的是执行sql语句的一个唯一标识符
SqlSession session=sqlSessionFactory.openSession();
return session;
}
@Test
public void QueryFood() throws IOException{
SqlSession session=getSession();
Map map=new HashMap();
map.put("price", 60);
map.put("foodname", "大盘鸡");
List list = session.selectList("a.selectFoodByParam", map);
System.out.println(list);
}
/**
*通过对象传值(面向对象)
* @throws IOException
*/
//@Test
public void FoodAll() throws IOException{
SqlSession session=getSession();
Food food=new Food();
food.setPrice("60");
food.setFoodname("大盘鸡");
List list = session.selectList("a.selectFoodByParam", food);
System.out.println(list);
}
}
实体类
public class Food {
private String foodname;
private String price;
public Food(){
}
public Food(String foodname, String price) {
super();
this.foodname = foodname;
this.price = price;
}
public String getFoodname() {
return foodname;
}
public void setFoodname(String foodname) {
this.foodname = foodname;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
自定义log日志及日志的打印
### 全局控制机制 ###
log4j.rootLogger = debug , a
# log4j日志分为 5种级别
# debug 调试 (开发阶段)
# info 运行信息 (测试或者运行阶段)
# warn 警告消息
# error 程序错误消息
# fatal 系统错误消息
# 通过5种级别输出的日志 打印在文件中
# int i=0;
# my.debug("定义了变量i");
# i=10
# my.debug("变量i设置了值 10");
# my.info("变量i设置了值 10")
# my.warn("警告。。。。")
# ....
#
# 全局控制机制
# root=info
#
#日志级别 fatal>error>warn>info>debug 所有全局控制中设置的级别 以下的所有日志都不打印 比如 设置 info 不打印debug fatal 前面四个日志都不会打印
#
log4j.appender.a = org.apache.log4j.ConsoleAppender
log4j.appender.a.Target = System.out
log4j.appender.a.layout = org.apache.log4j.PatternLayout
log4j.appender.a.layout.ConversionPattern =%-d{yyyy-MM-dd HH\:mm\:ss} [ %t\:%r ] - [ %p ] %m%n
//自定义log日志
Logger logger=Logger.getLogger(MyTest.class);
//@Test
public void QueryFood() throws IOException{
SqlSession session=getSession();
Map map=new HashMap();
map.put("price", 60);
map.put("foodname", "大盘鸡");
List list = session.selectList("a.selectFoodByParam", map);
logger.info(list);
System.out.println(list);
}
通过接口直接映射Sql(XML)
接口定义:
/**
* 接口
* @author Administrator
*
*/
public interface FoodMapper {
/**
* 根据名称查询所有的菜品信息
* @param foodName
* @return
*/
public List queryFood(String foodName,String price);
/**
* 通过菜品id删除
* @param foodId
*/
public void deleteFood(String foodId);
/**
* 通过名字模糊查找
* @param foodName
* @return
*/
public List queryFoodByName(@Param("foodName") String foodName);
/**
* 插入food
* @param food
*/
public void saveFood(Food food);
}
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>
<!-- 是mybatis的核心配置 数据库的连接信息告诉properties文件位置 -->
<properties resource="jdbc.properties"></properties>
<environments default="development">
<environment id="development">
<!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
<mapper resource="com/et/lesson02/xml/foodMapper.xml" />
</mappers>
</configuration>
foodMapper.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">
<!--
接口绑定 将接口中的方法和对应的sql声明进行绑定
接口绑定的参数 可以通过索引的方式获取 索引从0开始 也可用param1 param2
('s','sex') 0='sex' 1='abc'
param1='sex' param2='abc'
namespace="全路径.接口名"
-->
<mapper namespace="com.et.lesson02.xml.FoodMapper">
<select id="queryFood" resultType="java.util.Map">
<!--
select * from food where foodname=#{0} and price=#{1}
-->
select * from food where foodname=#{param1} and price=#{param2}
</select>
<delete id="deleteFood" >
delete from FOOD where FOODID=#{0}
<!-- 通过自定义类型 -->
<select id="queryFoodByName" resultType="food">
select * from food where foodname like '%${foodName}%'
</select>
<insert id="saveFood" >
<!-- 在程序中获取主键 将获取到的主键塞入参数foodId中
keyProperty="告诉塞入的属性名"
order="BEFORE"在执行insert语句之前
statementType="STATEMENT" 表示sql语句
-->
<selectKey keyProperty="foodId" order="BEFORE" resultType="int" statementType="STATEMENT">
select Food_SEC.Nextval from dual
</selectKey>
insert into food values(#{foodId},#{foodName},#{price})
</insert>
</mapper>
通过接口直接映射Sql(注解)
接口定义:
/**
* 接口
* @author Administrator
*
*/
public interface FoodMapper {
/**
* 根据名称查询所有的菜品信息
* @Param("foodName")可以指定参数 例如foodname=#{foodName}
* @param foodName
* @return
*/
@Select("select * from food where foodname=#{foodName} and price=#{price}")
public List<Map> queryFood(@Param("foodName")String foodName,@Param("price")String price);
/**
* 通过菜品id删除
* @param foodId
*/
@Delete(" delete from FOOD where FOODID=#{0}")
public void deleteFood(String foodId);
/**
* 通过名字模糊查找
* @param foodName
* @return
*/
@Select("select * from food where foodname like '%${foodName}%'")
public List<Food> queryFoodByName(@Param("foodName") String foodName);
/**
* 插入food
* before=true 表示insert之前执行 false之后
* @param food
*/
@SelectKey(before=true,keyProperty="foodId", resultType=int.class, statement = "select Food_SEC.Nextval from dual" )
@Insert("insert into food values(#{foodId},#{foodName},#{price})")
public void saveFood(Food food);
mybatis.xml内容: 不需要foodMapper.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>
<!-- 是mybatis的核心配置
1.数据库的连接信息
告诉properties文件位置 -->
<properties resource="jdbc.properties">
</properties>
<environments default="development">
<environment id="development">
<!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射
class="全路径.接口名"
-->
<mappers>
<mapper class="com.et.lesson02.annotion.FoodMapper" />
</mappers>
</configuration>
测试类
public class MyTest {
public static SqlSession getSession() throws IOException{
String resource = "com/et/lesson02/xml/mybatis.xml";
//获取文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//工厂类
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//session 操作的是执行sql语句的一个唯一标识符
SqlSession session=sqlSessionFactory.openSession();
return session;
}
/**
* 根据名称查询所有的菜品信息
* @throws IOException
*/
//@Test
public void QueryFood() throws IOException{
SqlSession session=getSession();
//获取接口
FoodMapper fm=session.getMapper(FoodMapper.class);
List list=fm.queryFood("大盘鸡", "60");
System.out.println(list);
}
/**
* 通过菜品id删除
* @throws IOException
*/
//@Test
public void deleteFood() throws IOException{
SqlSession session=getSession();
//获取接口
FoodMapper fm=session.getMapper(FoodMapper.class);
fm.deleteFood("4");
session.commit();
}
/**
* 通菜品名模糊查找
* @throws IOException
*/
@Test
public void QueryFoodByName() throws IOException{
SqlSession session=getSession();
//获取接口
FoodMapper fm=session.getMapper(FoodMapper.class);
List list=fm.queryFoodByName("鸡");
System.out.println(list);
}
/**
* 插入food 在程序中获取主键
* @throws IOException
*/
@Test
public void QueryFoodSelectKey() throws IOException{
SqlSession session=getSession();
//获取接口
FoodMapper fm=session.getMapper(FoodMapper.class);
Food food=new Food();
food.setFoodName("牛肉面");
food.setPrice("10");
fm.saveFood(food);
session.commit();
System.out.println(food.getFoodId());
}
}
typeAliases
类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。例如:
mybatis.xml
<!-- 自定义类型别名
resultType="全包名路径.类名"=type
resultType="food"
-->
<typeAliases>
<typeAlias type="com.et.lesson02.Food" alias="自定义名字 food"/>
</typeAliases>
<!-- 给所有的类取别名 别名为类的首字母小写-->
<typeAliases>
<package name="com.et.lesson03"/>
</typeAliases>
SELECT调用存储过程
创建存储过程:
create or replace procedure prg_add(p1 in number,p2 in number,p3 out number)
as
begin
p3:=p1+p2;
end;
创建函数:
create or replace function fun_add(p1 in number,p2 in number)
return number
as
begin
return p1+p2;
end;
Mybatis映射文件中使用select调用存储过程
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>
<!-- 是mybatis的核心配置
1.数据库的连接信息
告诉properties文件位置 -->
<properties resource="jdbc.properties"></properties>
<environments default="development">
<environment id="development">
<!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
<mapper resource="com/et/lesson02/procedure/ProcMapper.xml" />
</mappers>
</configuration>
ProcMapper.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.et.lesson02.procedure.ProcMapper.xml">
<!-- jdbc调用存储过程的语法
{call 存储过程名(?,?)}
函数的语法
{?=call 函数名 (?,?)}
-->
<select id="call_prg_add" resultType="java.util.Map" statementType="CALLABLE">
{call prg_add(
#{p1,mode=IN,jdbcType=NUMERIC},
#{p2,mode=IN,jdbcType=NUMERIC},
#{result,mode=OUT,jdbcType=NUMERIC})}
</select>
<!--函数 -->
<select id="call_fun_add" resultType="java.util.Map" statementType="CALLABLE">
{#{result,mode=OUT,jdbcType=NUMERIC}=call fun_add(
#{p1,mode=IN,jdbcType=NUMERIC},
#{p2,mode=IN,jdbcType=NUMERIC})
}
</select>
</mapper>
测试类
public class MyProcTest {
public static SqlSession getSession() throws IOException{
String resource = "com/et/lesson02/procedure/mybatis.xml";
//获取文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//工厂类
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//session 操作的是执行sql语句的一个唯一标识符
SqlSession session=sqlSessionFactory.openSession();
return session;
}
/**
* 存储过程
* @throws IOException
*/
//@Test
public void testProcFood() throws IOException{
SqlSession session=getSession();
Map map=new HashMap();
map.put("p1",100);
map.put("p2",200);
map.put("result",0);
String result=session.selectOne("call_prg_add",map);
System.out.println(map.get("result"));
}
/**
* 函数
* @throws IOException
*/
@Test
public void testFunFood() throws IOException{
SqlSession session=getSession();
Map map=new HashMap();
map.put("p1",100);
map.put("p2",200);
map.put("result",0);
String result=session.selectOne("call_fun_add",map);
System.out.println(map.get("result"));
}
}
sql 这个元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。它可以被静态地(在加载参数) 参数化. 不同的属性值通过包含的实例变化. 比如:
foodMapper.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">
<!--
sql这个元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。
-->
<mapper namespace="com.et.lesson03.sql.FoodMapper">
<sql id="commonSql">
select * from
</sql>
<select id="queryFood" resultType="java.util.Map">
<include refid="commonSql"></include>
food where foodname=#{param1} and price=#{param2}
</select>
</mapper>
mybatis.xml
<!-- 键和sql语句映射 -->
<mappers>
<mapper resource="com/et/lesson03/sql/foodMapper.xml" />
</mappers>
Result Maps
结果集映射:数据库的列名和实体类的属性名如果不一致 需要建立 列名和属性名的映射关系
结果集映射返回的结构是相同的,只是多了一层关系
<!--
结果集映射:数据库的列名和实体类的属性名如果不一致 需要建立 列名和属性名的映射关系
结果集映射返回的结构是相同的都是grade 只是多了一层关系
<select id="queryAllGrade" resultType="间接将resultType映射到resultMap">
select * from grade
</select>
-->
<select id="queryAllGrade" resultMap="gradeMap">
select * from grade
</select>
<!-- resultType="返回的班级" -->
<select id="queryGradeById" resultMap="gradeMap">
select * from grade where gid=#{gid}
</select>
用xml实现一对多和多对一的结果集映射
/**
* 一对多
* 班级实体
* @author Administrator
*
*/
public class Grade {
private int gid;
private String gname;
private List<Student> studentList=new ArrayList<Student>();
public List<Student> getStudentList() {
return studentList;
}
public void setStudentList(List<Student> studentList) {
this.studentList = studentList;
}
public int getGid() {
return gid;
}
public void setGid(int gid) {
this.gid = gid;
}
public String getGname() {
return gname;
}
public void setGname(String gname) {
this.gname = gname;
}
}
/**
* 多对一
* 实体类
* @author Administrator
*
*/
public class Student {
private int sid;
private String sname;
private Grade grade;
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
}
多对一和一对多的关系:
/**
*多对一接口
* @author Administrator
*
*/
public interface StudentMapper {
/**
* 通过编号查询学生
* @param
* @return
*/
public Student queryStudentById(String sid);
}
/**
* 接口
* @author Administrator
*
*/
public interface GradeMapper {
/**
* 查询所有的班级
* @param
* @return
*/
public List queryAllGrade();
/**
* 通过id查找所有的班级
* 一对多
* @param gid
* @return
*/
public Grade queryGrade(String gid);
}
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.et.lesson03.resultMap.xml.StudentMapper">
<!-- 映射多对一的关系
多对一使用的关联<association property="关联的属性名"></association>
-->
<resultMap type="student" id="studentMap" autoMapping="true">
<!-- 列和属性的关系 主键使用id 非主键使用result -->
<id column="sid" property="sid"/>
<!-- select * from grade where gid=${学生信息中的gid}
select="queryGradeById"指定学生的班级
-->
<association property="grade" column="gid" select="com.et.lesson03.resultMap.xml.GradeMapper.queryGradeById">
</association>
</resultMap>
<!-- 多对一 -->
<select id="queryStudentById" resultMap="studentMap">
select * from student where sid=#{0}
</select>
<!-- 一对多 -->
<select id="queryStudentByGid" resultMap="studentMap">
select * from student where gid=#{0}
</select>
</mapper>
gradeMapper.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.et.lesson03.resultMap.xml.GradeMapper">
<!--
type="返回的都是grade类" id="名字"
column="数据库列名" property="属性名"
autoMapping="true"相同列自动映射
-->
<resultMap type="grade" id="gradeMap" autoMapping="true">
<!-- 列和属性的关系 主键使用id 非主键使用result -->
<id column="gid" property="gid"/>
<result column="gname" property="gname"/>
</resultMap>
<!--
结果集映射:数据库的列名和实体类的属性名 如果不一致 需要建立 列名和属性名的映射关系
结果集映射返回的结果是相同 的 都是grade 只是多了一层关系
-->
<select id="queryAllGrade" resultMap="gradeMap">
select * from grade
</select>
<!-- 多对一resultType="返回的班级" -->
<select id="queryGradeById" resultMap="gradeMap">
select * from grade where gid=#{gid}
</select>
<!-- 用于一对多的映射
一对多使用的关联<collection property="关联的属性名" javaType="返回的类型"></collection>
-->
<resultMap type="grade" id="gradeOne" autoMapping="true">
<!-- 列和属性的关系 主键使用id 非主键使用result -->
<id column="gid" property="gid"/>
<result column="gname" property="gname"/>
<collection property="studentList" column="gid" javaType="list" select="com.et.lesson03.resultMap.xml.StudentMapper.queryStudentByGid" autoMapping="true">
</collection>
</resultMap>
<!-- 一对多的关系 查询某个班级下 多个学生 -->
<select id="queryGrade" resultMap="gradeOne">
select * from grade where gid=#{gid}
</select>
</mapper>
测试类
public class MyTest {
public static SqlSession getSession() throws IOException{
String resource = "com/et/lesson03/resultMap/xml/mybatis.xml";
//获取文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//工厂类
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//session 操作的是执行sql语句的一个唯一标识符
SqlSession session=sqlSessionFactory.openSession();
return session;
}
/**
* 查询所有的班级
* @throws IOException
*/
@Test
public void QueryAllGrade() throws IOException{
SqlSession session=getSession();
//获取接口
GradeMapper gm=session.getMapper(GradeMapper.class);
List<Grade> list=gm.queryAllGrade();
for (Grade g : list) {
System.out.println(g.getGid()+"-----"+g.getGname());
}
System.out.println(list.size());
}
/**
* 多对一的查询
* @throws IOException
*/
@Test
public void QueryManyToOne() throws IOException{
SqlSession session=getSession();
//获取接口
StudentMapper gm=session.getMapper(StudentMapper.class);
Student st=gm.queryStudentById("2");
System.out.println(st.getSname()+"---"+st.getGrade().getGname());
}
/**
* 一对多的查询
* @throws IOException
*/
@Test
public void QueryOneToMany() throws IOException{
SqlSession session=getSession();
//获取接口
GradeMapper gm=session.getMapper(GradeMapper.class);
Grade ge=gm.queryGrade("1");
for (Student s:ge.getStudentList()) {
System.out.println(ge.getGname()+"==="+s.getSid()+"---"+s.getSname());
}
System.out.println(ge.getStudentList().size());
}
}
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>
<!-- 是mybatis的核心配置
1.数据库的连接信息
告诉properties文件位置 -->
<properties resource="jdbc.properties"></properties>
<!-- 给所有的类取别名 别名为类的首字母小写-->
<typeAliases>
<package name="com.et.lesson03.resultMap.xml"/>
</typeAliases>
<environments default="development">
<environment id="development">
<!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
<mapper resource="com/et/lesson03/resultMap/xml/GradeMapper.xml" />
<mapper resource="com/et/lesson03/resultMap/xml/StudentMapper.xml" />
</mappers>
</configuration>
用注解实现一对多和多对一的结果集映射 不需要xml映射文件
/**
* 接口
* @author Administrator
*
*/
public interface GradeMapper {
/**
* 查询所有的班级
* @param
* @return
*/
public List queryAllGrade();
/**
* 通过id查找所有的班级
* @param gid
* @return
* 一对多
* many=@Many
*/
@Results({
@Result(column="gid",property="studentList",javaType=ArrayList.class,many=@Many(
select="com.et.lesson03.resultMap.annotion.StudentMapper.queryStudentByGid"
))
})
@Select("select * from grade where gid=#{0}")
public Grade queryGrade(String gid);
/**
* 多对一
* @param gid
* @return
*/
@Select("select * from grade where gid=#{0}")
public Grade queryGradeById(String gid);
}
/**
*多对一
* @author Administrator
*
*/
public interface StudentMapper {
/**
* 通过编号查询学生
* 列名不同时要映射@Result(column="ganme",property="ganme1")
* 相同的时候自动映射
*多对一
* one=@One(select="全路径.接口名.方法名 ")
* @param
* @return
*/
@Results({
@Result(column="gid",property="grade",one=@One(select="com.et.lesson03.resultMap.annotion.GradeMapper.queryGradeById"))
})
@Select("select * from student where sid=#{0}")
public Student queryStudentById(String sid);
/**
* 一对多
* @param gid
* @return
*/
@Select("select * from student where gid=#{0}")
public List<Student> queryStudentByGid(String gid);
}
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>
<!-- 是mybatis的核心配置
1.数据库的连接信息
告诉properties文件位置 -->
<properties resource="jdbc.properties"></properties>
<!-- 给所有的类取别名 别名为类的首字母小写-->
<typeAliases>
<package name="com.et.lesson03.resultMap.annotion"/>
</typeAliases>
<environments default="development">
<environment id="development">
<!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
<mapper class="com.et.lesson03.resultMap.annotion.GradeMapper" />
<mapper class="com.et.lesson03.resultMap.annotion.StudentMapper" />
</mappers>
</configuration>
测试类
public class MyTest {
public static SqlSession getSession() throws IOException{
String resource = "com/et/lesson03/resultMap/annotion/mybatis.xml";
//获取文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//工厂类
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//session 操作的是执行sql语句的一个唯一标识符
SqlSession session=sqlSessionFactory.openSession();
return session;
}
/**
* 查询所有的班级
* @throws IOException
*/
//@Test
public void QueryAllGrade() throws IOException{
SqlSession session=getSession();
//获取接口
GradeMapper gm=session.getMapper(GradeMapper.class);
List<Grade> list=gm.queryAllGrade();
for (Grade g : list) {
System.out.println(g.getGid()+"-----"+g.getGname());
}
System.out.println(list.size());
}
/**
* 多对一的查询
* @throws IOException
*/
//@Test
public void QueryManyToOne() throws IOException{
SqlSession session=getSession();
//获取接口
StudentMapper gm=session.getMapper(StudentMapper.class);
Student st=gm.queryStudentById("2");
System.out.println(st.getSname()+"---"+st.getGrade().getGname());
}
/**
* 一对多的查询
* @throws IOException
*/
@Test
public void QueryOneToMany() throws IOException{
SqlSession session=getSession();
//获取接口
GradeMapper gm=session.getMapper(GradeMapper.class);
Grade ge=gm.queryGrade("1");
for (Student s:ge.getStudentList()) {
System.out.println(ge.getGname()+"==="+s.getSid()+"---"+s.getSname());
}
System.out.println(ge.getStudentList().size());
}
}
动态sql(xml)
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。
动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis 3 大大提升了它们,现在用不到原先一半的元素就可以了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。
IF
if用来判断条件是否满足 满足就将if中的sql 自动拼接到主sql
where 1=1相当于标签
相当于
where 自动判断第一个条件是否存在where 如果没有就追加
同时去掉一个and
trim 永远 灵活度更高
prefix=”前缀” 配置的参数会被添加在sql语句的开始的地方
prefixOverrides=”” sql语句首次出现的参数会被覆盖
prefix覆盖prefixOverrides
学生实体类
/**
* 查询学生时将班级也查出
* @author Administrator
*
*/
public class Student {
private String sid;
private String sname;
private Integer sex;
private Integer age;
private String address;
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
/**
* @author Administrator
*接口类
*/
public interface StudentMapper {
/**
* 通过编号查询学生
* @param
* @return
*/
public List<Student> queryStudentById(Student student);
/**
* 通过学生的性别查询
* 参数中传入sex 就根据条件查 没有传值就查所有的女生
* @param sex
* @return
*/
public List<Student> queryBySex(@Param("sex")Integer sex);
/**
* 修改学生信息
* @param
* @return
*/
public void updateStudent(Student student);
/**
* 通过传入的班级查询所有的学生
* @Param("取别名")
*/
public List<Student> queryStudentAndGrade(@Param("gradeList")List<String> gradeList);
}
mybatis的核心文件配置:
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>
<!-- 是mybatis的核心配置
1.数据库的连接信息
告诉properties文件位置 -->
<properties resource="com/et/lesson04/jdbc.properties"></properties>
<!-- 给所有的类取别名 别名为类的首字母小写-->
<typeAliases>
<package name="com.et.lesson04.xml"/>
</typeAliases>
<environments default="development">
<environment id="development">
<!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
<mapper resource="com/et/lesson04/xml/StudentMapper.xml" />
</mappers>
</configuration>
StudentMapper.xml
<select id="queryStudentById" resultType="student">
select * from student
<where>
<if test="sname!=null">
and sname like '%${sname}%'
</if>
<if test="address!=null">
and address like '%${address}%'
</if>
</where>
</select>
<select id="queryStudentById" resultType="student">
select * from student
<trim prefix="where" prefixOverrides="and">
<if test="sname!=null">
and sname like '%${sname}%'
</if>
<if test="address!=null">
and address like '%${address}%'
</if>
</trim>
</select>
choose, when, otherwise
你们不想用到所有的条件语句,而只想从中择其一二。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
StudentMapper.xml
<select id="queryBySex" resultType="student">
select * from student where 1=1
<choose>
<when test="sex!=null">
and sex=#{sex}
</when>
<otherwise>
and sex=1
</otherwise>
</choose>
</select>
trim, where, set
<!-- set标签 动态去掉最后一个逗号(,)
用trim实现set 例如:<trim prefix="set" prefixOverrides=""></trim>
-->
<update id="updateStudent">
update student
<set>
<if test="sname!=null">
sname=#{sname},
</if>
<if test="sex!=null">
sex=#{sex},
</if>
<if test="age!=null">
age=#{age}
</if>
</set>
where sid=#{sid}
</update>
foreach
动态 SQL 的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建 IN 条件语句的时候。比如:
<!--
foreach
open="循环条件开始之前追加的条件"
close="循环条件结束之后追加的sql"
separator="非最后一次的循环值上添加逗号分隔符"
where gid in()等于 open="where gid in(" close=")"
collection="指定传入值的集合"
item="每循环一次就用临时变量存"
${gid}获取gid
-->
<select id="queryStudentAndGrade" resultType="student">
select * from student
<foreach item="gid" collection="gradeList" open="where gid in(" close=")" separator="," >
${gid}
</foreach>
</select>
动态sql(注解)
mybatis的核心文件配置:
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>
<!-- 是mybatis的核心配置
1.数据库的连接信息
告诉properties文件位置 -->
<properties resource="com/et/lesson04/jdbc.properties"></properties>
<!-- 给所有的类取别名 别名为类的首字母小写-->
<typeAliases>
<package name="com.et.lesson04.annotation"/>
</typeAliases>
<environments default="development">
<environment id="development">
<!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
<mapper class="com.et.lesson04.annotation.StudentMapper" />
</mappers>
</configuration>
/**
* @author Administrator
*接口类
*/
public interface StudentMapper {
/**
* 通过编号查询学生
* @SelectProvider提供sql语句有一个类中的方法提供类的方法于接口中的方法名相同
* type=类名.class
* method="类中的方法名"
* @param
* @return
*/
@SelectProvider(type=StudentProvier.class,method="queryStudentBySql")
public List<Student> queryStudentById(@Param("stu")Student student);
/**
* 通过学生的性别查询
* 参数中传入sex 就根据条件查 没有传值就查所有的女生
* ${}在注解中会失效
* @param sex
* @return
*/
@Select("<script>select * from student where 1=1" +
"<choose>"+
" <when test=\"sex!=null\">"+
" and sex=#{sex}"+
" </when>"+
" <otherwise>"+
" and sex=1"+
" </otherwise>"+
" </choose></script>")
public List<Student> queryBySex(@Param("sex")Integer sex);
/**
* 修改学生信息
* @param
* @return
*/
@UpdateProvider(type=StudentProvier.class,method="updateStudentSql")
public void updateStudent(@Param("stud")Student student);
/**
* 通过传入的班级查询所有的学生
* foreach
* @Param("取别名")
*/
@SelectProvider(type=StudentProvier.class,method="queryStudentAndGradeBySql")
public List<Student> queryStudentAndGrade(@Param("gradeList")List<String> gradeList);
}
提供方法的类
public class StudentProvier {
/**
* 通过键值对方式传参
* ${}在注解中会失效
* 提供sql语句方法的参数是Map 键值对
* 对象的属性取值用别名.属性名
* @return
*/
public String queryStudentByIdSql(Map map){
Student st=(Student)map.get("stu");
String sql=" select * from student where 1=1 ";
if(st.getSname()!=null &&!"".equals(st.getSname())){
st.setSname("%"+st.getSname()+"%");
sql+=" and sname like #{stu.sname}";
}
if(st.getAddress()!=null && !"".equals(st.getAddress())){
st.setAddress("%"+st.getAddress()+"%");
sql+=" and address like #{stu.address}";
}
return sql;
}
public String queryStudentBySql(Map map){
Student st=(Student)map.get("stu");
SQL sql=new SQL();
sql.SELECT("*").FROM("student");
if(st.getSname()!=null &&!"".equals(st.getSname())){
st.setSname("%"+st.getSname()+"%");
sql.WHERE(" sname like #{stu.sname}");
}
if(st.getAddress()!=null && !"".equals(st.getAddress())){
st.setAddress("%"+st.getAddress()+"%");
sql.AND();
sql.WHERE(" address like #{stu.address}");
}
return sql.toString();
}
public String updateStudentSql(Map map){
Student st=(Student)map.get("stud");
SQL sql=new SQL();
sql.UPDATE("student");
if(st.getSname()!=null || !"".equals(st.getSname())){
sql.SET("sname=#{stud.sname}");
}
if(st.getSex()!=null || !"".equals(st.getSex()) ){
sql.SET("sex=#{stud.sex}");
}
if(st.getAge()!=null || !"".equals(st.getAge())){
sql.SET("age=#{stud.age}");
}
sql.WHERE("sid=#{stud.sid}");
return sql.toString();
}
public String queryStudentAndGradeBySql(Map map){
List<String> list=(List<String>)map.get("gradeList");
SQL sql=new SQL();
sql.SELECT("*").FROM("student");
String str="";
for (String stu : list) {
str+=stu+",";
}
String st=str.substring(0, str.length()-1);
sql.WHERE(" gid in ("+st+")");
return sql.toString();
}
}
测试类
public class MyTest {
public static SqlSession getSession() throws IOException{
String resource = "com/et/lesson04/xml/mybatis.xml";
//获取文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//工厂类
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//session 操作的是执行sql语句的一个唯一标识符
SqlSession session=sqlSessionFactory.openSession();
return session;
}
/**
* 通过学生id查询
* @throws IOException
*/
@Test
public void queryStudentById() throws IOException{
SqlSession session=getSession();
//获取接口
StudentMapper sm=session.getMapper(StudentMapper.class);
Student st=new Student();
st.setSname("张");
st.setAddress("深圳");
List<Student> list=sm.queryStudentById(st);
for (Student stu : list) {
System.out.println(stu.getSname());
}
}
/**
* 通过学生性别查询
* @throws IOException
*/
@Test
public void queryBySexChoose() throws IOException{
SqlSession session=getSession();
//获取接口
StudentMapper sm=session.getMapper(StudentMapper.class);
Integer sex=null;
List<Student> list=sm.queryBySex(sex);
for (Student stu : list) {
System.out.println(stu.getSname());
}
}
/**
* 修改学生信息
*/
@Test
public void updateStudent() throws IOException{
SqlSession session=getSession();
//获取接口
StudentMapper sm=session.getMapper(StudentMapper.class);
Student st=new Student();
st.setSid("1");
st.setSname("张三三");
sm.updateStudent(st);
session.commit();
}
/**
* 通过传入的班级查询所有的学生
*/
@Test
public void queryStudentAndGradeForEach() throws IOException{
SqlSession session=getSession();
//获取接口
StudentMapper sm=session.getMapper(StudentMapper.class);
List list=new ArrayList();
list.add("1");
list.add("2");
list.add("3");
List<Student> lt=sm.queryStudentAndGrade(list);
for (Student student : lt) {
System.out.println(student.getSname());
}
}
}
Mybatis一级和二级缓存
Mybatis一级缓存为sqlSession级别的缓存 默认开启 相同的sqlsession对象 查询相同条件的结果时 存在一级缓存只会查询一次,sqlSession关闭后缓存失效 调用cleanCache后 缓存被清除,执行过增删改后缓存会被清除
二级缓存为sqlSessionFactory级别的缓存
/**
* @author Administrator
*
*/
public interface StudentMapper {
/**
* 通过编号查询学生
* @param
* @return
*/
public Student queryStudentById(String sid);
}
映射配置文件
<?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.et.lesson05.xml.StudentMapper">
<!-- 二级缓存开启
mybatis 默认缓存类FifoCache
内存数据不足时需要一种机制 保证内存不出现溢出 需要将旧的数据清除 最先加入的数据最先清除
LRU:最近在使用次数最少的被优先清除
LFU:最近一段时间内使用次数最少
eviction="FIFO"默认是FIFO
-->
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" type="com.et.lesson05.xml.RedisCache">
</cache>
<select id="queryStudentById" resultType="student">
select * from student where sid=#{sid}
</select>
</mapper>
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>
<!-- 是mybatis的核心配置
1.数据库的连接信息
告诉properties文件位置 -->
<properties resource="com/et/lesson05/jdbc.properties"></properties>
<!-- 二级缓存开启方式 也用不了要在映射文件中加<cache></cache>-->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 给所有的类取别名 别名为类的首字母小写-->
<typeAliases>
<package name="com.et.lesson05.xml"/>
</typeAliases>
<environments default="development">
<environment id="development">
<!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
<mapper resource="com/et/lesson05/xml/StudentMapper.xml" />
</mappers>
</configuration>
测试类
public class MyTest {
/**
* 用于二级缓存
* @return
* @throws IOException
*/
public SqlSessionFactory getSessionFactory() throws IOException{
String resource = "com/et/lesson05/xml/mybatis.xml";
//获取文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//工厂类
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//session 操作的是执行sql语句的一个唯一标识符
return sqlSessionFactory;
}
/**
* 用于一级缓存
* @return
* @throws IOException
*/
public static SqlSession getSession() throws IOException{
String resource = "com/et/lesson05/xml/mybatis.xml";
//获取文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//工厂类
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//session 操作的是执行sql语句的一个唯一标识符
SqlSession session=sqlSessionFactory.openSession();
return session;
}
/**
* 通过学生id查询
* 一级缓存 :同一个session对象针对同一份数据的查询产生的缓存
* 第一次查询是调用数据 获取数据后
* 通过session设置到一级缓存中
* 第二次查询时 通过session一级缓存判断是否存在 相同的主键数据值 如果存在直接返回引用否则就查数据库
* @throws IOException
*/
//@Test
public void queryStudentByIdToSqlSession() throws IOException{
SqlSession session=getSession();
//获取接口
StudentMapper sm=session.getMapper(StudentMapper.class);
Student st=sm.queryStudentById("1");
//从缓存中查询
Student st1=sm.queryStudentById("1");
System.out.println(st==st1);
}
/***
* 二级缓存:同一个sessionFactory下的不同session可以共享数据(二级缓存默认是没有开启)
* @throws IOException
*/
@Test
public void queryStudentByIdToSessionFactory() throws IOException{
SqlSessionFactory sessionFactory=getSessionFactory();
SqlSession session=sessionFactory.openSession();
SqlSession session1=sessionFactory.openSession();
//获取接口
StudentMapper sm=session.getMapper(StudentMapper.class);
Student st=sm.queryStudentById("1");
session.close();
//获取接口
StudentMapper sm1=session1.getMapper(StudentMapper.class);
//从缓存中查询
Student st1=sm1.queryStudentById("1");
System.out.println(st==st1);
}
}
自定义缓存
/**
* 分布式环境
*/
import java.io.IOException;
import java.util.concurrent.locks.ReadWriteLock;
import org.apache.ibatis.cache.Cache;
import redis.clients.jedis.Jedis;
public class RedisCache implements Cache {
/**
* 操作redis对象
*/
Jedis jedis=new Jedis("localhost",6379);
private String cacheId;
public RedisCache(String cacheId){
this.cacheId=cacheId;
}
@Override
public void clear() {
//清空缓存
//jedis.flushDB();
}
@Override
public String getId() {
return cacheId;
}
/**
* mybatis自动调用getObject检测是否在缓存中存在
*/
@Override
public Object getObject(Object key) {
try {
byte[] bt=jedis.get(JavaReadis.objectToByteArrat(key));
if(bt==null){
return null;
}
return JavaReadis.byteArrayToObject(bt);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public ReadWriteLock getReadWriteLock() {
return null;
}
@Override
public int getSize() {
return 0;
}
/**
* mybatis读取数据是将数据库中读取的数据通过putObject设置到缓存中
*/
@Override
public void putObject(Object key, Object value) {
//写入redis
try {
jedis.set(JavaReadis.objectToByteArrat(key), JavaReadis.objectToByteArrat(value));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* mybatis缓存策略 自动判断内存的大小 决定是否删除某些过期 久远的数据
*/
@Override
public Object removeObject(Object key) {
Object obj=getObject(key);
try {
jedis.del(JavaReadis.objectToByteArrat(key));
} catch (IOException e) {
e.printStackTrace();
}
return obj;
}
}
学生实体类
/**
* 查询学生时将班级也查出
* @author Administrator
*
*/
public class Student implements Serializable{
private String sid;
private String sname;
private Integer sex;
private Integer age;
private String address;
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
public class JavaReadis {
/**
* 将对象转成byte数组
* 序列化
* 写入数据到redis时调用
* jedis.set("myname", "张三");
* 默认mybatis是没有继承redis需要自己实现
* @param obj
* @return
* @throws IOException
*/
public static byte[] objectToByteArrat(Object obj) throws IOException{
//内存流
ByteOutputStream bos=new ByteOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.writeObject(obj);
return bos.getBytes();
}
/**
* 将byte数组转成对象
* 反序列化
* @param bt
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public static Object byteArrayToObject(byte[] bt) throws IOException, ClassNotFoundException{
//内存流
ByteInputStream bis=new ByteInputStream(bt,bt.length);
// 反序列化
ObjectInputStream ois=new ObjectInputStream(bis);
return ois.readObject();
}
public static void main(String[] args) {
Jedis jedis=new Jedis("localhost",6379);
//键值对
jedis.set("myname", "张三");
System.out.println(jedis.get("myname"));
}
}
Mybatis集成Spring
步骤1.下载 mybatis-spring插件或者添加maven依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.3</version>
</dependency>
步骤2.配置druid数据源
步骤3.配置SqlSessionFactoryBean设置数据源以及mybatis配置文件的位置
步骤四.配置SqlSessionTemplate 通过构造器注入SqlSessionFactoryBean
步骤五.配置DataSourceTransactionManager注入数据源配置事物
步骤六.配置MapperScannerConfigurer扫描注解对应的mapper文件对应的包
步骤七 配置spring事物的切面以及通知
spring.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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
">
<!--spring是bean的容器(service+dao处理) 扫描 -->
<context:component-scan base-package="com.et">
<!-- 排除注解 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<context:property-placeholder location="classpath:/jdbc.properties" />
<!-- 所有数据库操作的源头实现子接口DataSource
DriverManagerDataSource (请求产生一个连接 用完关闭 连接要重用 这样的机制叫连接池)
-->
<!-- 数据源只是为了获取连接池-->
<bean id="dataSource"
class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${url}"></property>
<property name="username" value="${username1}"></property>
<property name="password" value="${password2}"></property>
<property name="driverClassName" value="${driverClass}"></property>
<!-- 默认初始化的连接个数 -->
<property name="initialSize" value="1"></property>
<!--最大允许的连接个数 -->
<property name="maxActive" value="200"></property>
<!-- 最大的等待人数 -->
<property name="maxIdle" value="100"></property>
<!-- 监控sql 开启sql统计功能 -->
<property name="filters" value="stat"></property>
</bean>
<!-- 通过spring集成mybatis -->
<!-- 配置session工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入连接的数据源 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="sessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<!-- 构造器注入工厂 -->
<constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg>
</bean>
<!-- 扫描mybatis的接口映射 (*..* 任意多层次的包两个以上的包) -->
<bean id="scannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.*.mapper"></property>
</bean>
<!-- 事务管理器 -->
<bean id="tm" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 提交连接事务 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 通知 并将事务管理器关联 -->
<tx:advice id="txAdvice" transaction-manager="tm">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<!-- 只读 -->
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 事务(*(返回值) com.*.service.*(类或接口).*(方法)(..)任意参数) -->
<aop:config>
<!--定义切点 -->
<aop:pointcut expression="execution(* com.*.service.*.*(..))" id="myPointCut"/>
<!--关联切点和事务的管理器 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPointCut"/>
</aop:config>
</beans>
springmvc.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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
">
<!--springmvc控制层处理+视图层 扫描 -->
<context:component-scan base-package="com.et">
<!-- 排除注解 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
<context:property-placeholder location="classpath:/jdbc.properties" />
<!-- 引用返回对象 响应json -->
<mvc:annotation-driven>
<mvc:message-converters>
<!-- 配置返回字节数组解析成json的消息转换器 -->
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<!-- 设置响应支持的类型 -->
<value>text/html;charset="UTF-8"</value>
<!-- 设置请求body支持的类型 -->
<value>application/x-www-form-urlencoded</value>
</list>
</property>
</bean>
<!-- 配置返回对象解析成json的消息转换器 -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<!-- 设置响应支持的类型 -->
<value>text/html;charset="UTF-8"</value>
<!-- 设置请求body支持的类型 -->
<value>application/x-www-form-urlencoded</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!--
================================================
spring配置
================================================
-->
<!-- spring配置文件位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<!-- 配置监听 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--
================================================
springmvc配置
================================================
-->
<!-- 请求method支持put和delete必须添加过滤器 支持rest风格-->
<filter>
<filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- springmvc的核心配置 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定springmvc的配置文件名称 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mymvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>Filter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 启用druid的监控功能 -->
<servlet>
<servlet-name>mydruid</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
<init-param>
<param-name>loginUsername</param-name>
<param-value>admin</param-value>
</init-param>
<init-param>
<param-name>loginPassword</param-name>
<param-value>admin</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mydruid</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
</web-app>
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>SSMA</groupId>
<artifactId>SSMA</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name/>
<description/>
<dependencies>
<!-- springmvc的配置-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<!-- 事务的配置 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<!-- 事务的配置 -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.12</version>
</dependency>
<!-- (druid)连接池的配置 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.5</version>
</dependency>
<!-- mybatis集成spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.3</version>
</dependency>
<!-- 配置mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<!-- 添加jacson的json解析库 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.12</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.12</version>
</dependency>
<!-- mysql的配置 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.26</version>
</dependency>
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>javaee-api</artifactId>
<version>5.0-1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>1.2_04</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>1.2_04</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>${basedir}/src</sourceDirectory>
<outputDirectory>${basedir}/WebRoot/WEB-INF/classes</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webappDirectory>${basedir}/WebRoot</webappDirectory>
<warSourceDirectory>${basedir}/WebRoot</warSourceDirectory>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
目录结构:
@Controller
public class MyFoodController {
@Autowired
MyFoodService ms;
/**
*第三种直接返回对象 springmvc自动转成json(默认是不可以 需要消息转换器(MappingJackson2HttpMessageConverter)
*会覆盖字节数组的消息转换器所有同时加字节数组的消息转换器ByteArrayHttpMessageConverter)
*添加注解@ResponseBody
*/
@ResponseBody
@RequestMapping(value="/queryAllList",method={RequestMethod.GET})
public List<Map<String, Object>> foodMap(String foodname) throws UnsupportedEncodingException, IOException{
List<Map<String, Object>> queryFood=ms.queryAllFood(foodname);
return queryFood;
}
/**
* 删除方法
*/
@RequestMapping(value="/food/{foodid}",method=RequestMethod.DELETE)
public String deleteFood(@PathVariable String foodid,OutputStream os,HttpServletResponse response) throws UnsupportedEncodingException, IOException{
try {
ms.deleteFood(foodid);
os.write("1".getBytes("UTF-8"));
} catch (Exception e) {
os.write("0".getBytes("UTF-8"));
}
return null;
}
/**
* 添加方法
*/
@RequestMapping(value="/food",method={RequestMethod.POST})
public String saveFood(String foodName,String price,OutputStream os,HttpServletResponse response) throws UnsupportedEncodingException, IOException{
try {
ms.saveFood( foodName, price);
os.write("1".getBytes("UTF-8"));
} catch (Exception e) {
os.write("0".getBytes("UTF-8"));
}
return null;
}
/**
* 修改方法
*/
@RequestMapping(value="/food/{foodid}",method={RequestMethod.PUT})
public String updateFood(@PathVariable String foodid,String foodName,String price,OutputStream os,HttpServletResponse response) throws UnsupportedEncodingException, IOException{
try {
ms.updateFood(foodid, foodName, price);
os.write("1".getBytes("UTF-8"));
} catch (Exception e) {
os.write("0".getBytes("UTF-8"));
}
return null;
}
}
public interface MyFoodDao {
/**
* 查询
* @param foodname
* @return
*/
public abstract List<Map<String, Object>> queryAllFood(String foodname);
/**
* 删除
* @param foodId
*/
public abstract void deleteFood(String foodId);
/**
* 添加
* @param foodName
* @param price
*/
public abstract void saveFood(String foodName, String price);
/**
* 修改
* @param foodId
* @param foodName
* @param price
*/
public abstract void updateFood(String foodId, String foodName, String price);
}
@Repository
public class MyFoodDaoImpl implements MyFoodDao {
@Autowired
FoodMapper mapper;
public List<Map<String, Object>> queryAllFood(String foodname){
return mapper.queryAllFood(foodname);
}
public void deleteFood(String foodId){
mapper.deleteFood(foodId);
}
public void saveFood(String foodName,String price){
mapper.saveFood(foodName, price);
}
public void updateFood(String foodId,String foodName,String price){
mapper.updateFood(foodId, foodName, price);
}
}
public interface MyFoodService {
/**
* 查询
* @param foodname
* @return
*/
public abstract List<Map<String, Object>> queryAllFood(String foodname);
/**
* 删除
* @param foodId
*/
public abstract void deleteFood(String foodId);
/**
* 添加
* @param foodName
* @param price
*/
public abstract void saveFood(String foodName, String price);
/**
* 修改
* @param foodId
* @param foodName
* @param price
*/
public abstract void updateFood(String foodId, String foodName, String price);
}
@Service
public class MyFoodServiceImpl implements MyFoodDao, MyFoodService {
@Autowired
MyFoodDao dao;
public List<Map<String, Object>> queryAllFood(String foodname){
return dao.queryAllFood(foodname);
}
public void deleteFood(String foodId){
dao.deleteFood(foodId);
}
public void saveFood(String foodName,String price){
dao.saveFood(foodName, price);
}
public void updateFood(String foodId,String foodName,String price){
dao.updateFood(foodId, foodName, price);
}
}
public interface FoodMapper {
/**
* 查询
*/
@Select("select * from food where foodname like '%${foodname}%'")
public List<Map<String, Object>> queryAllFood(@Param("foodname")String foodname);
/**
* 删除
*/
@Delete("delete from food where foodid=#{0}")
public void deleteFood(String foodId);
/**
* 添加
*/
@Insert("insert into food(foodid,foodname,price) values((select IFNULL(max(foodid),0)+1 from food f),#{0},#{1})")
public void saveFood(String foodName,String price);
/**
* 修改
*/
@Update("update food set foodname=#{1},price=#{2} where foodid=#{0}")
public void updateFood(String foodId,String foodName,String price);
}
通过ajax实现
WEB-INF/food.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'food.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script type="text/javascript">
function sendAjax(url,methodType,param,retnFunction){
//调用http://localhost:8080/SpringMvcDay/queryAll 获取数据通过dom方法添加到table中
//ajax(异步)+json
var xmlhttp = null;
//兼容所有的浏览器创建这个对象(简称XHR对象)
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
//匿名函数 不需要调的函数叫回调函数 当请求发送后回自动调用该方法
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
retnFunction(xmlhttp.responseText);
}
}
if(methodType=="get" || methodType=="GET"){
//open方法表示产生一个请求的关联(get 提交)
xmlhttp.open("GET",url+"?"+param, true);
xmlhttp.send();
}else{
//open方法表示产生一个请求的关联(POST 提交)
xmlhttp.open("POST",url, true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded;charset=UTF-8");
xmlhttp.send(param);
}
}
function query() {
var foodname=document.getElementsByName("foodName")[0].value;
sendAjax("${pageContext.request.contextPath}/queryAllList","GET","foodname="+foodname,function(responseText){
//返回字符串的json
var resultJson = responseText;
//转换为js对象
var resultObj = JSON.parse(resultJson);
//获取table对象
var table = document.getElementById("myTable");
//将所有名字为dataTr的tr全部删除
var allDataTr = document.getElementsByName("dataTr");
var length = allDataTr.length;
for ( var i = 0; i < length; i++) {
table.removeChild(allDataTr[0]);
}
//根据json的行数追加多个tr
for ( var i = 0; i < resultObj.length; i++) {
var obj = resultObj[i];
//创建<td>
var tid = document.createElement("td");
//将内容添加到td中
tid.innerText = obj.foodid;
var tname = document.createElement("td");
tname.innerText = obj.foodname;
var tprice = document.createElement("td");
tprice.innerText = obj.price;
var td2=document.createElement("td");
//删除按钮
var ib=document.createElement("button");
ib.innerText="删除";
td2.appendChild(ib);
//修改按钮
var ib1=document.createElement("button");
ib1.innerText="修改";
td2.appendChild(ib1);
//创建<tr>
var tr = document.createElement("tr");
//将当前对象绑定到当前按钮
ib.foodObj=obj;
//将当前行的tr绑定当按钮上
ib.myLineTr=tr;
//删除按钮事件
ib.addEventListener("click",function(){
//获取按钮
var eventStr=event.srcElement;
//删除当前行+发送ajax请求到后台删除数据库
table.removeChild(eventStr.myLineTr);
sendAjax("${pageContext.request.contextPath}/food/"+ib.foodObj.foodid,"POST","_method=delete",function(responseText){
if(responseText==1)
alert("删除成功");
else{
alert("删除失败");
}
});
});
//将当前对象绑定到当前按钮
ib1.foodObj=obj;
//修改按钮事件
ib1.addEventListener("click",function(){
//获取按钮
var eventStr=event.srcElement;
document.getElementById('updateDiv').style.display='block';
document.getElementsByName("updateFoodName")[0].value=eventStr.foodObj.foodname;
document.getElementsByName("updateFoodPrice")[0].value=eventStr.foodObj.price;
document.getElementsByName("updateFoodId")[0].value=eventStr.foodObj.foodid;
});
tr.setAttribute("name", "dataTr");
tr.appendChild(tid);
tr.appendChild(tname);
tr.appendChild(tprice);
tr.appendChild(td2);
table.appendChild(tr);
}
});
}
/**
新增的方法
*/
function saveFood(){
var myFoodName=document.getElementsByName("myFoodName")[0].value;
var myFoodPrice=document.getElementsByName("myFoodPrice")[0].value;
sendAjax("${pageContext.request.contextPath}/food","POST","foodName="+myFoodName+"&price="+myFoodPrice,function(responseText){
if(responseText==1){
document.getElementById('addDiv').style.display='none';
query();
alert("新增成功");
}else{
alert("新增失败");
}
});
}
/**
修改的方法
*/
function updateFood(){
var myFoodName=document.getElementsByName("updateFoodName")[0].value;
var myFoodPrice=document.getElementsByName("updateFoodPrice")[0].value;
var myFoodId=document.getElementsByName("updateFoodId")[0].value;
sendAjax("${pageContext.request.contextPath}/food/"+myFoodId,"POST","_method=put&foodName="+myFoodName+"&price="+myFoodPrice,function(responseText){
if(responseText==1){
document.getElementById('updateDiv').style.display='none';
query();
alert("修改成功");
}else{
alert("修改失败");
}
});
}
</script>
</head>
<body>
<input type="text" name="foodName" id="foodName">
<input type="button" value="查询" onclick="query()">
<input type="button" value="添加" onclick="document.getElementById('addDiv').style.display='block';">
<table id="myTable" border="1">
<tr>
<th>菜品编号</th>
<th>菜品名</th>
<th>菜品价格</th>
<th>操作</th>
</tr>
</table>
</body>
<div id="addDiv" style="display:none;position: absolute;left:45%;z-index: 100;border:1px solid black;width: 240px;height: 65px">
菜品名 :<input type="text" name="myFoodName"><br/>
菜品价格:<input type="text" name="myFoodPrice"><br/>
<input type="button" value="保存" onclick="saveFood()"> <input type="button" value="关闭" onclick="document.getElementById('addDiv').style.display='none';">
</div>
<div id="updateDiv" style="display:none;position: absolute;left:45%;z-index: 100;border:1px solid black;width: 240px;height: 90px">
<input type="hidden" name="updateFoodId"><br/>
菜品名 :<input type="text" name="updateFoodName"><br/>
菜品价格:<input type="text" name="updateFoodPrice"><br/>
<input type="button" value="修改" onclick="updateFood()"> <input type="button" value="关闭" onclick="document.getElementById('updateDiv').style.display='none';">
</div>
</html>
MyBatis使用Generator自动生成代码
一、在pom.xml中添加plugin
<!-- 代码生成工具的配置 -->
<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<configuration>
<configurationFile>src/main/java/mbg.xml</configurationFile>
</configuration>
</plugin>
</plugins>
</build>
二、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>
<!-- 生成代码需要的步骤
1.连接数据库(驱动包 四要素)
-->
<classPathEntry location="E:\mysql-connector-java-5.1.26-bin.jar" />
<!-- 设置生成代码的规则
targetRuntime="MyBatis3"开发环境使用mybatis的版本
-->
<context id="DB2Tables" targetRuntime="MyBatis3">
<!-- 配置mysql的四要素 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/food"
userId="root"
password="123456">
</jdbcConnection>
<!-- -->
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!--实体类bean 带有get set -->
<javaModelGenerator targetPackage="com.et.entity" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!--sql语句相关的xml或注解的生成包路径 -->
<sqlMapGenerator targetPackage="com.et.resources" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 生成接口的位置
type="XMLMAPPER" 生成xml
type="ANNOTATEDMAPPER" 生成注解
-->
<javaClientGenerator type="ANNOTATEDMAPPER" targetPackage="com.et.dao" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!--告诉mbg需要生成代码的表
schema="DB2ADMIN"用于oracle中
-->
<table tableName="food" >
</table>
</context>
</generatorConfiguration>
完整版
<?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>
<!-- 配置mysql 驱动jar包路径.用了绝对路径 -->
<classPathEntry location="D:\Work\Java\eclipse\workspace\myBatisGenerator\WebContent\WEB-INF\lib\mysql-connector-java-5.1.22-bin.jar" />
<context id="yihaomen_mysql_tables" targetRuntime="MyBatis3">
<!-- 为了防止生成的代码中有很多注释,比较难看,加入下面的配置控制 -->
<commentGenerator>
<property name="suppressAllComments" value="true" />
<property name="suppressDate" value="true" />
</commentGenerator>
<!-- 注释控制完毕 -->
<!-- 数据库连接 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=utf8"
userId="root"
password="password">
</jdbcConnection>
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 数据表对应的model 层 -->
<javaModelGenerator targetPackage="com.yihaomen.model" targetProject="src">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- sql mapper 隐射配置文件 -->
<sqlMapGenerator targetPackage="com.yihaomen.mapper" targetProject="src">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 在ibatis2 中是dao层,但在mybatis3中,其实就是mapper接口 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.yihaomen.inter" targetProject="src">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 要对那些数据表进行生成操作,必须要有一个. -->
<table schema="mybatis" tableName="category" domainObjectName="Category"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
</context>
</generatorConfiguration>