在这里,我们将给大家分享关于商城实现简单的限时促销的知识,让您更了解商城实现简单的限时促销方案的本质,同时也会涉及到如何更有效地120行代码手写一个简单的MyBatis实现简单的CRUD、5、实现简单
在这里,我们将给大家分享关于商城实现简单的限时促销的知识,让您更了解商城实现简单的限时促销方案的本质,同时也会涉及到如何更有效地120行代码手写一个简单的MyBatis实现简单的CRUD、5、实现简单的代币、Android Studio实现简单的购物商城界面、c# 实现简单的串口通讯的内容。
本文目录一览:- 商城实现简单的限时促销(商城实现简单的限时促销方案)
- 120行代码手写一个简单的MyBatis实现简单的CRUD
- 5、实现简单的代币
- Android Studio实现简单的购物商城界面
- c# 实现简单的串口通讯
商城实现简单的限时促销(商城实现简单的限时促销方案)
在商品表里 添加四个字段 是否参加促销 促销开始时间 促销结束时间 促销价格
获取服务器当时的时间 与 后台添加的 促销时间 对比 例如 :
获取正在促销商品 从数据库中取出 正在促销 且 现在时间 大于 开始时间 小于结束时间 的商品
即为正在促销的商品
限时抢购可能有点麻烦 要考虑到高并发的 问题 这个时候就要用到缓存数据库了 建立缓存 给数据库加一道墙
120行代码手写一个简单的MyBatis实现简单的CRUD
首发于Enaium的个人博客
不用XML只用注解
首先需要创建6个注解
SQL用于输入SQL语句
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQL {
String[] value();
}
用来表示这个方法是Update
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Update {
}
用来表示这个方法是Select
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Select {
}
用来表示这个方法是Insert
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Insert {
}
用来表示这个方法是Delete
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Delete {
}
用来表示方法参数名
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Param {
String value();
}
好了注解写完了
开始写主类
用map实现简单的配置,然后读取配置连接数据库,然后程序关闭的时候关闭连接。
public class Satis {
private final Statement statement;
public Satis(Map<String, String> config) throws Exception {
Class.forName(config.get("driver"));
Connection connection = DriverManager.getConnection(config.get("url"), config.get("username"), config.get("password"));
statement = connection.createStatement();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
statement.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}));
}
}
创建getMapper
方法。
public <T> T getMapper(Class<?> mapper) {
}
使用动态代理。
public <T> T getMapper(Class<?> mapper) {
Object instance = Proxy.newProxyInstance(mapper.getClassLoader(), new Class<?>[]{mapper}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
};
return (T) instance;
}
遍历方法获取方法是否有SQL
这个注解。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.isAnnotationPresent(SQL.class)) {
}
return null;
}
创建4个方法,分别获取方法是否有这几个注解。
private boolean isSelect(Method method) {
return method.isAnnotationPresent(Select.class);
}
private boolean isDelete(Method method) {
return method.isAnnotationPresent(Delete.class);
}
private boolean isInsert(Method method) {
return method.isAnnotationPresent(Insert.class);
}
private boolean isUpdate(Method method) {
return method.isAnnotationPresent(Update.class);
}
遍历SQL
注解的值。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.isAnnotationPresent(SQL.class)) {
SQL sql = method.getAnnotation(SQL.class);
for (String value : sql.value()) {
}
}
return null;
}
获取方法上是否有Select
或Delete
注解,是的话把SQL
参数的值(获取参数的Param
注解的值)替换为调用方法时的参数。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.isAnnotationPresent(SQL.class)) {
SQL sql = method.getAnnotation(SQL.class);
for (String value : sql.value()) {
if (isSelect(method) || isDelete(method)) {
int index = 0;
for (Parameter parameter : method.getParameters()) {
if (parameter.isAnnotationPresent(Param.class)) {
Param param = parameter.getAnnotation(Param.class);
value = value.replace("#{" + param.value() + "}", args[index].toString());
}
index++;
}
}
}
}
return null;
}
如果是Insert
或Update
注解,获取第一个参数,获取这个参数的所有方法并获取值。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.isAnnotationPresent(SQL.class)) {
SQL sql = method.getAnnotation(SQL.class);
for (String value : sql.value()) {
if (isInsert(method) || isUpdate(method)) {
Class<?> parameterType = method.getParameterTypes()[0];
for (Field declaredField : parameterType.getDeclaredFields()) {
value = value.replace("#{" + declaredField.getName() + "}", "\"" + parameterType.getMethod(getGetMethodName(declaredField.getName())).invoke(args[0]).toString() + "\"");
}
}
}
}
return null;
}
简单的获取方法名的方法。
private String getSetMethodName(String name) {
return "set" + name.substring(0, 1).toUpperCase(Locale.ROOT) + name.substring(1);
}
private String getGetMethodName(String name) {
return "get" + name.substring(0, 1).toUpperCase(Locale.ROOT) + name.substring(1);
}
执行SQL语句,如果有返回值那就返回实例化。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.isAnnotationPresent(SQL.class)) {
SQL sql = method.getAnnotation(SQL.class);
for (String value : sql.value()) {
String typeName = method.getGenericReturnType().getTypeName();
ResultSet resultSet = statement.executeQuery(value);
if (!typeName.equals("void")) {
return toEntity(resultSet, typeName);
}
}
}
return null;
}
将返回值实例化。
private <T> T toEntity(ResultSet resultSet, String className) throws SQLException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException {
boolean list = className.contains("<");//是不是列表
if (list) {
className = className.substring(className.indexOf("<") + 1, className.lastIndexOf(">"));//获取列表的泛型
}
Class<?> klass = Class.forName(className);
HashMap<String, Class<?>> fieldNameList = new HashMap<>();
for (int i = 0; i < resultSet.getMetaData().getColumnCount(); i++) {//获取字段和参数
fieldNameList.put(resultSet.getMetaData().getColumnName(i + 1), Class.forName(resultSet.getMetaData().getColumnClassName(i + 1)));
}
List<Object> objectList = new ArrayList<>();
while (resultSet.next()) {
Object instance = klass.newInstance();//实例化
for (Map.Entry<String, Class<?>> entry : fieldNameList.entrySet()) {//遍历字段
//调用set方法赋值
klass.getMethod(getSetMethodName(entry.getKey()), entry.getValue()).invoke(instance, resultSet.getObject(entry.getKey(), entry.getValue()));
}
objectList.add(instance);//添加到列表
}
resultSet.close();//关闭
if (objectList.isEmpty()) {
return null;//如果列表为空返回null
}
return list ? (T) objectList : (T) objectList.get(0);//判断是否为列表,如果是直接返回,如果不是取第一个
}
好了已经写完了。
现在来测试
实体
@Data
@AllArgsConstructor
public class AccountEntity {
private Long id;
private String name;
private Integer age;
public AccountEntity() {//用了lombok就不会自动生成无参构造方法了
}
}
接口
public interface AccountMapper {
@Select
@SQL("select * from account")
List<AccountEntity> getAll();
@Select
@SQL("select * from account where id = #{id}")
AccountEntity getById(@Param("id") Serializable id);
@Delete
@SQL("delete from account where id = #{id}")
void deleteById(@Param("id") Serializable id);
@Insert
@SQL("insert into account(id, name, age) values (#{id}, #{name}, #{age})")
void insert(AccountEntity accountEntity);
@Update
@SQL("update account set name=#{name}, age=#{age} where id=#{id}")
void update(AccountEntity accountEntity);
}
主类
public class Main {
public static void main(String[] args) throws Exception {
Satis satis = new Satis(ImmutableMap.of(
"url", "jdbc:mariadb://localhost:3306/enaium?useUnicode=true&characterEncoding=UTF-8",
"driver", "org.mariadb.jdbc.Driver",
"username", "root",
"password", "root"));//使用guava
AccountMapper mapper = satis.getMapper(AccountMapper.class);//获取Mapper
System.out.println(mapper.getById(1));//获取ID为1的Account
mapper.getAll().forEach(System.out::println);//获取所有Account
mapper.insert(new AccountEntity(0L, "Enaium", 1));//插入一个新的Account
mapper.getAll().forEach((it) -> {//把所有Account的Age都改为0
it.setAge(0);
mapper.update(it);
});
}
}
源码
5、实现简单的代币

一、代币源码。
这里我们创建一个 Token2 的合约,并粘贴到在线编译器。https://ethereum.github.io/browser-solidity
pragma solidity 0.4.16;
contract Token2 {
uint[] public balancesOf;
function Token() {
balancesOf.push(100);
balancesOf.push(200);
}
//转账功能
function transfer(uint _from, uint _to, uint _amount) {
balancesOf[_from] -= _amount;
balancesOf[_to] += _amount;
}
//挖矿功能
function mint(uint value) {
balancesOf[0] += value;
}
}
二、调用代码。
点击 create,就会在内存中将该智能合约创建一个实例,即将下面的 web3 deploy 代码部署在虚拟的内存中。
合约中的每个方法和成员变量,在右边都会有对应的调用按钮。
1、初始化数组。
点击一下 “Token”,就相当于调用了代码中的下面方法。把 2 个数放入数组,如果调用多次,会一直放入,数组一直变大。
function Token() {
balancesOf.push(100);
balancesOf.push(200);
}
2、获取数组的值。
点击 “balancesOf” 按钮,输入数组下标,就会显示对应下标的值。这里输入 1,显示 200;输入 0,显示 100
2、测试转账。
输入数组下标,从 1 转账到 0,转账 30 个。调用如下:
查询后知道,1 减少了 30;0 增加了 30。
mint 方法也同样的道理。
参考文档: http://www.ethchinese.com/?p=784
Android Studio实现简单的购物商城界面
项目目录
- 一、项目概述
- 二、开发环境
- 三、详细设计
- 1、商品列表的搭建
- 2、商品条目的搭建
- 3、数据适配器的搭建
- 3.1、常用数据适配器(Adapter)
- 3.2、BaseAdapter的方法
- 3.3、定义数据适配器
- 3.4、优化数据适配器
- 4、适配的数据和图片集合
- 四、项目效果
- 五、项目总结
- 六、源码下载
一、项目概述
随着网络的发展、手机等电子产品的普及和电商的崛起,人们越来越倾向于足不出户的网上购物,网购已经成为一种趋势,在我们的日常消费模式当中已经占据了很大一部分,几乎生活当中能见到的东西在购物平台上都可以买到。
那么这些购物平台是如何显示这些商品列表的呢?当我们去浏览商品列表时这些信息是怎么添加上去的呢?带着这些疑问,本次项目就带大家来学习ListView的使用。
二、开发环境
三、详细设计
1、商品列表的搭建
首先搭建商品列表的layout文件,最外层采用的是LinearLayout(线性布局),orientation(方向)选择的是vertical(垂直),这样界面内的控件就是从上至下垂直排列了。
接下来放置一个TextView控件,width设为math_parent,即填充满父容器,宽度和父容器一样;高度设置的为45dp,文本内容text是"购物商城",字体大小textSize设为18sp,字体颜色textColor设为白色,背景background设为橙色,gravity(文字位置)显示为center(水平居中)。
最后放置一个ListView控件,即列表,宽度填充满屏幕,高度自适应。预览效果如图:
代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="45dp"
android:text="购物商城"
android:textSize="18sp"
android:textColor="#FFFFFF"
android:background="#FF8F03"
android:gravity="center"/>
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
2、商品条目的搭建
有ListView一定要有item,因为光有列表不行,还必须给列表添加内容,而item就是列表里面每一行显示的内容,两者相辅相成,共同组成列表。
商品条目界面的搭建只需要搭建第一行的item,其他item格式一样,只需要在主文件MainActivity中定义一个数组,写好商品内容,然后自动生成。所以先来搭建好第一行的item。
最外层布局选择的是RelativeLayout(相对布局),顶端放置了一个ImageView控件,用于显示商品的图片,宽度和高度自己设定,位置选择的是垂直居中。
接下来放置了一个子布局RelativeLayout,使用android:layout_toRightOf="@+id/iv"语句将子布局整个放置在刚刚图片的右侧,内容依旧是垂直居中。
在这个子布局中,先放置了一个TextView控件,用于显示商品名称。文本id 设为 title,宽度和高度都是设定为依据内容大小调整的,文本内容为“桌子”,文本大小为20sp,文本颜色选择的是黑色。
又放置了一个TextView,主要用于显示价格。id设为tv_price,宽和高自适应,文本内容为“价格”,使用android:layout_below="@+id/title" 语句将它放到商品名称的TextView下方。
最后放置了一个TextView,主要用于显示价格的数字。具体属性设定同上,使用android:layout_toRightOf="@+id/tv_price"语句将它放在价格的TextView右方,上边距设为10dp。
界面预览效果如图:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<ImageView
android:id="@+id/iv"
android:layout_width="150dp"
android:layout_height="120dp"
android:layout_centerVertical="true"/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@+id/iv"
android:layout_centerVertical="true">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="桌子"
android:textSize="20sp"
android:textColor="#000000"/>
<TextView
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="价格:"
android:textSize="20sp"
android:layout_marginTop="10dp"
android:layout_below="@+id/title"
android:textColor="#FF8F03"/>
<TextView
android:id="@+id/price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1000"
android:textSize="20sp"
android:layout_below="@+id/title"
android:layout_toRightOf="@+id/tv_price"
android:textColor="#FF8F03"
android:layout_marginTop="10dp"/>
</RelativeLayout>
</RelativeLayout>
3、数据适配器的搭建
3.1、常用数据适配器(Adapter)
3.2、BaseAdapter的方法
3.3、定义数据适配器
搭建完列表后,现在在MainActivity中要定义数据适配器,将数据转换为我们可以看到的视图。
先定义了MyBaseAdapter继承于BaseAdapter,包含四个方法:
(1)getCount方法获取item的总数,返回ListView Item条目代表的对象;
(2)getItem方法,参数为item的下标,返回item的数据对象;
(3)getItemId方法,参数为item的下标,返回item的id;
(4)View getView方法,为获取相应position对应的Item视图。position是当前Item的位置,convertView用于复用旧视图,parent用于加载XML布局。
定义一个ViewHolder类,声明三个成员变量。 紧接着将商品名称title、价格price和金额iv和相应的控件id进行绑定,若convertView为null,则找到控件并加载视图,不为空则直接显示商品信息。适配器MyBaseAdapter 的代码如下:
class MyBaseAdapter extends BaseAdapter{
@Override
public int getCount(){ //得到item的总数
return titles.length; //返回ListView Item条目代表的对象
}
@Override
public Object getItem(int position){
return titles[position]; //返回item的数据对象
}
@Override
public long getItemId(int position){
return position; //返回item的id
}
@Override
public View getView(int position, View convertView, ViewGroup parent){//获取item中的View视图
ViewHolder holder;
if(convertView==null){
convertView=View.inflate(MainActivity.this,R.layout.list_item, null);
holder=new ViewHolder();
holder.title=convertView.findViewById(R.id.title);
holder.price=convertView.findViewById(R.id.price);
holder.iv=convertView.findViewById(R.id.iv);
convertView.setTag(holder);
}else{
holder=(ViewHolder)convertView.getTag();
}
holder.title.setText(titles[position]);
holder.price.setText(prices[position]);
holder.iv.setimageResource(icons[position]);
return convertView;
}
}
3.4、优化数据适配器
刚刚的代码是使用使用ViewHolder类和复用convertView优化过的代码,不仅减少了耗时操作,而且防止了数据量过大导致内存溢出的问题,一举两得。
class ViewHolder{
TextView title;
TextView price;
ImageView iv;
}
4、适配的数据和图片集合
在MainActivity类中定义了三个数组,分别是titles数组,用于显示商品列表;prices数组,用于显示金额单价;icons集合,用于显示drawable里面导入的商品图片。然后使用onCreate方法初始化控件,创建并设置了Adapter,代码如下:
public class MainActivity extends AppCompatActivity {
//需要适配的数据
private String[] titles={"桌子","苹果","蛋糕","线衣","猕猴桃","围巾"};
private String[] prices={"1800元","10元/kg","300元","350元","280元"};
//图片集合
private int[] icons={R.drawable.table,R.drawable.apple,R.drawable.cake,
R.drawable.wearclothes,R.drawable.kiwifruit,R.drawable.scarf};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化ListView控件
ListView listView=findViewById(R.id.lv);
//创建一个Adapter的实例
MyBaseAdapter mAdapter=new MyBaseAdapter();
//设置Adapter
listView.setAdapter(mAdapter);
}
至此,项目详细设计介绍完毕。(码字不易,腰酸背痛ing)
四、项目效果
打开模拟器运行,商品列表界面如图,可以上下拖动。
五、项目总结
本次购物商城项目主要考验学生对于ListView和基本控件的使用,希望大家可以熟练掌握,这些知识点在Android项目中会经常使用,因此希望大家能够熟练掌握上述知识点的使用,方便后续开发项目。
六、源码下载
需要源码学习的同学可以关注我的微信公众号,回复:购物商城,即可获取源码,还有很多Android项目等你来学习。
任何事情都应该去尝试一下,因为你无法知道,什么样的事或者什么样的人将会改变你的一生。
c# 实现简单的串口通讯
本文提供一个用C#实现串口通讯实例,亲自编写,亲测可用!
开发环境:
VS2008+.net FrameWork3.5(实际上2.0应该也可以)
第一步
创建一个WinForm窗体,拉入一些界面元素
重点就是,图中用红框标出的,工具箱——组件——SerialPort,做.net串口通讯,这是必备控件
第二步
设置SerialPort控件属性
用C#向串口发送数据没什么特别的,就是调用SerialPort的Write方法往串口写数据就行
但是从串口那里接收数据的方式就比较特别了
首先,需要在代码里声明一个特别的事件函数
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { this.Invoke(new EventHandler(UpdateUIText)); }
此函数是用来绑定到SerialPort控件的DataReceived事件
顾名思义,这个事件就是在接收到串口返回的数据时触发,里面就一句代码
对这句代码有兴趣的可以私下再去研究,这里就不赘述了
总之,这句代码的用途就是用来调动另一个函数,对界面UI元素的值进行更新(当然你也可以在里面执行其他操作)
private void UpdateUIText(object s, EventArgs e) { try { //必须要阻塞线程一段时间,以免在交易超时的情况下,由于read太快导致读取不完整 System.Threading.Thread.Sleep(500); string txt = serialPort.ReadExisting(); txt_Received.Text = txt; } catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); } }
第三步
开始写逻辑代码,废话不多说,直接贴上来
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WinForm串口通讯 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { string[] ports = System.IO.Ports.SerialPort.GetPortNames(); if (ports.Length == 0) { MessageBox.Show("本机没有串口!"); } Array.Sort(ports); serialPort.PortName = ports[0];//串口号COM3 serialPort.BaudRate = 115200;//波特率 serialPort.DataBits = 8;//数据位 serialPort.StopBits = System.IO.Ports.StopBits.One;//停止位 serialPort.Encoding = System.Text.Encoding.GetEncoding("GB2312");//此行非常重要,解决接收中文乱码的问题 // 打开串口 try { serialPort.Open(); } catch (Exception ex) { //捕获到异常信息,创建一个新的comm对象,之前的不能用了。 serialPort = new System.IO.Ports.SerialPort(); //将异常信息传递给用户。 MessageBox.Show(ex.Message); return; } } private void button1_Click(object sender, EventArgs e) { string msgOrder = txt_Msg.Text; //MessageBox.Show(msgOrder); serialPort.Write(msgOrder); } private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { this.Invoke(new EventHandler(UpdateUIText)); } private void UpdateUIText(object s, EventArgs e) { try { //必须要阻塞线程一段时间,以免在交易超时的情况下,由于read太快导致读取不完整 System.Threading.Thread.Sleep(500); string txt = serialPort.ReadExisting(); txt_Received.Text = txt; } catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); } } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { try { if (serialPort != null && serialPort.IsOpen) { serialPort.Close(); serialPort.Dispose(); } } catch (Exception ex) { //将异常信息传递给用户。 MessageBox.Show(ex.Message); return; } } } }
至此,一个简单完整的串口通讯就完成了,希望对你们有所帮助
以上就是c# 实现简单的串口通讯的详细内容,更多关于c# 串口通讯的资料请关注其它相关文章!
- C#基于WinForm实现串口通讯
- C#实现简单串口通讯实例
- C#基于SerialPort类实现串口通讯详解
- C#串口通讯概念及简单的实现方法
- C#操作串口通信协议Modbus的常用方法介绍
我们今天的关于商城实现简单的限时促销和商城实现简单的限时促销方案的分享已经告一段落,感谢您的关注,如果您想了解更多关于120行代码手写一个简单的MyBatis实现简单的CRUD、5、实现简单的代币、Android Studio实现简单的购物商城界面、c# 实现简单的串口通讯的相关信息,请在本站查询。
本文标签: