版权声明:本文为作者原创书籍。转载请注明作者和出处,未经授权,严禁私自转载,侵权必究!!!
情感语录:业余生活要有意义,不要越轨!
Mybatis 的下载并搭建
下载地址:https://github.com/mybatis/mybatis-3
本文采用mybatis-3.5.0 正式版学习。最好把夹包和源码包都下载下来,方便看demo中的模板,mybatis-3.5.0.zip
,mybatis-3-mybatis-3.5.0.zip
Mybatis之 Sqlsession,所有的操作基本靠这个来完成的,那它到底有啥作用呢?
Sqlsession的作用:
1、向sql语句传入参数
2、执行SQL语句
3、获取执行sqL语句的结果
4、事务的控制
如何得到 Sqlsession:
1、通过配置文件获取数据库连接相关信息
2、通过配置信息构建Sqlsessionfactory
3、通过 Sqlsessionfactory打开数据库会话
public class DBAccess {
public SqlSession getSqlSession() throws IOException{
//第一步 通过配置文件获取数据库连接信息
Reader reader = Resources.getResourceAsReader("com/learn/config/Configuration.xml");
//第二步 通过配置信息构建一个 Sqlsessionfactor
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//第三步 通过 sqlsessionfactory打开个数据库会话
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
}
Configuration.xml?这是什么鬼,客官莫急,该配置文件就是我们刚下载下来的源码包中就有的,参照学习,路径:\src\test\java\org\apache\ibatis\submitted\complex_property
将该文件拷贝到你工程中,其他看不懂的先注释掉,只保留下面这段就好(源配置文件中并没有password这项 需要手动配置上,这里用mysql举例)
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="" value=""/>
</transactionManager>
<dataSource type="UNPOOLED">
<!--配置mysql驱动-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--配置数据库-->
<property name="url" value="jdbc:mysql://127.0.0.1:3306/teststudy"/>
<!--数据库的用户名-->
<property name="username" value="root"/>
<!--数据库的密码-->
<property name="password" value="zxy1546688949"/>
</dataSource>
</environment>
</environments>
新建数据库:"teststudy",名字谁便取,需要注意的是对应上Configuration.xml文件中配置的数据库url。新建一张"message"表,添加"id","title","content"三个字段,我这里方便测试id就没让自增长。
数据库和表都建立完成,激动的心颤动的手,我已经安奈不住想插入数据了,下面先举个例使用mybatis向数据库插入数据:
额??怎么插呢?先将Configuration.xml同目录下的User.xml配置文件也拷贝到工程并改名MessageBean.xml,并在Configuration.xml配置文件添加该文件的路径信息:
<mappers>
<mapper resource="com/learn/sqlxml/MessageBean.xml"/>
</mappers>
找到insert语句,简单修改下如下:
① 单条语句插入:
<!--注意拼接sql语法-->
<insert id="insertMessage" parameterType="com.learn.parameter.MessageParam" statementType="PREPARED"
keyProperty="id" useGeneratedKeys="true">
INSERT INTO message
(
id,
title,
content
)
VALUES
(
#{id,jdbcType=INTEGER},
#{title,jdbcType=VARCHAR},
#{content,jdbcType=VARCHAR}
)
</insert>
编写代码:
public void insertMsg(String id,String title, String content) {
DBAccess dbAccess = new DBAccess();
SqlSession sqlSession = null;
try {
sqlSession = dbAccess.getSqlSession();
//执行sql语句
MessageParam msg = new MessageParam();
msg.setId(id);
msg.setTitle(title);
msg.setContent(content);
sqlSession.insert("insertMessage", msg);
//注意提交
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != sqlSession) {
sqlSession.close();
}
}
}
测试代码:
@Test
public void testInsertMsg(){
ApiTest apiTest = new ApiTest();
//添加点信息
apiTest.insertMsg("1","hello","word");
}
执行上面代码刷新数据库
哎呀,这就插入数据库了,简直不能太方便..........多来几条数据试试看!
② 在MessageBean.xml中添加如下进行批量插入:
<!--批量插入-->
<insert id="insertListMsg" parameterType="java.util.List" useGeneratedKeys="true">
insert into message
(id,title,content)
values
<foreach collection="list" item="item" index="index" separator =",">
(
#{item.id,jdbcType=INTEGER},
#{item.title,jdbcType=VARCHAR},
#{item.content,jdbcType=VARCHAR}
)
</foreach>
</insert>
编写代码:
public void insertListMsg(List<MessageParam> list) {
DBAccess dbAccess = new DBAccess();
SqlSession sqlSession = null;
try {
sqlSession = dbAccess.getSqlSession();
//执行sql语句
sqlSession.insert("insertListMsg", list);
//注意提交
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != sqlSession) {
sqlSession.close();
}
}
}
测试代码:
@Test
public void testInsertListMsg(){
ApiTest apiTest = new ApiTest();
List<MessageParam> paramList = new ArrayList<>();
//添加点信息
for (int i = 2; i<22;i++){
MessageParam param = new MessageParam();
param.setId(i+"");
param.setTitle("你看我头上是几"+i);
param.setContent("这是第"+i+"条数据");
paramList.add(param);
}
apiTest.insertListMsg(paramList);
}
执行上面方法刷新数据库可以看到下面最新插入的数据。
属性介绍:useGeneratedKeys 参数只针对 insert 语句生效,默认为 false。当设置为 true 时,表示如果插入的表以自增列为主键,则允许 JDBC 支持自动生成主键,并可将自动生成的主键返回。
具体用法:
useGeneratedKeys=”true” keyProperty=”对应的主键的对象”。
③ 有了数据我们进行查询下,下面来个最简单的表查询,在MessageBean.xml中添加如下:
<!--resultMap 这里指查询的结果需要对应到那些列上 parameterType 指定参数类型,当多个参数是使用对象包装-->
<select id="queryListMessage" resultMap="messageResult">
SELECT * FROM Message
</select>
注:这里使用到了resultMap 属性,resultMap 这里指查询的结果需要对应到那些属性上(需要创建实体建立对应关系),resultMap 指定的实体类指向了id 为messageResult的配置信息,在MessageBean.xml中添加如下:
<!-- resultMap type指 MessageBean这个实体类,这步就相当传统的jdbc set方法避免了手动, id 在该节点中不允许同名-->
<resultMap type="com.learn.bean.MessageBean" id="messageResult">
<!--id 用于主键列-->
<id column="id" jdbcType="INTEGER" property="id"/>
<!--普通列-->
<result column="title" jdbcType="VARCHAR" property="title"/>
<result column="content" jdbcType="VARCHAR" property="content"/>
</resultMap>
编写代码:
public List<MessageBean> queryMessageList() {
List<MessageBean> listBean = new ArrayList<>();
DBAccess dbAccess = new DBAccess();
SqlSession sqlSession = null;
try {
sqlSession = dbAccess.getSqlSession();
listBean = sqlSession.selectList("queryListMessage");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != sqlSession) {
sqlSession.close();
}
}
return listBean;
}
测试用例:
@Test
public void testQureyListMsg(){
ApiTest apiTest = new ApiTest();
//查询全部
List<MessageBean> listBeans = apiTest.queryMessageList();
for (int i = 0; i < listBeans.size(); i++) {
System.out.println(listBeans.get(i).toString());
}
}
输出结果:
MessageBean{id='1', content='word', title='hello'}
MessageBean{id='2', content='这是第2条数据', title='你看我头上是几2'}
MessageBean{id='3', content='这是第3条数据', title='你看我头上是几3'}
MessageBean{id='4', content='这是第4条数据', title='你看我头上是几4'}
MessageBean{id='5', content='这是第5条数据', title='你看我头上是几5'}
MessageBean{id='6', content='这是第6条数据', title='你看我头上是几6'}
MessageBean{id='7', content='这是第7条数据', title='你看我头上是几7'}
........
④假如我只想查询id为5的这条数据呢?那好sql的基本操作条件查询,在MessageBean.xml中添加如下:
<!--条件查询-->
<select id="queryMessage" parameterType="com.learn.parameter.MessageParam" resultMap="messageResult">
SELECT * FROM Message WHERE id = #{id}
</select>
注:原生sql语句要查询id=5的这条数据是不是这样写:select * from message where id = 5
,开发中肯定不能写死在程序,是不是通过?
进行占位啊?那好在mybatis中是通过#{属性}
的方式,这个属性
是怎么来的呢?是由:parameterType
属性配置方式指定,如上parameterType="com.learn.parameter.MessageParam"
即:MessageParam实体的完整包路径:
public class MessageParam {
private String id;
private String content;
private String title;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
编写代码:
public MessageBean qureyMsg(String id) {
DBAccess dbAccess = new DBAccess();
SqlSession sqlSession = null;
MessageBean bean = null;
try {
sqlSession = dbAccess.getSqlSession();
//执行sql语句
bean = sqlSession.selectOne("queryMessage", id);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != sqlSession) {
sqlSession.close();
}
}
return bean;
}
测试用例:
@Test
public void testQureyOneMsg(){
ApiTest apiTest = new ApiTest();
//查询id为1的信息
MessageBean messageBean = apiTest.qureyMsg("5");
System.out.println(messageBean.toString());
}
输出结果:
2019-03-22 13:17:36,073 [main] DEBUG [Message.queryMessage] - <== Total: 1
MessageBean{id='5', content='这是第5条数据', title='你看我头上是几5'}
⑤删除数据:怎么通过mybatis删除数据信息呢?和查询等操作没什么区别,在MessageBean.xml中添加如下代码:
<delete id="delete" parameterType="com.learn.parameter.MessageParam">
DELETE FROM message WHERE id = #{id:INTEGER}
</delete>
编写代码:
public void delMsg(String id) {
DBAccess dbAccess = new DBAccess();
SqlSession sqlSession = null;
try {
sqlSession = dbAccess.getSqlSession();
//执行sql语句
sqlSession.delete("delete", id);
//注意提交
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != sqlSession) {
sqlSession.close();
}
}
}
测试用例:
@Test
public void testDelMsg(){
ApiTest apiTest = new ApiTest();
//删除第一条 hello word信息。
apiTest.delMsg("1");
}
结果输出:
2019-03-22 16:12:39,777 [main] DEBUG [Message.delete] - ==> Preparing: DELETE FROM message WHERE id = ?
2019-03-22 16:12:39,822 [main] DEBUG [Message.delete] - ==> Parameters: 1(String)
2019-03-22 16:12:39,836 [main] DEBUG [Message.delete] - <== Updates: 1
可以看到成功的删除了。思考!!!! 我要删除多条数据怎么办?mybatis又不支持多参数传入,咳咳,那我穿入一个集合可以不呢?当然是可以的,如下:
<!--批量删除 separator属性可以指定拼接的格式,如ids = 1,2,3 -->
<delete id="deleteLisMsg" parameterType="java.util.List">
DELETE FROM message WHERE id in
(
<foreach collection="list" item="item" separator=",">
#{item}
</foreach>
)
</delete>
编写代码:
public void testDeletebatcheMsg(List<String> ids) {
DBAccess dbAccess = new DBAccess();
SqlSession sqlSession = null;
try {
sqlSession = dbAccess.getSqlSession();
//执行sql语句
sqlSession.delete("deleteLisMsg", ids);
//注意提交
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != sqlSession) {
sqlSession.close();
}
}
}
测试用例:
@Test
public void testDeletebatcheMsg(){
ApiTest apiTest = new ApiTest();
//通过id 删除点信息
List<String> ids = new ArrayList<>();
ids.add("2");
ids.add("3");
ids.add("4");
ids.add("5");
apiTest.testDeletebatcheMsg(ids);
}
输出结果:
2019-03-22 16:19:59,893 [main] DEBUG [Message.deleteLisMsg] - ==> Preparing: DELETE FROM message
WHERE id in( ? , ? , ? , ? )
2019-03-22 16:19:59,944 [main] DEBUG [Message.deleteLisMsg] - ==> Parameters: 2(String), 3(String), 4(String),
5(String)
2019-03-22 16:19:59,965 [main] DEBUG [Message.deleteLisMsg] - <== Updates: 4
可以看到成功的删除四条信息。等等!!! 在你文章里能看到打印的sql语句和参数,为嘛我在控制台啥也看不见呢?what amazing ????? 接触过SSH框架的都知道可以格式化sql语句输出,mybaits木有这玩意。怎么办?客观别急,放下手中的菜刀。我们可以通过打印的方式将其输出嘛。
准备打印夹包并放入工程添加上依赖(add as library),没有的客观也别急,文末源码里会给出:
commons-logging-1.2.jar
log4j-1.2.17.jar
log4j-core-2.11.1.jar
log4j-api-2.11.1.jar
编写log4j.properties
配置文件,我这里直接放入了src下,规范起见还是建议放入到指定的配置文件目录下比较好,方便以后管理:
log4j.rootLogger=DEBUG,Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.org.apache=INFO
好了就上面两个步骤,再次操作就能看到sql语句啦!!
细心的同学会发现上面的代码是不是有问题啊,整个工程中如果有同名的方法,那不是在调用方法时,怎么区分该调那个呢?像这样写sqlSession.delete("deleteLisMsg", ids);
肯定是不好的,在项目中应该 命名空间+方法名
才是正确的写法,指定到具体的那个配置文件上的那个方法。
我们的MessageBean.xml命名空间用的 Message
命名
<!-- namespace 指定命名空间,同一命名空间下不支持相同的id名称 -->
<mapper namespace="Message">
正确的写法应该是 sqlSession.delete("Message.deleteLisMsg", ids);
,好了文章就介绍到这里!!!!
网友评论