mybatis
1.mybatis
作用:封装了jdbc操作,简化数据库访问代码。
封装功能如下:
--封装了获取连接,执行sql,释放链接。
--封装了sql参数设置
--封装了记录映射成实体对象过程,实体类属性名要与查询结果集ResultSet中的列名保持一致。
mybatis需要的jar包:
mybatis,mysql-connector,SqlMapConfig.xml,EmpMapper.xml
返回数据类型:
--实体对象
a。如果属性名与字段一致,使用resultType
b。属性名与字段不一致。有两种方法:
1.给字段加别名,使他与属性名一致
2.使用resultMap替代resultType定义
例子:
<!-- 用的CostBean1类,而不是Cost,所以用的是resultMap ,这样做麻烦,推荐用sql别名-->
<select id="findCost" resultMap="costMap" >
select cost_id,name,status,createtime from cost
</select>
<resultMap type="org.alexhe.entity.CostBean1" id="costMap">
<id property="id" column="cost_id"/><!-- 主键字段用id,这里实体属性是id,数据表里字段是cost_id,不一致 -->
<result property="name" column="name"/>
<result property="status" column="status"/>
<result property="createTime" column="createtime"/> <!-- 这里实体属性是createTime,数据表里字段是createtime,不一致 -->
</resultMap>
--Map集合
<select id="findMap" resultType="map">
select cost_id,name from cost
</select>
java代码:
//测试返回Map结果
List<Map<String,Object>> list=session.selectList("findMap");
for(Map<String,Object> data:list){
System.out.println(data.get("cost_id")+":"+data.get("name"));
}
--基本值
<select id="findRows" resultType="int">
select count(*) from cost
</select>
int rows=session.selectOne("findRows");
2.Mapper映射器接口规则(只要写一个接口,用起来简单)
a。根据xml里的Sql定义的id属性当接口方法名
b。根据xml里sql定义的parameterType类型当方法参数类型
c。根据sql定义的resultType类型定义方法返回类型(多行使用List<泛型>;单行使用泛型)
d。将sql定义文件<mapper>的namespace属性指定成包名.接口名。
<mapper namespace="org.alexhe.dao.ICostDao" >
例子:
sqlMapConfig.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="dbConfig.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED"> <!-- //POOLED指 是一个数据源的实现类(org.apache.ibatis.datasource.pooled.PooledDataSource) -->
<property name="driver" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 老方法映射 <mapper resource="mapper/User.xml"/> --> <!-- //引入mapper -->
<!-- 接口映射 -->
<mapper resource="org/alexhe/sql/CostMapper.xml"/>
</mappers>
</configuration>
dbConfig.properties:
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/wahaha?useSSL=false&useUnicode=true&characterEncoding=utf8
db.username=root
db.password=xxxx
接口Dao,ICostDao:
package org.alexhe.dao;
import java.util.List;
import org.alexhe.entity.Cost;
public interface ICostDao {
public List<Cost> findAll();
}
实体类:Cost:
package org.alexhe.entity;
import java.io.Serializable;
import java.util.Date;
public class Cost implements Serializable{
private Integer cost_id;
private String name;
private Long base_duration;
private Double base_cost;
private Double unit_cost;
private String status;
private String descr;
private Date createtime;
private Date starttime;
private String cost_type;
实体类:CostBean1:
package org.alexhe.entity;
import java.util.Date;
public class CostBean1 {
private Integer id;
private String name;
private String status;
private Date createTime;
mybatis sql文件:CostMapper.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="org.alexhe.dao.ICostDao" >
<select id="findAll" resultType="org.alexhe.entity.Cost">
select * from cost
</select>
<select id="findPage" resultType="org.alexhe.entity.Cost" parameterType="int">
select * from cost limit #{begin},5
</select>
<select id="findMap" resultType="map">
select cost_id,name from cost
</select>
<select id="findRows" resultType="int">
select count(*) from cost
</select>
<!-- 用的CostBean1类,而不是Cost,所以用的是resultMap ,这样做麻烦,推荐用sql别名-->
<select id="findCost" resultMap="costMap" >
select cost_id,name,status,createtime from cost
</select>
<resultMap type="org.alexhe.entity.CostBean1" id="costMap">
<id property="id" column="cost_id"/><!-- 主键字段用id -->
<result property="name" column="name"/>
<result property="status" column="status"/>
<result property="createTime" column="createtime"/>
</resultMap>
</mapper>
mybatis的util文件用来去的SqlSession对象:
package org.alexhe.util;
import java.io.IOException;
import java.io.Reader;
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 MyBatisUtil {
public static SqlSession getSqlSession(){
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
//加载SqlMapConfig.xml文件
String conf="sqlMapConfig.xml";
Reader reader=null;
try {
reader = Resources.getResourceAsReader(conf);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//获取SqlSessionFactory
SqlSessionFactory factory=builder.build(reader);
//获取SqlSession
SqlSession session=factory.openSession();
return session;
}
}
Test程序:
package org.alexhe;
import java.util.List;
import java.util.Map;
import org.alexhe.dao.ICostDao;
import org.alexhe.entity.Cost;
import org.alexhe.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
public class TestCost {
public static void main(String[] args) {
// TODO Auto-generated method stub
SqlSession session=MyBatisUtil.getSqlSession();
//测试返回Map结果
List<Map<String,Object>> list=session.selectList("findMap");
for(Map<String,Object> data:list){
System.out.println(data.get("cost_id")+":"+data.get("name"));
}
//测试Mapper映射器接口
ICostDao dao=session.getMapper(ICostDao.class);
List<Cost> list2=dao.findAll();
System.out.println(list2);
session.close();
}
}
cloud note项目 unit 10 01
1.mybatis动态sql
可以根据传入sql不同,生成不同的sql语句
mybatis提供了一套标签,用语在xml中动态拼凑sql语句。
select * from emp
<if test="xxx">...</if>
<chosse>
<when test="xxx">...</when>
<when test="xxx">...</when>
<otherwise>...</otherwise>
</chosse>
<foreach></foreach>
<where>
<set>
a.组合查询功能
笔记:标题,状态,开始日期,结束日期。
/note/hightSearch.do
-->HightSearchController
-->NoteService
-->NoteDao-->cn_note
-->返回NoteResult结构的json数据
NoteMapper.xml
<!-- 组合查询 -->
<select id="hightSearch" parameterType="map" resultType="org.alexhe.note.entity.Note">
select * from cn_note
<where>
<if test="title!=null">
cn_note_title like #{title}
</if>
<if test="status!=null">
and cn_note_status_id = #{status}
</if>
<if test="beginDate!=null">
and cn_note_create_time >=#{beginDate}
</if>
<if test="endDate!=null">
and cn_note_create_time <=#{endDate}
</if>
</where>
</select>
然后写dao
package org.alexhe.note.dao;
import java.util.List;
import java.util.Map;
import org.alexhe.note.entity.Note;
import org.springframework.stereotype.Repository;
@Repository("noteDao")
public interface INoteDao {
public List<Note> hightSearch(Map params);
public void save(Note note);
public List<Map> findByBookId(String bookId);
}
然后写service
package org.alexhe.note.service;
import org.alexhe.note.entity.NoteResult;
public interface INoteService {
public NoteResult hightSearch(String title,String status,Long begin,Long end);
public NoteResult addNote(String noteTitle,String bookId,String userId);
public NoteResult loadNotes(String bookId);
}
然后写serviceImpl
@Override
public NoteResult hightSearch(String title, String status, Long begin, Long end) {
// TODO Auto-generated method stub
NoteResult result=new NoteResult();
Map params=new HashMap();
if(title != null && "".equals(title)){
title ="%"+title+"%";
params.put("title", title);
}
if(status !=null && !"0".equals(status)){
params.put("status", status);
}
if(begin !=null){
params.put("beginDate", begin);
}
if(end != null){
params.put("endDate", end);
}
List<Note> list=noteDao.hightSearch(params);
result.setStatus(0);
result.setData(list);
result.setMsg("查询成功");
return result;
}
最后写Controller:
package org.alexhe.note.controller.note;
import javax.annotation.Resource;
import org.alexhe.note.entity.NoteResult;
import org.alexhe.note.service.INoteService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/note")
public class HightSearchControler {
@Resource
private INoteService noteService;
@RequestMapping("/highSearch.do")
@ResponseBody
public NoteResult execute(String title,String status,Long begin,Long end){
NoteResult result=noteService.hightSearch(title, status, begin, end);
return result;
}
}
b。动态更新Sql
笔记标题
创建时间
所属笔记本
updateNote(note)-->
update cn_note set cn_notebook_id=?,cn_note_title=?,cn_user_id=?,cn_status_id=?,cn_note_type_id=?,cn_note_body=?,cn_note_create_time=?,cn_note_last_modify_time=? where cn_note_id=?
<!-- 动态更新,可以将不为null的属性更新到数据库 -->
<update id="dynamicUpdate" parameterType="org.alexhe.note.entity.Note">
update cn_note
<set>
<if test="cn_notebook_id != null">
cn_notebook_id=#{cn_notebook_id},
</if>
<if test="cn_note_title != null">
cn_note_title=#{cn_note_title},
</if>
<if test="cn_user_id != null">
cn_user_id=#{cn_user_id},
</if>
<if test="cn_note_status_id != null">
cn_note_status_id=#{cn_note_status_id},
</if>
<if test="cn_note_type_id != null">
cn_note_type_id=#{cn_note_type_id},
</if>
<if test="cn_note_body != null">
cn_note_body=#{cn_note_body},
</if>
<if test="cn_note_create_time != null">
cn_note_create_time=#{cn_note_create_time},
</if>
<if test="cn_note_last_modify_time != null">
cn_note_last_modify_time=#{cn_note_last_modify_time}
</if>
</set>
where cn_note_id=#{cn_note_id}
</update>
c。批量删除
delete from cn_note where cn_note_id in(xxx,xxx,xxx)
<!-- 批量删除 -->
<delete id="deleteNotes">
delete from cn_note
where cn_note_id in
<foreach collection="array" item="iiiid" open="(" close=")" separator=",">
#{iiiid}
</foreach>
</delete>
1.mybatis 关联映射 cloud note项目 unit11 01
cn_user
cn_notebook-->cn_user_id(关联字段)
cn_user.cn_user_id=cn_notebook.cn_user_id
cn_user-->User
cn_notebook-->NoteBook
关联映射主要优点:便于查询相关表记录信息
对象关联:对象之间建立关系,需要使用关联属性建立关系。关联属性一般有下面两种类型:单个实体对象类型;集合类型
关联查询例子1:
第一步User这个bean类新增属性,并添加get set方法
private List<NoteBook> books;
第二步,mybatis的xml文件里,resultType改成resultMap,名字userMap可以随便起
<!-- 根据用户id提取cn_user信息及其相关cn_notebook信息-->
<select id="findUser" parameterType="string" resultMap="userMap"> 起个名字教userMap
select * from cn_user where cn_user_id=#{userId}
</select>
<select id="findBooks" parameterType="string"
resultType="org.alexhe.note.entity.NoteBook">
select * from cn_notebook where cn_user_id=#{userId}
</select>
<resultMap type="org.alexhe.note.entity.User" id="userMap"> 指向上面的userMap
<!-- user中cn_user_id,cn_user_name默认按名称匹配 -->
<!-- 定义关联属性books如何加载 -->
<collection property="books" User类里的字段名字
javaType="java.util.List" 数据类型List
ofType="org.alexhe.note.entity.NoteBook" 这是泛型
select="findBooks" 指向上面的findBooks
column="cn_user_id"> 用userid进行关联
</collection>
</resultMap>
关联数据抓取策略:
--单独发送一个sql抓取,上面关联查询例子1
--推荐,(就是下面关联查询例子2)将关联数据与朱对象数据一起抓取(基于表关联查询 join... on...)
关联查询例子2:
<!-- 关联查询案例2 -->
<select id="findAll" resultMap="userMap2">
select * from cn_user usr left outer join cn_notebook book on(usr.cn_user_id=book.cn_user_id)
</select>
<resultMap type="org.alexhe.note.entity.User" id="userMap2">
<result property="cn_user_id" column="cn_user_id"/>
<result property="cn_user_name" column="cn_user_name"/>
<result property="cn_user_password" column="cn_user_password"/>
<result property="cn_user_token" column="cn_user_token"/>
<result property="cn_user_desc" column="cn_user_desc"/>
<collection property="books"
javaType="java.util.List"
ofType="org.alexhe.note.entity.NoteBook">
<result column="cn_notebook_id" property="cn_notebook_id"/>
<result column="cn_user_id" property="cn_user_id"/>
<result column="cn_notebook_type_id" property="cn_notebook_type_id"/>
<result column="cn_notebook_name" property="cn_notebook_name"/>
<result column="cn_notebook_desc" property="cn_notebook_desc"/>
<result column="cn_notebook_createtime" property="cn_notebook_createtime"/>
</collection>
</resultMap>